СОДЕРЖАНИЕ ►
Таймер на Ардуино с обратным отсчетом с кнопками или энкодером и дисплеем LCD 1602 I2C — интересный и полезный проект. Рассмотрим несколько вариантов таймера с отсчетом времени на Arduino Nano или Uno, которые можно использовать на кухне или в аквариуме для включения световой и звуковой индикации или реле от Ардуино. А вы можете выбрать для себя наиболее подходящий вариант данного проекта.

Простой таймер Ардуино millis()
Чтобы понять принцип работы функции millis() Arduino продемонстрируем пример программы счетчика с выводом времени на монитор порта. Команда millis позволяет осуществлять задержу в выполнении программы без delay и осуществлять при выполнении программы многозадачность. Отсчет времени начинается сразу после загрузки программы в микроконтроллер и открытия монитора порта Arduino IDE.
// переменные для отсчета минут и секунд int SEC = 0; int MIN = 0; unsigned long timer; void setup() { Serial.begin(9600); timer = millis(); } void loop() { // если прошло 1000 мс - прибавляем одну секунду к переменной SEC if (millis() - timer > 1000) { timer = millis(); SEC = SEC + 1; if (SEC > 59) { SEC = 0; MIN = MIN + 1; } // выводим текущий счетчик времени на монитор порта Serial.println(String(MIN) + " : " + String(SEC)); } }
Пояснения к коду:
- секунда прибавляется через 1000 мс, минута прибавляется когда переменная SEC станет больше 59.
Таймер на Arduino Nano с LCD 1602
Для этого занятия потребуется:
- Arduino Uno / Arduino Nano / Arduino Mega;
- дисплей LCD 1602;
- энкодер ардуино / тактовые кнопки;
- зуммер, светодиод и резистор 220 Ом;
- макетная плата;
- провода «папа-папа», «папа-мама».
Первый вариант проекта — таймер на Ардуино с управлением от кнопки. При нажатии на первую и вторую кнопку можно увеличивать и уменьшать временной интервал в минутах. При клике на третью кнопку, подключенную к пину 6 Ардуино Нано, запускает обратный отсчет. По окончании отсчета зажигается светодиод и включается звуковой сигнал. Четвертая кнопка, подключенная к пину 8, служит для сброса таймера.
Схема сборки таймера на Ардуино с кнопками

Также таймер можно в любой момент остановить нажатием на третью кнопку. После сборки электрической схемы, загрузите следующий пример программы таймера на Ардуино. Обратите внимание, что для работы часов на дисплее с I2C модулем, потребуется установить библиотеку LiquidCrystal_I2C.h. Эту и другие популярные библиотеки можно скачать на нашем сайте на странице — Библиотеки для Ардуино.
Скетч для таймера на Ардуино Нано с кнопками
#include "Wire.h" // библиотека для протокола I2C #include "LiquidCrystal_I2C.h" // библиотека для LCD 1602 LiquidCrystal_I2C LCD(0x27, 20, 2); // присваиваем имя дисплею 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(2, INPUT_PULLUP); // подключаем тактовые кнопки pinMode(4, INPUT_PULLUP); pinMode(6, INPUT_PULLUP); pinMode(8, INPUT_PULLUP); 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() { boolean button1IsUp = digitalRead(2); // узнаем текущее состояние кнопок boolean button2IsUp = digitalRead(4); boolean button3IsUp = digitalRead(6); boolean button4IsUp = digitalRead(8); // при нажатии на первую кнопку вычитаем минуту и выводим на дисплей if (button1WasUp && !button1IsUp) { delay(10); button1IsUp = digitalRead(2); 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; // запоминаем состояние кнопки 1 // при нажатии на вторую кнопку прибавляем минуту и выводим на дисплей if (button2WasUp && !button2IsUp) { delay(10); button2IsUp = digitalRead(4); 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; // запоминаем состояние кнопки 2 // при нажатии на третью кнопку выключаем светодиод и переходим в цикл while if (button3WasUp && !button3IsUp && MIN > 0) { delay(10); button3IsUp = digitalRead(6); if (!button3IsUp) { if (SEC == 0) { SEC = 60; MIN = MIN - 1; } if (MIN < 0 ) { MIN = 0; } digitalWrite(10, LOW); w = 1; } } button3WasUp = button3IsUp; // запоминаем состояние кнопки 3 // при нажатии на четвертую кнопку обнуляем счетчик и включаем светодиод if (button4WasUp && !button4IsUp) { delay(10); button4IsUp = digitalRead(8); 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; // запоминаем состояние кнопки 4 while (w == 1 ) { // если прошло 1000 мс - вычитаем одну секунду от переменной SEC if (millis() - timer > 1000) { 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(10, HIGH); tone(12, 100); delay(500); noTone(12); w = 0; } // если секунды дошли до нуля - вычитаем одну минуту if (SEC == 0) { 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); } } // если была нажата третья кнопка, выходим из цикла без обнуления счетчика boolean button3IsUp = digitalRead(6); if (button3WasUp && !button3IsUp) { delay(10); button3IsUp = digitalRead(6); if (!button3IsUp) { LCD.setCursor(2, 0); LCD.print("TIMER STOP"); w = 0; } } button3WasUp = button3IsUp; // запоминаем состояние кнопки 3 } }
Пояснения к коду:
- в цикле while секунда вычитается через 1000 мс;
- сбросить таймер можно только, остановив обратный отсчет времени.
Кухонный таймер Ардуино с энкодером
Сейчас рассмотрим, как сделать таймер на Ардуино своими руками с энкодером и 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 ) { // если прошло 1000 мс - вычитаем одну секунду от переменной SEC 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(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; // запоминаем состояние кнопки } }
Пояснения к коду:
- частоту звукового сигнала можно изменить через команду tone();
- для скетча потребуется установить библиотеку RotaryEncoder.
Заключение. В этом обзоре представлено лишь два варианта изготовления часов с таймером для аквариума или кухни своими руками. В комментариях вы можете оставить вопросы по данному проекту (если они есть) или предложить свой вариант проекта с обратным отсчетом времени, который можно добавить к этому обзору.










Новичек в ардуино ,очерь хочу разобраться хотя работаю наладчиком на чпу,стоит задача создание водосчетчика с обратным отчетом для контроля работы фильтров ,то есь задается определенное значение литров после чего его необходимо промыть ,вопрос от чего отталкиваться ?
У вас есть счетчик воды, таймер здесь совсем не нужен
Что значит 0х27 в строке LiquidCrystal_I2C LCD(0x27, 20, 2);
Это адрес дисплея на шине i2c Ардуино
При работе с шаговым двигателем, не будут влиять на таймер?
Вопрос вам — где и как вы сделали схему самого проект? Можете пожалуйста сказать? Пробовал повторить в Tinkercard — не получилось, там нету такого как у вас. Вот… Скажите пожалуйста где вы это сделали
В программе Arduino IDE с настоящей платой и деталями
Здравы будьте. Есть ли возможность прописать в скетче Кухонный таймер Ардуино с энкодером выход на исполнительное реле чтобы оно включалось в момент нажатия пуск и выключалось по истечению времени таймера? В скетчах я товарищ дерево
Подключите реле к 10 пину, вместо светодиода. И поменяйте местами команды для включения digitalWrite(10, LOW); и digitalWrite(10, HIGH);
Все разобрался + увеличил частоту и время звучания зуммера
Подскажите.Как организовать установку секунд с шагом 10 секунд и максимальным временем 10 минут.
Ограничение таймера по минутам:
после операции сложения: MIN = MIN + 1; SEC = 0;
добавить условие: if (MIN > 10) { MIN = 10; }
С секундами сложнее — надо дописывать программу
Зачем всё так сложно?
Зачем таймер хранить в минутах и секундах?
Гораздо проще хранить его в виде количества секунд в integer…
У вас практически идиентичный блок вывода на экран пять раз повторяется в коде, зачем?
Напишите функцию вывода текущего времени на экран, в ней же преобразовывайте секунды в часы:минуты:секунды. В ней же обновляйте на экране только изменившиеся цифры чтобы весь экран не моргал каждую секунду от очистки…
Нужен был таймер, самому писать было лень. Нагуглил первый попавшийся пример — ваш. Начал его модифицировать чтобы добавить часы. Заблудился в вашем коде, плюнул и написал свой таймер с нуля