Arduino стрелочный индикатор

Содержание

2 Схемы

Принципиальные электросхемы, подключение устройств и распиновка разъёмов

Термометр со стрелочным индикатором на микроконтроллере Ардуино

Сейчас вы узнаете, как превратить обычный стрелочный (аналоговый) вольтметр в цифровой термометр, с помощью платформы Arduino и ds18b20 датчика температуры. В принципе эта технология подходит не только для отображения температуры – любые другие (физические и электрические) величины с разных датчиков можно вывести цифровым методом на стрелочный прибор по данному методу.

Модуль DS18B20

Всем известный готовый модуль ds18b20 – это цифровой термометр, который обеспечивает 9-битное измерение температуры и имеет функцию энергонезависимой программируемой верхней и нижней точки срабатывания. Кроме того, ds18b20 обменивается данными по 1-Wire шине и требует только одну линию данных для связи с микропроцессором. Кроме того, ds18b20 может получать питание непосредственно от линии данных, что исключает необходимость внешнего источника питания.

ds18b20 цоколёвка

На самом деле, каждый ds18b20 имеет уникальный 64-битный последовательный код, который позволяет даже нескольким DS18B20s функционировать на одной шине 1-Wire. Таким образом, с использованием всего одного микропроцессора можно контролировать много температурных датчиков, распределённых по большой площади.

Схема сборки термометра

Сама схема настолько проста, что нет смысла её рисовать – все соединения видны на фотографии. Вначале подключите ds18b20 к контакту (-) для Arduino заземления, контакт (+) для 5 В и сигнальный выход к цифровому выводу 2, Для того, чтобы управлять вольтметром, связываем положительный его провод с контактом 9 (один из ШИМ) и минус подсоединяем к GND. После этого, чтобы изменить на вольтметре шкалу на термометр, просто распечатайте фото, что в приложении к статье. Вольтметр тут на 5 В, но вы можете взять любой другой индикатор, в том числе обычный микроамперметр, добавив к нему последовательно нужный резистор (примерно 10-100 кОм).

Список нужных деталей

  • Ардуино Уно
  • Датчик ds18b20
  • Стрелочный вольтметр
  • Несколько проводов
  • Источник питания (можно АКБ)

Детали для термометра

Принцип работы

Широтно-импульсная модуляция, или ШИМ, это техника получения аналогового результаты с использованием цифровых средств.

Широтно-импульсная модуляция управления стрелочником

При прошивке микроконтроллера вы должны добавить “библиотеку DallasTemperature” в вашу среду разработки Arduino, так как это библиотека, которая поддерживает датчик температуры на микросхеме ds18b20.

Код состоит из трех основных частей:

  1. Чтение температуры с датчика
  2. Преобразование температуры в ШИМ
  3. Отображение значения на шкале

Настройка термометра

В настройках мы будем считывать температуру с датчика. Затем, мы преобразуем это значение в функцию PWM (ШИМ) в диапазоне от 0 до 255. Это может быть сделано внутри функции программы. Далее подадим сигнал на вывод 9, который подключен к стрелочному вольтметру.

При настройках температурного диапазона имейте ввиду – чем меньше разрыв между крайними значениями, тем больше разрешение термометра. Скачать даташит на датчик и код прошивки можно по ссылке.

Видео работы устройства

Источник

Стрелочный индикатор звука на LCD дисплее

Цифровой VU meter с OLED дисплеем на Arduino, он же измеритель уровня звука, можно собрать на Ардуино платформе. Устройство довольно простое, для начинающих это будет полезный опыт. Разумеется, как высокоточный прибор измерения уровня звука оно не годится, но как показометр в любой УНЧ — вполне.

Схема принципиальная индикатора

Ключевым элементом схемы является резистор R1 на 10 кОм, он нужен для того, чтобы защитный диод AVR микроконтроллера не влиял на качество звучания устройства, да и чисто с целей защиты микроконтроллера он там не будет лишним. Резистором R2 осуществляется подстройка максимального уровня сигнала, можно взять любой другой номинал от 1 кОм до 100 кОм, в случае подключения к аудио выходу компьютера идеально подходит 10 кОм. Чувствительность составляет всего лишь 1.1 В при дефолтных настройках скетча. Диапазон питания у схемы довольно таки широкий, от 3.3 до 5 В, но чем ниже напряжение – тем ниже яркость свечения дисплея.

Ардуино Нано подходит только версия на основе ATmega328 (V3.0). Mini USB кабеля в комплекте не будет, поэтому понадобится его достать отдельно.

Список деталей для сборки

  • Arduino Nano V3.0
  • 128×64 OLED I2C дисплеи
  • Провода, макетная плата
  • Кабель mini-USB
  • Источник питания 3.3-5 В

Код для Arduino

Пояснение по настройке скетча для Arduino

#define analogInput 0 // В этой строчке задаётся аналоговый пин ардуино;
#define HighSens true // режим высокой чувствительности, достигается за счёт изменения опорного напряжения в 1.1 V,
//может быть как включено true, так и выключено — false, рекомендую включить;
#define FASTADC true // ускорение работы ADC, для Arduino Nano/Uno/Pro Mini рекомендуется включить(true );
#define Sensitivity 1024 // чувствительность, это значение не может быть больше 1024, если Ваш источник аудиосигнала
//выдаёт небольшое выходное напряжение, то можете попробовать в 2, 4 раза уменьшить это значение;
#define SampleWindow 15 // количество сэмплов, число в миллисекундах, чем оно меньше, тем шустрее дёргается стрелка,
//по умолчанию 50, но я для себя подобрал 15-20, больше уже ардуина не тянет.

Исходники к проекту можно найти в архиве – скачать файл

Видео работы измерителя

Источник

Форум сайта mypractic.ru

Обсуждение и вопросы по темам сайта.

Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение АнтонНикиточкин » 20 мар 2020, 18:31

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение Эдуард » 20 мар 2020, 19:48

Посмотрите, как будут вести себя двигатель , механика. Если все будет нормально, то останется сделать начальную синхронизацию.

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение АнтонНикиточкин » 21 мар 2020, 11:36

Загружен скетч следующий

// программа следящего электропривода без обратной связи

#define MEASURE_PERIOD 80 // время периода измерения (* 250 мкс)
#define numStepsMotor 400 // число шагов двигателя на оборот

int timeCount; // счетчик времени
long sumU; // переменные для суммирования кодов АЦП
long averageU; // сумма кодов АЦП (среднее значение * 80)
int currentStep; // текущее положение двигателя
int setStep; // заданное положение двигателя

StepMotor myMotor(9, 10, 11, 12); // создаем объект типа StepMotor, задаем выводы для фаз

void setup() <
Timer1.initialize(250); // инициализация таймера 1, период 250 мкс
Timer1.attachInterrupt(timerInterrupt, 250); // обработчик прерываний
myMotor.setMode(0, false); // шаговый режим, без фиксации при остановке
myMotor.setDivider(15); // делитель частоты 15
>

void loop() <
// проверка остановки двигателя
if( myMotor.readSteps() == 0) <
// двигатель остановился

// вычисление заданного положения
setStep = averageU * (numStepsMotor — 1) / 1023 / MEASURE_PERIOD;

// определение сколько шагов надо сделать
int stepsToDo; // сколько шагов надо сделать

stepsToDo = currentStep — setStep; // ошибка рассогласования

if( abs(stepsToDo) >= (numStepsMotor / 2) ) <

if((stepsToDo) > 0) stepsToDo -= numStepsMotor;
else stepsToDo += numStepsMotor;
>

myMotor.step(stepsToDo); // запуск двигателя
currentStep = setStep; // перегрузка текущего положения
>
>

//————————————— обработчик прерывания 250 мкс
void timerInterrupt() <
myMotor.control(); // управвление двигателем

sumU += analogRead(A0); // суммирование кодов АЦП
timeCount++; // +1 счетчик выборок усреднения

// проверка числа выборок усреднения
if ( timeCount >= MEASURE_PERIOD ) <
timeCount= 0;
averageU= sumU; // перегрузка среднего значения
sumU= 0;
>
>

Шаговый движок подключен напрямую к выходам ардуино, питания ему вполне хватает, следовательно от драйверов я думаю можно отказаться. Тестируется один канал. В принципе работает, но не очень красиво. Стрелка сильно трясется, быстро перемещаясь из стороны в сторону. Я так понимаю, это происходит изза оцифровки аналогового входа без усреднения значений? Как его изменить?

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение АнтонНикиточкин » 21 мар 2020, 12:50

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение Эдуард » 21 мар 2020, 14:55

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение АнтонНикиточкин » 22 мар 2020, 18:29

честно говоря я не вполне понял, откда была задержка, после пересобирания, все получилось отлично.
Настройка работы мотора получена опытным путем, менял переменные в скетче. Выяснилась особенность, что рабочая амплитуда стрелки при работе смещается по часовой. Но так как на краях амплитуды будут установлены ограничители механические, все хорошо, и не требуется обнуление в начале работы, хотя если получится его прописать, было бы здорово для красоты.
Конденсатор подобран так же опытным путем, емкость 100мкф. Диод 4007, резистор 10кОм.
Подскажитне пожалуйста, как прикрутить второй мотор к скетчу.

// программа следящего электропривода без обратной связи

#define MEASURE_PERIOD 80 // время периода измерения (* 250 мкс)
#define numStepsMotor 1600 // число шагов двигателя на оборот

int timeCount; // счетчик времени
long sumU; // переменные для суммирования кодов АЦП
long averageU; // сумма кодов АЦП (среднее значение * 80)
int currentStep; // текущее положение двигателя
int setStep; // заданное положение двигателя

StepMotor myMotor(9, 10, 11, 12); // создаем объект типа StepMotor, задаем выводы для фаз

void setup() <
Timer1.initialize(250); // инициализация таймера 1, период 250 мкс
Timer1.attachInterrupt(timerInterrupt, 250); // обработчик прерываний
myMotor.setMode(1, false); // шаговый режим, без фиксации при остановке
myMotor.setDivider(6); // делитель частоты 6
>

void loop() <
// проверка остановки двигателя
if( myMotor.readSteps() == 0) <
// двигатель остановился

// вычисление заданного положения
setStep = averageU * (numStepsMotor — 1) / 1023 / MEASURE_PERIOD;

// определение сколько шагов надо сделать
int stepsToDo; // сколько шагов надо сделать

stepsToDo = currentStep — setStep; // ошибка рассогласования

if( abs(stepsToDo) >= (numStepsMotor / 2) ) <

if((stepsToDo) > 0) stepsToDo -= numStepsMotor;
else stepsToDo += numStepsMotor;
>

myMotor.step(stepsToDo); // запуск двигателя
currentStep = setStep; // перегрузка текущего положения
>
>

//————————————— обработчик прерывания 250 мкс
void timerInterrupt() <
myMotor.control(); // управвление двигателем

sumU += analogRead(A0); // суммирование кодов АЦП
timeCount++; // +1 счетчик выборок усреднения

// проверка числа выборок усреднения
if ( timeCount >= MEASURE_PERIOD ) <
timeCount= 0;
averageU= sumU; // перегрузка среднего значения
sumU= 0;
>
>

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение Эдуард » 22 мар 2020, 19:02

Здравствуйте!
Смещение происходит потому что не задана фиксация ротора двигателя при остановке.
myMotor.setMode(1, false); // шаговый режим, без фиксации при остановке
Попробуйте второй параметр указать true.

Может в начале работы просто сделать количество шагов, которое гарантировано упрет стрелку в крайнее левое положение.

Давайте с одним двигателем закончим, потом второй добавим.

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение АнтонНикиточкин » 23 мар 2020, 00:12

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение Эдуард » 23 мар 2020, 11:59

Re: Стрелочный индикатор громкости на 2 шаговых двигателях и Ардуино

Сообщение АнтонНикиточкин » 23 мар 2020, 13:38

День добрый! Последний скетч таков. Подключил второй мотор. Добавил движение против часовой до упора в начале работы. Работает почти идеально, визуально похоже на аналоговую измерительную головку, но чуть заметно подергивание в движении стрелки, я думаю это из-за дискретности работы шд. Было бы полное сходство, если возможно было бы подключить в движение ускорение, но в целом меня устраивает. Если кто-то решит повторить, рекомендую в корпуса моторчиков капнуть масла, оно чуть компенсирует люфт шестеренок редуктора. Если в скетче есть косяки, напишите пожалуйста какие.

// программа следящего электропривода без обратной связи

#define MEASURE_PERIOD 8 // время периода измерения (* 100 мкс)
#define numStepsMotor 1600 // число шагов двигателя на оборот

int timeCount; // счетчик времени
long sumU1; // переменные для суммирования кодов АЦП
long averageU1; // сумма кодов АЦП (среднее значение * 8)
long sumU2; // переменные для суммирования кодов АЦП
long averageU2; // сумма кодов АЦП (среднее значение * 8)
int currentStep1; // текущее положение двигателя 1
int setStep1; // заданное положение двигателя 1
int currentStep2; // текущее положение двигателя 2
int setStep2; // заданное положение двигателя 2

StepMotor myMotor1(9, 10, 11, 12); // создаем объект типа StepMotor, задаем выводы для фаз мотора 1
StepMotor myMotor2(4, 5, 6, 7); // создаем объект типа StepMotor, задаем выводы для фаз мотора 2

void setup() <
Timer1.initialize(100); // инициализация таймера 1, период 100 мкс
Timer1.attachInterrupt(timerInterrupt, 250); // обработчик прерываний
myMotor1.setMode(1, true); // шаговый режим, без фиксации при остановке
myMotor1.setDivider(6); // делитель частоты 8
myMotor2.setMode(1, true); // шаговый режим, без фиксации при остановке
myMotor2.setDivider(6); // делитель частоты 8

myMotor1.step(500); //вращение мотора 1 на 500 шагов до ограничителя
myMotor2.step(500); //вращение мотора 2 на 500 шагов до ограничителя
>

// вычисление заданного положения
setStep1 = averageU1 * (numStepsMotor — 1) / 1023 / MEASURE_PERIOD;

// определение сколько шагов надо сделать
int stepsToDo1; // сколько шагов надо сделать

stepsToDo1 = currentStep1 — setStep1; // ошибка рассогласования

if( abs(stepsToDo1) >= (numStepsMotor / 2) ) <

if((stepsToDo1) > 0) stepsToDo1 -= numStepsMotor;
else stepsToDo1 += numStepsMotor;
>

myMotor1.step(stepsToDo1); // запуск двигателя
currentStep1 = setStep1; // перегрузка текущего положения
>
// ————————————-мотор 2 —————————————-
// проверка остановки двигателя
if( myMotor2.readSteps() == 0) <
// двигатель остановился

// вычисление заданного положения
setStep2 = averageU2 * (numStepsMotor — 1) / 1023 / MEASURE_PERIOD;

// определение сколько шагов надо сделать
int stepsToDo2; // сколько шагов надо сделать

stepsToDo2 = currentStep2 — setStep2; // ошибка рассогласования

if( abs(stepsToDo2) >= (numStepsMotor / 2) ) <

if((stepsToDo2) > 0) stepsToDo2 -= numStepsMotor;
else stepsToDo2 += numStepsMotor;
>

myMotor2.step(stepsToDo2); // запуск двигателя
currentStep2 = setStep2; // перегрузка текущего положения
>
>

//————————————— обработчик прерывания 100 мкс
void timerInterrupt() <
myMotor1.control(); // управвление двигателем
myMotor2.control(); // управвление двигателем

sumU1 += analogRead(A0); // суммирование кодов АЦП
sumU2 += analogRead(A1); // суммирование кодов АЦП
timeCount++; // +1 счетчик выборок усреднения

// проверка числа выборок усреднения
if ( timeCount >= MEASURE_PERIOD ) <
timeCount= 0;
averageU1= sumU1; // перегрузка среднего значения
sumU1= 0;
averageU2= sumU2; // перегрузка среднего значения
sumU2= 0;
>
>

Источник

Adblock
detector