Датчик холла ардуино двигатель

Исходный код программы (скетча)

Arduino

#include<LiquidCrystal.h>
LiquidCrystal lcd(A5,A4,A3,A2,A1,A0);
#include <Stepper.h>
const int stepsPerRevolution = 200; // число шагов на один оборот шагового двигателя, измените это число для своего двигателя
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
volatile byte REV;
unsigned long int rpm,RPM;
unsigned long st=0;
unsigned long time;
int ledPin = 13;
int led = 0,RPMlen , prevRPM;
int flag = 0;
int flag1=1;
#define bladesInFan 2
float radius=4.7; // в дюймах
int preSteps=0;
float stepAngle= 360.0/(float)stepsPerRevolution;
float minSpeed=0;
float maxSpeed=280.0;
float minSteps=0;
float maxSteps=maxSpeed/stepAngle;
void setup()
{
myStepper.setSpeed(60);
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
lcd.begin(16,2);
lcd.print(«Speedometer»);
delay(2000);
attachInterrupt(0, RPMCount, RISING);
}
void loop()
{
readRPM();
radius=((radius * 2.54)/100.0); // преобразуем в метры
int Speed= ((float)RPM * 60.0 * (2.0 * 3.14 * radius)/1000.0);
// RPM умножаем на 60 чтобы перевести минуты в часы, диаметр шины — 2pi*r, r — радиус, деление на 1000 чтобы перевести скорость в км/ч
int Steps=map(Speed, minSpeed,maxSpeed,minSteps,maxSteps);

if(flag1)
{
Serial.print(Speed);
Serial.println(«Kmh»);
lcd.setCursor(0,0);
lcd.print(«RPM: «);
lcd.print(RPM);
lcd.print(» «);
lcd.setCursor(0,1);
lcd.print(«Speed: «);
lcd.print(Speed);
lcd.print(» Km/h «);
flag1=0;
}
int currSteps=Steps;
int steps= currSteps-preSteps;
preSteps=currSteps;
myStepper.step(steps);
}
int readRPM()
{
if(REV >= 10 or millis()>=st+1000) // данные будут обновляться каждые 10 считываний или через 1 секунду в неиспользуемом состоянии
{
if(flag==0)
flag=1;
rpm = (60/2)*(1000/(millis() — time))*REV/bladesInFan;
time = millis();
REV = 0;
int x= rpm;
while(x!=0)
{
x = x/10;
RPMlen++;
}
Serial.println(rpm,DEC);
RPM=rpm;
delay(500);
st=millis();
flag1=1;
}
}
void RPMCount()
{
REV++;
if (led == LOW)
{
led = HIGH;
}
else
{
led = LOW;
}
digitalWrite(ledPin, led);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

#include<LiquidCrystal.h>

LiquidCrystallcd(A5,A4,A3,A2,A1,A0);

#include <Stepper.h>

constintstepsPerRevolution=200;// число шагов на один оборот шагового двигателя, измените это число для своего двигателя

SteppermyStepper(stepsPerRevolution,8,9,10,11);

volatilebyteREV;

unsignedlongintrpm,RPM;

unsignedlongst=;

unsignedlongtime;

intledPin=13;

intled=,RPMlen,prevRPM;

intflag=;

intflag1=1;

#define bladesInFan 2

floatradius=4.7;// в дюймах

intpreSteps=;

floatstepAngle=360.0(float)stepsPerRevolution;

floatminSpeed=;

floatmaxSpeed=280.0;

floatminSteps=;

floatmaxSteps=maxSpeedstepAngle;

voidsetup()

{

myStepper.setSpeed(60);

Serial.begin(9600);

pinMode(ledPin,OUTPUT);

lcd.begin(16,2);

lcd.print(«Speedometer»);

delay(2000);

attachInterrupt(,RPMCount,RISING);

}

voidloop()

{

readRPM();

radius=((radius*2.54)100.0);// преобразуем в метры

intSpeed=((float)RPM*60.0*(2.0*3.14*radius)1000.0);

// RPM умножаем на 60 чтобы перевести минуты в часы, диаметр шины — 2pi*r, r — радиус, деление на 1000 чтобы перевести скорость в км/ч

intSteps=map(Speed,minSpeed,maxSpeed,minSteps,maxSteps);

if(flag1)

{

Serial.print(Speed);

Serial.println(«Kmh»);

lcd.setCursor(,);

lcd.print(«RPM: «);

lcd.print(RPM);

lcd.print(»           «);

lcd.setCursor(,1);

lcd.print(«Speed: «);

lcd.print(Speed);

lcd.print(» Km/h       «);

flag1=;

}

intcurrSteps=Steps;

intsteps=currSteps-preSteps;

preSteps=currSteps;

myStepper.step(steps);

}

intreadRPM()

{

if(REV>=10ormillis()>=st+1000)//  данные будут обновляться каждые 10 считываний или через 1 секунду в неиспользуемом состоянии

{

if(flag==)

flag=1;

rpm=(602)*(1000(millis()-time))*REVbladesInFan;

time=millis();

REV=;

intx=rpm;

while(x!=)

{

x=x10;

RPMlen++;

}

Serial.println(rpm,DEC);

RPM=rpm;

delay(500);

st=millis();

flag1=1;

}

}

voidRPMCount()

{

REV++;

if(led==LOW)

{

led=HIGH;

}

else

{

led=LOW;

}

digitalWrite(ledPin,led);

}

Общие принципы работы проектируемого тахометра

В этом проекте мы будем создавать цифровой тахометр на основе платы Arduino и модуля инфракрасного датчика для обнаружения вращения и подсчета числа оборотов любого вращающегося объекта. Принцип его действия основан на том, что инфракрасный передатчик излучает инфракрасные лучи которые затем отражаются обратно к инфракрасному приемнику и затем инфракрасный модуль генерирует импульс на своем выходе который обнаруживается контроллером Arduino когда мы нажимаем кнопку start. Он осуществляет счет в течение 5 секунд.

После этих 5 секунд плата Arduino рассчитывает число оборотов в минуту по следующей формуле:

RPM= Count x 12 для одиночного вращающегося объекта.

Но поскольку в этом проекте для демонстрации работы схемы мы используем потолочный вентилятор, то мы должны внести некоторые изменения в приведенную формулу:

RPM=count x 12 / objects где objects – число лопастей в вентиляторе.

Обобщенная структурная схема работы устройства представлена на следующем рисунке.

Особенности измерения скорости движения и скорости вращения.

При измерении скорости вращения бензинового двигателя надо обязательно учесть величину К, которая совсем не очевидна. Например, вы намотали провод на кабель свечи и ожидаете, что там будет одна искра на один оборот. Это совсем не так. Во-первых, у 4-тактного двигателя вспышка происходит один раз на два оборота, у 2-тактного один раз на оборот коленвала. Во-вторых, для упрощения системы зажигания коммутатор подаёт искру на неработающие в данный момент цилиндры, типа на выпуске. Для получения правильного К надо почитать документацию на двигатель или подсмотреть показания эталонного тахометра.

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

Вывод информации

Типичная обида начинающего разработчика автомобильной и мотоциклетной электроники «стрелки дёргаются, цифры нечитабельны» лечится простым способом — надо обманывать клиента. Вы что думаете, автомобильный тахометр всегда показывает вам правду? Конечно же нет! Хотя вам этот обман нравится и вы хотите, чтобы ваш прибор дурил голову так же.

Стрелки

Если включить зажигание на новом модном автомобиле или мотоцикле, стрелки приборов сделают красивый вжух до максимума и медленнее опадут до нуля. Вот! Вот это нам и надо сделать. Надо, чтобы при показе максимальной величины стрелка не метнулась к ней мгновенно и не упала как акции лохотрона в ноль.

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

Вот пример с нелинейным выводом показаний:

Цифры

С цифрами всё намного сложнее. Быстрые изменения показаний приводят к тому, что несколько порядков сливаются в мутное пятно. Для скорости, как и писал выше, можно задать интервал раз в секунду и глаз успеет прочитать три цифры.

В мототехнике не зря делают аналоговые индикаторы оборотов, точные цифры не нужны, важна относительная близость к оборотам максимального крутящего момента, к максимальным вообще и холостые.

Я предлагаю менять частоту вывода информации на дисплей в зависимости от степени изменения величины. Если обороты меняются, скажем, на 5% от последнего подсчёта, а не показа — можно затупить и показывать раз в 300-500мс. Если на 20%, то показывать раз в 100мс.

Можно огрубить шкалу и показывать только две значащие цифры

С учётом мототематики, можно довольно точно показывать обороты холостого хода как описано чуть выше и огрублять вывод на оборотах от двух холостых. На высоких оборотах для гонщиков важнее делать блинкеры типа «передачу вниз», «передачу вверх» и «ты спалишь движок». То есть держать двигатель около максимального крутящего момента и не дать ему крутиться выше максимальных разрешённых оборотов. Блинкеры замечательно делаются с помощью SmartDelay когда можно унаследовать от этого класса свой с заданной ногой контроллера и частотой мигания, там есть методы для переопределения и они вызываются раз в заданное время.

Настройка карбюратора автомобиля

Теперь несколько слов о настройке карбюратора автомобиля «ВАЗ» с использованием данного прибора, на примере «ВАЗ-2108».

Настройка карбюратора на холостой ход

Необходимо установить номинальную частоту вращения коленвала на холостом ходу при допустимом содержании СО в выхлопе не более 2%.

Действия такие. Подключаете тахометр «+13V» к положительной клемме аккумулятора, «GND» к массе (минус аккумулятора). Контакт «К» — к контакту катушки зажигания, соединенному с выходом коммутатора («К»). Пускаете двигатель и прогреваете его до номинальной температуры.

Очень медленно вращаете винт качества смеси в ту и другую сторону, пока не найдете положение, при котором показания прибора максимальны. Затем винтом количества устанавливаете показания прибора 900-950тV, и снова немного подстраиваете винт качества, чтобы эти показания были максимальными.

Теперь нужно дать двигателю поработать некоторое время (1-2 минуты). Затем, запомните показания прибора (допустим было 928mV), и очень медленно завинчивайте винт качества до тех пор, пока показания прибора не уменьшатся на 100mV (в нашем случае, до 828mV).

Дайте двигателю поработать около минуты, и винтом количества установите номинальную частоту вращения, согласно требованию для данной модели автомобиля (например, 850 об/мин для ВАЗ-2108). При такой регулировке содержание СО (если двигатель исправен) будет в пределах 1,5-2%.

Познакомимся с основными принципами измерения частоты цифровым способом.

Всего существует два принципа. Оба они основаны на сравнении периодов образцового и измерительного сигналов.

Первый способ иллюстрирует следующая схема.

Рис. 3

Импульс входного сигнала (передним или задним фронтом), поступающий от датчика Холла, запускает аппаратное прерывание Ардуино.  При срабатывании функции прерывания запускается подсчет количества импульсов n встроенного тактового генератора, период следования которых Tзаранее известен, и продолжается до следующего срабатывания прерывания.

Таким образом сумма длительностей импульсов тактового генератора будет соответствовать времени Т между двумя срабатываниями аппаратного прерывания.

T = k*T

Частота определяется как величина обратная периоду:

f=1/T

А частота вращения, выраженная в об/мин будет в 60 раз больше:

n=60/T=60/(k*T).

Для получения длительности импульсов образцового сигнала встроенного генератора пользователю Ардуино доступна функция Micros (). Она показывает текущее значение времени в микросекундах с начала запуска программы. Таким образом, обращаясь к ней в моменты срабатывания функции прерывания, можно получить количество микросекунд между двумя срабатываниями. Так как длительность одного образцового импульса T равна 1 мкс=1/1000000 с, тогда формула приобретает вид:

n=60*1000000/(k).

Если на валу вращающегося двигателя установлен не один магнит, а несколько (z), то время T между ближайшими срабатываниями функции прерывания сокращается в z раз, а частота входного сигнала возрастает в z раз, тогда формула примет вид:

n=60*1000000/(k*z).

Рис. 4

Второй способ отличается от первого тем, что ведется прямой подсчет числа импульсов k, поступивших от датчика Холла за большой период времени Tm. Этот способ поясняется вторым рисунком. Согласно этому способу частота вращения вала будет равна:

f=k/Tm;

А в минуту – в 60 раз больше:

f=60*k/Tm.

Если принять Tm=1 c., то формула приобретает вид:

f=60*k.

Комментарии 18

А можно также взять другой контроллер. Или на дискретной логике сделать. Или на raspberry с линуксом. Для 2 датчиков планировщик как то из пушки по воробьям.

Вы передергиваете. Во-первых, реализация этого на логике — это еще больший оверинжиниринг, ибо влечет за собой десяток плат с микросхемами. Малину и жирные контроллеры с линуксом я не предлагал, как не предлагал и смену контроллера.

Во-вторых, у автора возникла проблема, я описываю подход, где этой проблемы вообще не возникнет — опрос кнопки в одном потоке, работа с датчиком в другом, с экраном в третьем. Причем, как я уже сказал, ничего менять не надо, ни новый контроллер, ни малину, ни линукс, просто немного кода, все равно у тс достаточно памяти.

В-третьих, нет никакого понятия «из пушек по воробьям»: все определяется стоимостью часа разработки и экономией денег после этой разработки. Если я делаю устройство в тираж 1м, то я буду биться за каждый рубль стоимости контроллера, и если надо, посажу разрабов писать на ассемблере прошивку, чтобы уложиться в более дешевый контроллер (разумеется, если меня удовлетворит стоимость поддержки такого ПО): там стоимость разработки сильно-сильно ниже стоимости партии. Если я делаю устройство в тираж 1 (прописью: одну) штуку, то мне абсолютно пофиг, стоит контроллер 10 рублей или 50 рублей, но очень-очень не пофиг на свое время: если +40 рублей к цене устройства экономят мне неделю работы за счет RTOS, планировщика, готовых жирных библиотек и так далее, то выбор очевиден. Тратить неделю на непрофильную работу, если это можно сконвертировать в небольшие затраты смысла ноль, лучше в свободное время какой-нибудь другой девайс сделать. Тут же даже не надо менять контроллер, просто прочитать и понять некоторые концепции, и разобраться, как добавить в проект либу.

У каждого есть свой набор микроскопов с удобными ручками

Нет, всё значительно проще. Аналоговый датчик (1 операционник) + интегратор для импульсов (ещё один) + линейный светодиодный индикатор на компаторах (по 1 на светодиод), например. Операционники бывают и по 4 в одном корпусе. Или АЦП на сдвиговых регистрах — тоже ничего сложного. Конечно, если задаться целью сделать I2C на мелкой логике, это будет страшно…

Вы правы. Но это же хобби-проект. Совершенно не факт, что автор планирует сильно упарываться в микроконтроллеры. А ардуиновский суперцикл — проще всего для понимания.

Механическая модификация

Механический автомобильный тахометр, своими руками сделанный, не требует питания и управляющих схем. На валу жестко фиксируется магнит постоянного типа. При его вращении создается вихревое поле, которое увлекает за собой специальную емкость из магнитного материала. Вращению чащи создает сопротивление спиральная пружина. Чем больше скорость вращения, тем активнее отклоняется вал, оснащенный стрелкой.

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

Код программы

Для создания тахометра на плате Ардуино нужна не только аппаратная часть, но и программная — загружаемый в систему скетч. Рассматриваемый пример строится на упомянутой выше библиотеке функций Arduino LCD (LiquidCrystal.h). Для упрощения понимания работы последней можно привести пример простого скетча: он выводит на экран стандартную фразу «Hello, World!». Код удобно использовать для тестирования оборудования.

В нашем приборе будет интенсивно применяться метод lcd.print(millis()/1000).

Считаем RPM вентилятора

Подсчет ведется по прерываниям луча инфракрасного передатчика. Метод удобный, но тестовым объектом выступает вентилятор с семью лопастями. Значит, на один полный оборот придется семь прерываний луча, и только завершение этого цикла будет означать увеличение счетчика RPM на единицу.

Итак, каждое седьмое прерывание равно одному обороту. Зная необходимое для такового время, можно вычислить и значение RPM. Вычисления выполняются по формулам:

  • время на полный оборот вентилятора — P×(µS/об.);
  • RPM = обороты в минуту = 60 000 000 × (µS/мин) × (1/P) = (60 000 000 / P) × (об/мин).

Скетч выполняет две задачи:

  • работа основного цикла;
  • обновление штампа времени зафиксированных прерываний ИК-потока.

В главном цикле наш контроллер считает количество RPM и обновляет информацию на экране.

Учитывая особенности кода, последнее станет происходить несколько раз в секунду. RPM тоже считается в основном цикле, поскольку прерывания обрабатываются отдельной функцией программы.

Точность работы составляет около 96%, что вполне достаточно для бытового применения.

Принцип работы тахометра достаточно простой

Есть несколько разновидностей конструкции:

Электрическая схема импульсная

На вал, частота которого измеряется, устанавливается метка, излучающая любое поле. Чаще всего это маленький магнит.

Рядом с валом размещается считывающее устройство – датчик. На нем формируются импульсы, соответствующие скорости вращения вала.

Электронная схема принимает сигналы, и выводит их на устройство отображения. Вместо пары магнит-датчик иногда применяется фото и светодиод.

Тогда на вал устанавливается диск с отверстием, и считывание происходит по вспышкам света.

Преимущество схемы – идеальная точность. Фактически, это цифровое устройство, работающее без погрешностей. Кроме того, такая схема не отбирает мощность у двигателя.

Недостаток – требуется электропитание. Это исключает применение прибора в чисто механических агрегатах.

Электрическая схема генераторного типа

Вал механизма соединен с компактным генератором. В зависимости от скорости вращения, меняется величина вырабатываемого напряжения.

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

Индукционный тахометр

Это также генераторная схема, только в данной конструкции применяется машина асинхронного типа. На катушки статора подается питание, и при вращении ротора происходит возбуждение и линейное увеличение напряжения.У таких приборов высокая погрешность, и они не являются энергонезависимыми. Зато снятие показаний (в отличие от тахометра постоянного тока) происходит уже на малых оборотах.

Механический тахометр

Система автономная, для работы не требуется ни питания, ни управляющих схем.На валу (5) жестко закреплен постоянный магнит (4). При вращении магнита возникает вихревое поле, которое увлекает за собой чашу (3) из магнитного материала.

Вращению чаши препятствует спиральная пружина (2). Чем выше скорость вращения, тем сильнее отклоняется вал со стрелкой.

Главное достоинство прибора – простота конструкции и отсутствие необходимости в электропитании. Недостатков два: высокая погрешность и сдвинутый нижний предел измерений. При малых оборотах стрелка не отклоняется.

Мы рассмотрим самое востребованное применение тахометров – автомобиль.

Любой механизм вращения (в нашем случае – коленчатый вал автомобиля) имеет предел нагрузки. То есть, силовая структура и подшипники могут выдержать определенную скорость.

Кроме того, остальные механизмы мотора также рассчитаны на предельно допустимую частоту оборотов.

Поэтому установка прибора контроля обязательна для любого современного ДВС. Исключение составляют лишь маломощные моторы для мотоциклов и мопедов.

Для контроля за оборотами коленвала нужен тахометр. В большинстве автомобилей (особенно с механическими КПП), показания прибора дают водителю возможность правильно выбирать момент перехода на следующую ступень.

Изготовление тахометра своими руками на базе Arduino, подробное видео.

В машинах с автоматической трансмиссией, схема подключения тахометра подает сигнал в модуль управления. Электроника не даст мотору выйти за разрешенные пределы.

Если ваш прибор перестал подавать признаки жизни, необходима диагностика. Как проверить тахометр в домашних условиях?

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

Механический тахометр проверяется с помощью дрели или шуруповерта. Хорошо, если есть регулятор оборотов. Хвостовик тросика крепится в патроне, корпус прибора жестко закрепляется.

Ремонт тахометра не такая сложная задача, если это не модуль электросхемы. После локализации неисправности, меняется неисправный компонент.

Проводка, контакты датчика, сам датчик, оторванный магнитик на коленвале. Как правило, причина поломки именно в этих деталях.

С механикой еще проще. Надо просто заменить изношенный узел на новый, либо приобретенный на авторынке.

Автомобили с механическими тахометрами, как правило, относятся к сильно подержанным, так что найти б/у запчасть не сложно. Подключение тахометра после ремонта калибровки не требует.

Тахометр + температура двигателя на Arduino для МиниМото

Купил я сыну в прошлом сезоне его первый мотоцикл. Радости не было предела.

Катались мы катались, всё хорошо, но т.к. на минибайках нет ни спидометра, ни тахометра, ничего, пришла идея это исправить. Есть конечно же в продаже готовые варианты, но весь интерес в том, чтобы попробовать сделать что-то самому, а купить можно всегда. Что у меня из этого вышло, читайте ниже.

Для фиксации оборотов двигателя использую датчик Холла NJK-5002C, при появлении в зоне срабатывания постоянного магнита датчик на выход подаёт сигнал. Магнитные полосы присутствуют на маховике двигателя, приклеивать/прикручивать магниты не нужно.

Для определения температуры двигателя использую водонепроницаемый датчик температуры DS18B20, который вставляется в специальную шайбу под свечу зажигания.

В моей реализации устройства по кнопке циклически переключаются режимы: при включении отображаются обороты, нажали на кнопку — обороты сменились на температуру, ещё раз нажали — температура сменилась на обороты и т.д. по кругу.

Поясню один момент в скетче, для чего я использую таймер: так вот, получить данные температуры с датчика (sensor.getTemp()) мы можем только отправив запрос (sensor.requestTemp();) и подождав (delay(1000);). Как всегда delay всё портит и если без таймера опрашивать кнопку в loop, то переключив один раз режим на отображение температуры (сработает delay) — сменить режим мы уже не сможем, т.к. микроконтроллер ждёт и нажатие на кнопку не обработает. Чтобы этого избежать я и опрашиваю кнопку по таймеру.

На видео показано как это всё работает, для установки на мотоцикл я немного не угадал с диаметром датчика NJK-5002C, который будет устанавливаться в корпус инерционного стартера и чтобы всё было ровно, диаметр нужен поменьше, планирую использовать датчик LJ8A3 или LJ6A3. К следующему мотосезону постараюсь всё оформить в какой-нибудь корпус и установить на МиниМото, соответственно по готовности дополню статью фотками и видео.

Ссылка на скетч и библиотеки.

Для тех, кому интересны покатушки на МиниМото, ссылка на канал моего сына на YouTube.

Давайте подумаем…

… о том, как нам это можно сделать. Скорость есть изменение положения за единицу времени. Другими словами — как быстро меняется положение объекта (робота) в пространстве или как быстро меняется положение вала. Математически это записывается как

V — линейная скорость;

S — путь, пройденный объектом (роботом), вычисляется как S=Pнов-Pстар (P — положения новое и старое, разница/расстояние между ними должна быть указана в метрах);

T — время измерения, начинается, когда объект (робот) находится в Pстар и заканчивается, когда объект находится в Pнов;

— угол, на который повернулся вал мотора ( — углы/положения вала новое и старое, разница между ними должна быть указана в градусах).

Очень часто эти формул пишут в следующем виде:

В них dP — изменение положения, dE — изменение угла, dt — «изменение времени» — время, за которое произошли эти изменения угла или положения.

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

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

На Arduino фоном могут происходить прерывания. В прошлых статьях я рассказывал о прерываниях от внешних сигналов (они так и называются «внешние прерывания»), но существуют еще прерывания по таймерам, прерывания от интерфейсов связи (срабатывают, например, при получении сообщения по UART/Serial или I2C) и многие другие.

Прерывания по таймеру нам могут подойти. Работают они следующим образом — в микроконтроллере независимо от основной программы работает таймер, когда он отсчитывает нужное время — срабатывает прерывание, основной скетч останавливается и вызывается подпрограмма — обработчик прерывания. В этот же момент таймер сбрасывается и начинает считать заново. После завершения обработчика выполнение возвращается в основной цикл, в то место, где он был прерван. Таким образом таймер не зависит от того, как долго или быстро выполнялся обработчик прерывания, все работает на аппаратном уровне. То есть, при использовании прерываний по таймерам T будет постоянной, заданной заранее в настройках таймера. Нам каждый раз прерывания таймера надо будет запоминать положение вала и сравнивать его с предыдущим.

Вот тут стоит остановиться и сделать ОЧЕНЬ важное замечание — инструментарий и среда Arduino не предоставляет нормального способа работы с таймерами. Можно, конечно, работать с регистрами самого микроконтроллера, но в разных платах они разные (AVR, SAMD21 и т.д.), и регистры у них разные

Кроме того, у каждой платы на таймерах висит куча важных и полезных функций: генерация ШИМ на ножках, работа по Serial’у, функции millis() и micros() и многие другие. Так что новичкам их вообще лучше не трогать, а мы для эксперимента попробуем, но очень аккуратно! Так что перед их использованием….

Ошибки дребезга

Для устрашения вас предположу, что измеряем частоту вращения двигателя от индуктивного датчика зажигания. То есть, грубо говоря, на высоковольтный провод намотан кусок кабеля и мы измеряем индукцию в нём. Это довольно распространённый метод, не правда ли? Что же здесь сложного может быть? Самая главная проблема — современные системы зажигания, они дают не один импульс, а сразу пачку.

Примерно так:

Но даже обычная система зажигания даёт переходные процессы:

Старинные же кулачковые контактные вообще показывают замечательные картинки.

Как с этим бороться? Частота вращения не может вырасти мгновенно, не даст инерция. Кроме того, в начале статьи я предложил ограничить частоту сверху разумными рамками. Отсчёты, что происходят слишком часто можно просто игнорировать.

Другой вид помех — это пропадание отсчётов. Из-за той же инерции у вас не может измениться частота в два раза за одну миллисекунду. Понятно, что это зависит от того, что вы собственно измеряете. Частота биения крыльев комара может, вероятно и за миллисекунду упасть до нуля.

Работа проекта

Когда вся аппаратная часть проекта у вас готова, загрузите программу в плату Arduino. Мы использовали для питания платы Arduino батарейку на 9 В, но вы можете использовать любой другой способ подачи питания на плату Arduino. Теперь поднесите магнит близко к датчику Холла и светодиод зажгется, когда вы уберете магнит — светодиод погаснет.

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

Когда мы будем подносить магнит близко к датчику датчик будет изменять свое состояние. Это изменение будет обнаруживаться контактом прерывания (контакт 2), при этом будет вызываться функция toggle, в которой состояние переменной “state” будет изменяться с 0 на 1. Поэтому светодиод будет зажигаться. Когда мы будем отдалять магнит от датчика Холла состояние сигнального контакта датчика также изменится. Это изменение также обнаружится контактом прерывания и, следовательно, состояние переменной “state” изменится с 1 на 0. Это приведет к выключения светодиода. Описанные процессы будут происходить всякий раз когда вы будете подносить магнит к датчику Холла и уносить его от датчика.

Немного физики

Для измерения частоты вращения нам понадобится датчик положения колеса/вала/круга/итп. Датчик ставится как правило один. Возможно, что он будет срабатывать не один раз на каждый оборот. Например, у вас датчик Холла и 4 магнита на колесе. Таким образом, для правильного вычисления частоты нужно знать:

  • количество срабатываний датчика на один оборот К;
  • минимальная ожидаемая частота Мин.
  • максимальная ожидаемая частота Макс.

То есть, если частота меньше разумного минимума, то считаем, что она равна нулю, если больше максимума — игнорируем показания.

С количеством срабатываний понятно, но зачем ещё эти мины и максы? Давайте рассмотрим сначала варианты расчёта частоты.

Со скоростью всё проще, достаточно знать число π, диаметр колеса, а частоту вращения мы уже знаем.

Вывод данных на LCD дисплей HD44780 с помощью arduino

Для работы с дисплеем HD44780 очень удобно использовать модуль I2C интерфейса. Бывают модули и LCD дисплеи продаются по отдельности, но зачастую и сразу в комплекте, спаянные. Я рекомендую, использовать уже собранные вместе, поскольку если подключать без I2C то придется подключать дисплей с помощью 16 проводов, когда через I2C их количество снижется до 4, два из которых это питание. А два других провода подключаются к пинам ардуино A4 и A5.
Чтобы управление выводом данных на дисплей, было более удобным и комфортным можно воспользоваться библиотекой LiquidCrystal_I2C.
Ниже приведена схема подключение дисплея, а также светодиода с фоторезистором к arduino.