Таймер обратного отсчета на Arduino с кнопками или энкодером и дисплеем 1602 I2C — интересный и полезный проект. Рассмотрим сразу два варианта таймера обратного отсчета на Arduino Uno, который можно использовать на кухне для включения света и звуковой индикации или автоматического включения реле от платы Arduino. Вы сможете сами выбрать наиболее подходящий вариант секундомера для вашего проекта.
СОДЕРЖАНИЕ
Необходимые компоненты:
- Arduino Uno / Arduino Nano / Arduino Mega
- тактовые кнопки / encoder ky-040
- экран lcd 1602 с модулем i2c
- светодиоды и резисторы
- макетная плата
- коннекторы
- библиотека LiquidCrystal_I2C.h и RotaryEncoder.h
Дополнительные материалы на эту тему:
Первый вариант представляет собой таймер Arduino с кнопочным управлением. Нажимая на первую и вторую кнопки, можно увеличивать и уменьшать временной интервал в минутах. Нажатие на третью кнопку, подключенную к пину 4, запускает обратный отсчет. По окончании обратного отсчета загорается светодиод и включается зуммер. Четвертая кнопка, подключенная к цифровому пину 5 платы, используется для сброса таймера.
Таймер Arduino с обратным отсчётом на LCD с кнопкой

| LCD 1602 i2c | Arduino Uno | Arduino Nano | Arduino Mega |
| GND | GND | GND | GND |
| VCC | 5V | 5V | 5V |
| SDA | A4 | A4 | 20 |
| SCL | A5 | A5 | 21 |
Секундомер с обратным отсчетом можно остановить в любой момент, нажав третью кнопку, подключенную к пину 4. После сборки электрической схемы, как на показано на изображении выше, загрузите в микроконтроллер Arduino следующий пример программы. Обратите внимание, что для работы таймера на дисплее LCD 1602 с модулем I2C необходимо сначала установить библиотеку популярную LiquidCrystal_I2C.
Скетч для таймера на Ардуино с кнопкой и дисплеем
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27, 16, 2);
#define LED 10
#define BUZ 12
#define B1 2
#define B2 3
#define B3 4
#define B4 5
boolean button1WasUp = true;
boolean button2WasUp = true;
boolean button3WasUp = true;
boolean button4WasUp = true;
byte w = 0;
int SEC = 0;
int MIN = 0;
unsigned long timer;
void setup() {
pinMode(B1, INPUT_PULLUP);
pinMode(B2, INPUT_PULLUP);
pinMode(B3, INPUT_PULLUP);
pinMode(B4, INPUT_PULLUP);
pinMode(BUZ, OUTPUT);
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
LCD.begin();
LCD.backlight();
LCD.setCursor(2, 0);
LCD.print("TIMER STOP");
LCD.setCursor(5, 1);
LCD.print(MIN);
LCD.print(" : ");
LCD.print(SEC);
}
void loop() {
boolean button1IsUp = digitalRead(B1);
boolean button2IsUp = digitalRead(B2);
boolean button3IsUp = digitalRead(B3);
boolean button4IsUp = digitalRead(B4);
if (button1WasUp && !button1IsUp) {
delay(10);
button1IsUp = digitalRead(B1);
if (!button1IsUp) {
MIN = MIN - 1; SEC = 0;
if (MIN < 0) { MIN = 0; }
LCD.clear();
LCD.setCursor(2, 0);
LCD.print("TIMER STOP");
LCD.setCursor(5, 1);
LCD.print(MIN);
LCD.print(" : ");
LCD.print(SEC);
}
}
button1WasUp = button1IsUp;
if (button2WasUp && !button2IsUp) {
delay(10);
button2IsUp = digitalRead(B2);
if (!button2IsUp) {
MIN = MIN + 1; SEC = 0;
LCD.clear();
LCD.setCursor(2, 0);
LCD.print("TIMER STOP");
LCD.setCursor(5, 1);
LCD.print(MIN);
LCD.print(" : ");
LCD.print(SEC);
}
}
button2WasUp = button2IsUp;
if (button3WasUp && !button3IsUp && MIN > 0) {
delay(10);
button3IsUp = digitalRead(B3);
if (!button3IsUp) {
if (SEC == 0) { SEC = 60; MIN = MIN - 1; }
if (MIN < 0 ) { MIN = 0; }
digitalWrite(LED, LOW);
w = 1;
}
}
button3WasUp = button3IsUp;
if (button4WasUp && !button4IsUp) {
delay(10);
button4IsUp = digitalRead(B4);
if (!button4IsUp) {
MIN = 0; SEC = 0;
digitalWrite(10, HIGH);
LCD.clear();
LCD.setCursor(2, 0);
LCD.print("TIMER STOP");
LCD.setCursor(5, 1);
LCD.print(MIN);
LCD.print(" : ");
LCD.print(SEC);
}
}
button4WasUp = button4IsUp;
while (w == 1 ) {
if (millis() - timer > 995) {
timer = millis();
SEC = SEC - 1;
if (SEC == 0 && MIN == 0) {
LCD.clear();
LCD.setCursor(2, 0);
LCD.print("TIMER STOP");
LCD.setCursor(5, 1);
LCD.print(MIN);
LCD.print(" : ");
LCD.print(SEC);
digitalWrite(LED, HIGH);
tone(BUZ, 100);
delay(500);
noTone(BUZ);
w = 0;
}
if (SEC == 0) {
SEC = 59; MIN = MIN - 1;
if (MIN < 0 ) { MIN = 0; }
}
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);
}
}
boolean button3IsUp = digitalRead(B3);
if (button3WasUp && !button3IsUp) {
delay(10);
button3IsUp = digitalRead(B3);
if (!button3IsUp) {
LCD.setCursor(2, 0);
LCD.print("TIMER STOP");
w = 0;
}
}
button3WasUp = button3IsUp;
}
}
Таймер Arduino с обратным отсчётом на LCD с энкодером

Теперь мы рассмотрим, как сделать таймер на Arduino с энкодером KY-040 и выводом информации на дисплей. Принцип управления аналогичен предыдущему. Вращая ручку энкодера, вы можете установить необходимый интервал минут секундомера, а нажимая на кнопку, вы можете запускать и останавливать обратный отсчет. На схеме выше показана схема сборки проекта на Arduino Uno, но проект может быть собран и на Arduino Nano.
Скетч для таймера на Ардуино с энкодером и дисплеем
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27, 20, 2);
#include "RotaryEncoder.h"
RotaryEncoder encoder(3, 2); // DT, CLK
#define STEPS 1
#define POSMIN 0
#define POSMAX 30
#define LED 10
#define BUZ 12
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(BUZ, OUTPUT);
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
LCD.begin();
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;
}
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(LED, LOW);
w = 1;
}
}
buttonWasUp = buttonIsUp; // запоминаем состояние кнопки
while (w == 1 ) {
if (millis() - timer > 1000) {
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(LED, HIGH);
tone(BUZ, 100);
delay(500);
noTone(BUZ);
w = 0;
}
if (SEC == 0 && w==1) {
SEC = 59; MIN = MIN - 1;
if (MIN < 0 ) { MIN = 0; }
}
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(LED, HIGH);
w = 0;
}
}
buttonWasUp = buttonIsUp; // запоминаем состояние кнопки
}
}
Заключение. В данном обзоре представлены два варианта сборки часов с таймером на Ардуино для кухни или аквариума своими руками. Частоту зуммера можно изменить с помощью команды tone, а для скетча необходимо установить библиотеку RotaryEncoder и LiquidCrystal_I2C. В комментариях вы можете оставить вопросы по данному проекту или предложить свой вариант таймера обратного отсчета с кнопкой или энкодером.

Пишет что нет такой функции в библиотеке как «Begin»
Попробуйте LCD.init();
Не могу найти официальную библиотеку «Liquidcrystal.h», искал на Arduino ide 1.8.19 .
Liquidcrystal.h искать не надо, она уже есть в стандартных библиотеках по умолчанию
как подключать дисплей?
Перед обновлением минуты лучше использовать проверку не SEC == 0, а SEC < 0, тогда на таймере будет отображаться и 0, а только потом следующая минута и 59 секунд. В текущем варианте при переходе с 5:01 на 4:59 таймер пропустит отображение 5:00.
#include «RotaryEncoder.h»
пишет ошибку
Последняя кнопка должна быть в пятом пине, а не в четвёртом. Пятый пин забыли.