Регулируемый таймер обратного отсчета на arduino mega 2560

Содержание

Автоматическое освещение на базе Arduino


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


Материалы и инструменты для самоделки: — контроллер Arduino Nano; — текстолитовые макетки; — датчики движения; — источник питания 5В; — реле; — паяльник с припоем; — провода; — материалы для изготовления корпуса электроники (оргстекло); — напильник.


Процесс изготовления:

Шаг первый. Доработка и установка реле

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

Шаг второй. Пару слов о датчике движения Автор не делал датчик движения фиксированным, поскольку была идея сделать его на «рожках», это позволит менять его направление при необходимости. Также пока однозначно не решено, где именно будет крепиться прибор. Особенность датчика в том, что при первом запуске ему надо дать время порядка 10-30 секунд. За это время он сам настроиться, произведет калибровку и будет работать как надо. В принципе, этот момент не так важен.Шаг третий. Прошивка электроники Прошивка собрана из кусков различных «туториалов» для датчиков. Работает электроника очень просто, когда датчик обнаруживает движение, идет сравнивание показателей фоторезистора с пороговым значением, которое необходимо для срабатывания реле. Это значение регулируется с помощью потенциометра. Если все требования соблюдены, реле включается на три минуты, можно задать и другой временной промежуток. Далее, если движения нет, то система отключает свет.

Чтобы проверить пороговые значения фоторезистора он был закрыт пальцем и затем автор направил на него фонарик мощностью в 2000 люмен.


В общей сложности с учетом праздников и помощи надежного коллеги — кота, на всю сборку было затрачено порядка 12-15 часов. Для работы системы достаточно источника питания в 4 Ватта, автору он обошелся в 200 рублей.

Подключается система тоже очень просто. Достаточно подключить освещение через реле и подать на электронику через источник питание в 5В.

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

Естественно важно продумать, где установить датчик движения

avtomaticheskoe-osveschenie.rar (скачиваний: 644)

Источник (Source)

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

Шаг третий. Датчик приближения

Инфракрасный датчик препятствий работает как кнопка, только не нужно ничего нажимать — достаточно просто поднести руки.

Подключу датчик напрямую к плате, как делал это в предыдущем проекте. Отличие одно: 4 контакт уже занят светодиодом, поэтому подключу сигнальную линию к 7 контакту.

Изменится и код.

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

Защита от помех AC

Момент выключения

Напряжение в сети является синусоидой, которая 100 раз в секунду пересекает значение 0. Если выключить нагрузку в тот момент, когда напряжение в сети равно нулю – это сильно уменьшит выброс. Для этих целей проще всего использовать твердотельные реле (SSR) с детектором нуля (Zero-Crossing Detector): такие реле сами отключают и включают нагрузку в нужный момент. Детектор нуля есть почти во всех моделях SSR, но лучше уточнить в документации. Для самодельных симисторных ключей, работающих в режиме вкл/выкл (без диммирования) рекомендуется ставить управляющую оптопару с детектором нуля: она тоже будет включать и выключать нагрузку в лучший для этого момент, то есть в ближайшем нуле.

Искрогасящие цепи AC

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

Подключение реле к Ардуино

Рассмотрим одноканальный модуль реле. Он имеет всего 3 контакта, подключаются они к Ардуино Uno следующим образом: GND – GND, VCC – +5V, In – 3. Вход реле – инвертирован, так что высокий уровень на In выключает катушку, а низкий – включает.

Светодиоды нужны для индикации – при загорании красного LED1 подается напряжение на реле, при загорании зеленого LED2 происходит замыкание. Когда включается микроконтроллер, транзистор закрыт. Для его открытия на базу нужен минус, подается при помощи функции digitalWrite(pin, LOW);. Транзистор открывается, протекает ток через цепь, реле срабатывает. Чтобы его выключить, на базу подается плюс при помощи digitalWrite(pin, HIGH);.

Схема подключения лампы и внешний вид макета представлены на рисунках.

О том, как можно писать скетч для реле в ардуино мы уже писали ранее.

Встроенные варианты частот

/**
 * freq: 500KHz = 500000 ops/sec
 * period: 1sec/500000 = 2us
 */
void timer_init_ISR_500KHz(int timer);

/**
 * freq: 200KHz = 200000 ops/sec
 * period: 1sec/200000 = 5us
 */
void timer_init_ISR_200KHz(int timer);s

/**
 * freq: 100KHz = 100000 ops/sec
 * period: 1sec/100000 = 10us
 */
void timer_init_ISR_100KHz(int timer);

/**
 * freq: 50KHz = 50000 ops/sec
 * period: 1sec/50000 = 20us
 */
void timer_init_ISR_50KHz(int timer);

/**
 * freq: 20KHz = 20000 ops/sec
 * period: 1sec/20000 = 50us
 */
void timer_init_ISR_20KHz(int timer);

/**
 * freq: 10KHz = 10000 ops/sec
 * period: 1sec/10000 = 100us
 */
void timer_init_ISR_10KHz(int timer);

/**
 * freq: 5KHz = 5000 ops/sec
 * period: 1sec/5000 = 200us
 */
void timer_init_ISR_5KHz(int timer);

/**
 * freq: 2KHz = 2000 ops/sec
 * period: 1sec/2000 = 500us
 */
void timer_init_ISR_2KHz(int timer);

/**
 * freq: 1KHz = 1000 ops/sec
 * period: 1sec/1000 = 1ms
 */
void timer_init_ISR_1KHz(int timer);

/**
 * freq: 500Hz = 500 ops/sec
 * period: 1sec/500 = 2ms
 */
void timer_init_ISR_500Hz(int timer);

/**
 * freq: 200Hz = 200 ops/sec
 * period: 1sec/200 = 5ms
 */
void timer_init_ISR_200Hz(int timer);

/**
 * freq: 100Hz = 100 ops/sec
 * period: 1sec/100 = 10ms
 */
void timer_init_ISR_100Hz(int timer);

/**
 * freq: 50Hz = 50 ops/sec
 * period: 1sec/50 = 20ms
 */
void timer_init_ISR_50Hz(int timer);

/**
 * freq: 20Hz = 20 ops/sec
 * period: 1sec/20 = 50ms
 */
void timer_init_ISR_20Hz(int timer);

/**
 * freq: 10Hz = 10 ops/sec
 * period: 1sec/10 = 100ms
 */
void timer_init_ISR_10Hz(int timer);

/**
 * freq: 5Hz = 5 ops/sec
 * period: 1sec/5 = 200ms
 */
void timer_init_ISR_5Hz(int timer);

/**
 * freq: 2Hz = 2 ops/sec
 * period: 1sec/2 = 500ms
 */
void timer_init_ISR_2Hz(int timer);

/**
 * freq: 1Hz = 1 ops/sec
 * period: 1sec
 */
void timer_init_ISR_1Hz(int timer);

Сборка

При реализации проекта я столкнулся с двумя основными трудностями:

  • Как определить, работает ли помпа, чтобы знать, когда начинать и заканчивать отсчет.
  • Как коммутировать 170В на 20 анодов (по 10 на каждую лампу).

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

Электромагнитные и твердотельные реле

Электромагнитное реле

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

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

Классификация электромагнитных реле:

  • Управляющий ток может быть как постоянным, так и переменным. В первом случае устройство может быть нейтральным или поляризованным. Для переменного тока якорь выполняется из электротехнической стали, чтобы уменьшить потери.
  • Якорное или герконовое реле. Для якорного процесс замыкания и размыкания происходит при помощи перемещения якоря, для герконового характерно отсутствие сердечника, магнитное поле воздействует на электрод с контактами.
  • Быстродействие – до 50 мс, до 150 мс и от 1 с.
  • Зщитное покрытие – герметизированное, зачехленное и открытое.

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

Твердотельные реле

  • Долгий срок эксплуатации.
  • Быстродействие.
  • Малые размеры.
  • Отсутствуют посторонние шумы, акустические помехи, дребезги контактов.
  • Низкое потребление энергии.
  • Качественная изоляция.
  • Стойкость к вибрации и ударам.
  • Нет дугового разряда, что позволяет работать во взрывоопасных местах.

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

Твердотельные реле также имеют несколько недостатков. Во-первых, при коммутации происходит нагрев устройства. Повышение температуры устройства приводит к ограничению регулируемого тока – при температурах, превышающих 60 градусов, уменьшается величина тока, максимальная рабочая температура 80 градусов.

Твердотельные реле классифицируются по следующим признакам:

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

Step 1: Prescalers and the Compare Match Register

The Uno has three timers called timer0, timer1, and timer2.  Each of the timers has a counter that is incremented on each tick of the timer’s clock.  CTC timer interrupts are triggered when the counter reaches a specified value, stored in the compare match register.  Once a timer counter reaches this value it will clear (reset to zero) on the next tick of the timer’s clock, then it will continue to count up to the compare match value again.  By choosing the compare match value and setting the speed at which the timer increments the counter, you can control the frequency of timer interrupts.
The first parameter I’ll discuss is the speed at which the timer increments the counter.  The Arduino clock runs at 16MHz, this is the fastest speed that the timers can increment their counters.  At 16MHz each tick of the counter represents 1/16,000,000 of a second (~63ns), so a counter will take 10/16,000,000 seconds to reach a value of 9 (counters are 0 indexed), and 100/16,000,000 seconds to reach a value of 99.
In many situations, you will find that setting the counter speed to 16MHz is too fast.  Timer0 and timer2 are 8 bit timers, meaning they can store a maximum counter value of 255.  Timer1 is a 16 bit timer, meaning it can store a maximum counter value of 65535.  Once a counter reaches its maximum, it will tick back to zero (this is called overflow).  This means at 16MHz, even if we set the compare match register to the max counter value, interrupts will occur every 256/16,000,000 seconds (~16us) for the 8 bit counters, and every 65,536/16,000,000 (~4 ms) seconds for the 16 bit counter.  Clearly, this is not very useful if you only want to interrupt once a second.
Instead you can control the speed of the timer counter incrementation by using something called a prescaler.  A prescaler dictates the speed of your timer according the the following equation:(timer speed (Hz)) = (Arduino clock speed (16MHz)) / prescaler
So a 1 prescaler will increment the counter at 16MHz, an 8 prescaler will increment it at 2MHz, a 64 prescaler = 250kHz, and so on.  As indicated in the tables above, the prescaler can equal 1, 8, 64, 256, and 1024.  (I’ll explain the meaning of CS12, CS11, and CS10 in the next step.) 
Now you can calculate the interrupt frequency with the following equation:interrupt frequency (Hz) = (Arduino clock speed 16,000,000Hz) / (prescaler * (compare match register + 1))
the +1 is in there because the compare match register is zero indexed
rearranging the equation above, you can solve for the compare match register value that will give your desired interrupt frequency:compare match register = [ 16,000,000Hz/ (prescaler * desired interrupt frequency) ] — 1
remember that when you use timers 0 and 2 this number must be less than 256, and less than 65536 for timer1
so if you wanted an interrupt every second (frequency of 1Hz):
compare match register = [16,000,000 / (prescaler * 1) ] -1
with a prescaler of 1024 you get:
compare match register = [16,000,000 / (1024 * 1) ] -1
= 15,624
since 256 < 15,624 < 65,536, you must use timer1 for this interrupt.

Прерывания таймеров в Arduino

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

Прерывания переполнения таймера (Timer Overflow Interrupt)

Это прерывание происходит всегда, когда значение счетчика достигает его максимального значения, например, для 16-битного счетчика это 65535. Соответственно, процедура обработки (обслуживания) прерывания (ISR) вызывается когда бит прерывания переполнения таймера установлен (enabled) в TOIEx присутствующем в регистре масок прерываний TIMSKx.

ISR Format:

Output Compare Register (OCRnA/B) – регистр сравнения выхода

Процедура обработки прерывания сравнения выхода (Output Compare Match Interrupt) вызывается при вызове функции TIMERx_COMPy_vect если установлен бит/флаг OCFxy в регистре TIFRx. Эта процедура обработки прерывания (ISR) становится доступной при помощи установки бита OCIExy, присутствующем в регистре маски прерываний TIMSKx.

Захват входа таймера (Timer Input Capture)

Процедура обработки этого прерывания вызывается если установлен бит/флаг ICFx в регистре флагов прерываний таймера (TIFRx — Timer Interrupt Flag Register). Эта процедура обработки прерываний становится доступной при установке бита ICIEx в регистре маски прерываний TIMSKx.

Объяснение программы для Arduino

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

Arduino

#include <LiquidCrystal.h>
#include <Keypad.h>

long int set1;
long int set2;
long int set3;
long int set4;
long int j;
int t1, t2, t3, t4, t5, t6;
int r1, r2, r3;
char key;
String r;
String hours;
String minutes;
String seconds;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <LiquidCrystal.h>
#include <Keypad.h>
 

longintset1;

longintset2;

longintset3;

longintset4;

longintj;

intt1,t2,t3,t4,t5,t6;

intr1,r2,r3;

charkey;

Stringr8;

Stringhours;

Stringminutes;

Stringseconds;

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

Arduino

const byte ROWS = 4; // четыре строки
const byte COLS = 4; // четыре столбца

char keys = {
{‘1′,’2′,’3′,’A’},
{‘4′,’5′,’6′,’B’},
{‘7′,’8′,’9′,’C’},
{‘*’,’0′,’#’,’D’}
};

1
2
3
4
5
6
7
8
9

constbyteROWS=4;// четыре строки

constbyteCOLS=4;// четыре столбца

charkeysROWSCOLS={

{‘1′,’2′,’3′,’A’},

{‘4′,’5′,’6′,’B’},

{‘7′,’8′,’9′,’C’},

{‘*’,’0′,’#’,’D’}

};

Затем мы сообщаем плате Arduino к каким ее контактам подключены контакты строк и столбцов клавиатуры, а также контакты ЖК дисплея.

Arduino

byte rowPins = { 6, 7, 8, 9 }; // подсоедините контакты клавиатуры ROW0, ROW1, ROW2 и ROW3 к этим контактам Arduino
byte colPins = { 10, 11, 12, 13 };// подсоедините контакты клавиатуры COL0, COL1, COL2 и COL3 к этим контактам Arduino
LiquidCrystal lcd(A0, A1, 5, 4, 3, 2); // создаем объект ЖК дисплея с параметрами (rs, enable, d4, d5, d6, d7)

1
2
3

byterowPinsROWS={6,7,8,9};// подсоедините контакты клавиатуры ROW0, ROW1, ROW2 и ROW3 к этим контактам Arduino

bytecolPinsCOLS={10,11,12,13};// подсоедините контакты клавиатуры COL0, COL1, COL2 и COL3 к этим контактам Arduino

LiquidCrystallcd(A0,A1,5,4,3,2);// создаем объект ЖК дисплея с параметрами (rs, enable, d4, d5, d6, d7)

Следующая команда создает объект клавиатуры в программе.

Arduino

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

1 Keypadkpd=Keypad(makeKeymap(keys),rowPins,colPins,ROWS,COLS);

В функции setFeedingTime() после нажатия кнопки мы можем ввести время, с которого начнется отсчет, для начала счета после этого необходимо нажать клавишу D на клавиатуре.

Arduino

void setFeedingTime()
{
feed = true;
int i=0;

lcd.clear();
lcd.setCursor(0,0);
lcd.print(«Set feeding Time»);
lcd.clear();
lcd.print(«HH:MM:SS»);
lcd.setCursor(0,1);

while(1){
key = kpd.getKey();
char j;

if(key!=NO_KEY){
lcd.setCursor(j,1);
lcd.print(key);
r = key-48;
i++;
j++;

if (j==2 || j == 5)
{
lcd.print(«:»); j++;
}
delay(500);
}

if (key == ‘D’)
{key=0; break; }
}
lcd.clear();
}

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

voidsetFeedingTime()

{

feed=true;

inti=;

lcd.clear();

lcd.setCursor(,);

lcd.print(«Set feeding Time»);

lcd.clear();

lcd.print(«HH:MM:SS»);

lcd.setCursor(,1);

while(1){

key=kpd.getKey();

charj;

if(key!=NO_KEY){

lcd.setCursor(j,1);

lcd.print(key);

ri=key-48;

i++;

j++;

if(j==2||j==5)

{

lcd.print(«:»);j++;

}

delay(500);

}

if(key==’D’)

{key=;break;}

}

lcd.clear();

}

В функции void setup() мы инициализируем ЖК дисплей и последовательную связь, а также задаем режим работы (на ввод или вывод данных) для используемых контактов.

Arduino

void setup()
{
lcd.begin(16,2);
Serial.begin(9600);
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A3, INPUT);
pinMode(A4, OUTPUT);
}

1
2
3
4
5
6
7
8
9

voidsetup()

{

lcd.begin(16,2);

Serial.begin(9600);

pinMode(A0,OUTPUT);

pinMode(A1,OUTPUT);

pinMode(A3,INPUT);

pinMode(A4,OUTPUT);

}

Встроенные варианты частот

/**
 * freq: 500KHz = 500000 ops/sec
 * period: 1sec/500000 = 2us
 */
void timer_init_ISR_500KHz(int timer);

/**
 * freq: 200KHz = 200000 ops/sec
 * period: 1sec/200000 = 5us
 */
void timer_init_ISR_200KHz(int timer);s

/**
 * freq: 100KHz = 100000 ops/sec
 * period: 1sec/100000 = 10us
 */
void timer_init_ISR_100KHz(int timer);

/**
 * freq: 50KHz = 50000 ops/sec
 * period: 1sec/50000 = 20us
 */
void timer_init_ISR_50KHz(int timer);

/**
 * freq: 20KHz = 20000 ops/sec
 * period: 1sec/20000 = 50us
 */
void timer_init_ISR_20KHz(int timer);

/**
 * freq: 10KHz = 10000 ops/sec
 * period: 1sec/10000 = 100us
 */
void timer_init_ISR_10KHz(int timer);

/**
 * freq: 5KHz = 5000 ops/sec
 * period: 1sec/5000 = 200us
 */
void timer_init_ISR_5KHz(int timer);

/**
 * freq: 2KHz = 2000 ops/sec
 * period: 1sec/2000 = 500us
 */
void timer_init_ISR_2KHz(int timer);

/**
 * freq: 1KHz = 1000 ops/sec
 * period: 1sec/1000 = 1ms
 */
void timer_init_ISR_1KHz(int timer);

/**
 * freq: 500Hz = 500 ops/sec
 * period: 1sec/500 = 2ms
 */
void timer_init_ISR_500Hz(int timer);

/**
 * freq: 200Hz = 200 ops/sec
 * period: 1sec/200 = 5ms
 */
void timer_init_ISR_200Hz(int timer);

/**
 * freq: 100Hz = 100 ops/sec
 * period: 1sec/100 = 10ms
 */
void timer_init_ISR_100Hz(int timer);

/**
 * freq: 50Hz = 50 ops/sec
 * period: 1sec/50 = 20ms
 */
void timer_init_ISR_50Hz(int timer);

/**
 * freq: 20Hz = 20 ops/sec
 * period: 1sec/20 = 50ms
 */
void timer_init_ISR_20Hz(int timer);

/**
 * freq: 10Hz = 10 ops/sec
 * period: 1sec/10 = 100ms
 */
void timer_init_ISR_10Hz(int timer);

/**
 * freq: 5Hz = 5 ops/sec
 * period: 1sec/5 = 200ms
 */
void timer_init_ISR_5Hz(int timer);

/**
 * freq: 2Hz = 2 ops/sec
 * period: 1sec/2 = 500ms
 */
void timer_init_ISR_2Hz(int timer);

/**
 * freq: 1Hz = 1 ops/sec
 * period: 1sec
 */
void timer_init_ISR_1Hz(int timer);

Реле Ардуино: распиновка, характеристики

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


Реле SRD-05VDC-SL-C Ардуино: распиновка, характеристики

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

Согласно характеристикам реле SRD-05VDC-SL-C, для переключения контактов достаточно около 5 Вольт 20 мА, выводы на Ардуино способны выдавать до 40 мА. Таким образом с помощью Ардуино мы можем управлять не только лампой накаливания, но и любым бытовым прибором — обогревателем, холодильником и т.д. Полевые транзисторы на Ардуино могут управлять токами только до 100 Вольт.

Кухонный таймер Ардуино с энкодером

Сейчас рассмотрим, как сделать таймер на Ардуино своими руками с энкодером и LCD. Принцип управления, подобен предыдущему варианту. Поворотом ручки энкодера можно задать необходимый временной интервал, а нажатием на ручку можно запускать и останавливать обратный отсчет времени. Далее размещена схема сборки проекта на Arduino Nano, этот проект можно собрать и на плате Arduino Uno.

Скетч таймера обратного отсчета времени

#include <Wire.h>                              // библиотека для протокола I2C
#include <LiquidCrystal_I2C.h>        // библиотека для LCD 1602 
LiquidCrystal_I2C LCD(0x27, 20, 2);  // присваиваем имя дисплею

#include <RotaryEncoder.h>                // библиотека для энкодера
RotaryEncoder encoder(4, 2);       // пины подключение энкодера (DT, CLK)

// задаем шаг энкодера, максимальное и минимальное значение
#define STEPS  1
#define POSMIN 0
#define POSMAX 30

int lastPos, newPos;
boolean buttonWasUp = true;

byte w = 0;

int SEC = 0;
int MIN = 0;
unsigned long timer;

void setup() {
   pinMode(6, INPUT_PULLUP);   // пин для кнопки энкодера
   encoder.setPosition(0 / STEPS);

   pinMode(10, OUTPUT);   // подключаем светодиод и зуммер
   pinMode(12, OUTPUT);
   digitalWrite(10, HIGH);

   LCD.init();                        // инициализация дисплея
   LCD.backlight();              // включение подсветки

   LCD.setCursor(2, 0);
   LCD.print("TIMER  STOP");
   LCD.setCursor(5, 1);
   LCD.print(MIN);
   LCD.print(" : ");
   LCD.print(SEC);
}

void loop() {

   // проверяем положение ручки энкодера
   encoder.tick();
   newPos = encoder.getPosition() * STEPS;
   if (newPos < POSMIN) {
      encoder.setPosition(POSMIN / STEPS);
      newPos = POSMIN;
   }
   else if (newPos > POSMAX) {
      encoder.setPosition(POSMAX / STEPS);
      newPos = POSMAX;
   }

   // если положение изменилось - меняем переменную MIN и выводим на дисплей
   if (lastPos != newPos) {
      MIN = newPos;
      lastPos = newPos;
      LCD.clear();
      LCD.setCursor(2, 0);
      LCD.print("TIMER  STOP");
      LCD.setCursor(5, 1);
      LCD.print(MIN);
      LCD.print(" : ");
      LCD.print(SEC);
   }

   // если была нажата кнопка энкодера запускаем отсчет времени
   boolean buttonIsUp = digitalRead(6);
   if (buttonWasUp && !buttonIsUp && MIN > 0) {
      delay(10);
      buttonIsUp = digitalRead(6);
      if (!buttonIsUp) {
         if (SEC == 0) { SEC = 60; MIN = MIN - 1; }
         if (MIN < 0 ) { MIN = 0; }
         digitalWrite(10, LOW);
         w = 1;
      }
   }
   buttonWasUp = buttonIsUp; // запоминаем состояние кнопки

   while (w == 1 ) {
      // если прошло 995 мс - вычитаем одну секунду от переменной SEC
      if (millis() - timer > 993) {
         timer = millis();
         SEC = SEC - 1;
 
      // если отсчет закончился - обнуляемся, включаем сигнал и выходим из цикла
      if (SEC == 0 && MIN == 0) {
         lastPos = 0; newPos = 0; MIN = 0; SEC = 0;
         LCD.clear();
         LCD.setCursor(2, 0);
         LCD.print("TIMER  STOP");
         LCD.setCursor(5, 1);
         LCD.print(MIN);
         LCD.print(" : ");
         LCD.print(SEC);
         digitalWrite(10, HIGH);
         tone(12, 100);
         delay(500);
         noTone(12);
         w = 0;
      }

      // если секунды дошли до нуля - вычитаем одну минуту
      if (SEC == 0 && w==1) {
         SEC = 59; MIN = MIN - 1;
         if (MIN < 0 ) { MIN = 0; }
      }

      // если из цикла while еще не вышли - выводим информацию на дисплей
      if (w == 1) {
         LCD.clear();
         LCD.setCursor(2, 0);
         LCD.print("TIMER START");
         LCD.setCursor(5, 1);
         LCD.print(MIN);
         LCD.print(" : ");
         LCD.print(SEC);
      }
    }

    // если была нажата кнопка - обнуляем переменные и выходим из цикла
    buttonIsUp = digitalRead(6);
    if (buttonWasUp && !buttonIsUp) {
       delay(10);
       buttonIsUp = digitalRead(6);
       if (!buttonIsUp) {
          lastPos = 0; newPos = 0; MIN = 0; SEC = 0;
          LCD.clear();
          LCD.setCursor(2, 0);
          LCD.print("TIMER  STOP");
          LCD.setCursor(5, 1);
          LCD.print(MIN);
          LCD.print(" : ");
          LCD.print(SEC);
          digitalWrite(10, HIGH);
          w = 0;
       }
    }
    buttonWasUp = buttonIsUp; // запоминаем состояние кнопки
  }
}

Пояснения к коду:

  1. частоту звукового сигнала можно изменить через команду tone();
  2. для скетча потребуется установить библиотеку RotaryEncoder.

Базовые вызовы

/**
 * Init ISR (Interrupt service routine) for the timer and start timer.
 * 
 * General algorithm
 * http://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts
 * 1. CPU frequency 16Mhz for Arduino
 * 2. maximum timer counter value (256 for 8bit, 65536 for 16bit timer)
 * 3. Divide CPU frequency through the choosen prescaler (16000000 / 256 = 62500)
 * 4. Divide result through the desired frequency (62500 / 2Hz = 31250)
 * 5. Verify the result against the maximum timer counter value (31250 < 65536 success).
 *    If fail, choose bigger prescaler.
 * 
 * Example: to set timer clock period to 20ms (50 operations per second == 50Hz)
 * 
 * 1) on 16MHz CPU (AVR Arduino)
 *   use prescaler 1:8 (TIMER_PRESCALER_1_8) and adjustment=40000-1:
 *   16000000/8/50=40000, minus 1 cause count from zero.
 * 
 * 2) on 80MHz CPU (PIC32MX ChipKIT)
 *   use prescaler 1:64 (TIMER_PRESCALER_1_64) and adjustment=25000-1:
 *   80000000/64/50=25000, minus 1 cause count from zero.
 *
 * 3) on 84MHz CPU (SAM Arduino Due)
 *   use prescaler 1:128 (TIMER_PRESCALER_1_128) and adjustment=13125-1:
 *   80000000/128/50=13125, minus 1 cause count from zero.
 * 
 * Timer interrupt handler timer_handle_interrupts would be called every 20ms
 * (50 times per second == 50Hz freq) in this case.
 * 
 * @param timer
 *   system timer id: use TIMER_DEFAULT for default timer
 *   or _TIMER1...TIMER9, _TIMER1_32BIT..._TIMER9_32BIT for specific timer.
 *   note: availability of specific timer depends on the platform.
 * @param prescaler
 *   timer prescaler (1, 2, 4, 8, 16, 32, 64, 128, 256, 1024),
 *   use constants: PRESCALER_1_1, PRESCALER_1_2, PRESCALER_1_8,
 *   PRESCALER_1_16, PRESCALER_1_32, PRESCALER_1_64, PRESCALER_1_128
 *   PRESCALER_1_256, PRESCALER_1_1024
 *   note: availability of specific prescaler depends on the platform.
 * @param adjustment
 *   adjustment divider after timer prescaled - timer compare match value.
 */
void timer_init_ISR(int timer, int prescaler, int adjustment);

/**
 * Stop ISR (Interrupt service routine) for the timer.
 * 
 * @param timer
 *     system timer id for started ISR
 */
void timer_stop_ISR(int timer);

/**
 * Timer ISR (Interrupt service routine) handler.
 * Implementation must be provided in module with user code.
 * 
 * @param timer
 *     system timer id for started ISR 
 */
void timer_handle_interrupts(int timer);