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


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

Таймер с обратным отсчетом на Arduino 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));
   }

}

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

  1. секунда прибавляется через 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
   }
}

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

  1. в цикле while секунда вычитается через 1000 мс;
  2. сбросить таймер можно только, остановив обратный отсчет времени.



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

Сейчас рассмотрим, как сделать таймер на Ардуино своими руками с энкодером и 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; // запоминаем состояние кнопки
  }
}

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

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

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



13 Replies to “Таймер на Ардуино с обратным отсчётом”

  1. Новичек в ардуино ,очерь хочу разобраться хотя работаю наладчиком на чпу,стоит задача создание водосчетчика с обратным отчетом для контроля работы фильтров ,то есь задается определенное значение литров после чего его необходимо промыть ,вопрос от чего отталкиваться ?

  2. Вопрос вам — где и как вы сделали схему самого проект? Можете пожалуйста сказать? Пробовал повторить в Tinkercard — не получилось, там нету такого как у вас. Вот… Скажите пожалуйста где вы это сделали

  3. Здравы будьте. Есть ли возможность прописать в скетче Кухонный таймер Ардуино с энкодером выход на исполнительное реле чтобы оно включалось в момент нажатия пуск и выключалось по истечению времени таймера? В скетчах я товарищ дерево

    1. Подключите реле к 10 пину, вместо светодиода. И поменяйте местами команды для включения digitalWrite(10, LOW); и digitalWrite(10, HIGH);

  4. Подскажите.Как организовать установку секунд с шагом 10 секунд и максимальным временем 10 минут.

    1. Ограничение таймера по минутам:

      после операции сложения: MIN = MIN + 1; SEC = 0;
      добавить условие: if (MIN > 10) { MIN = 10; }

      С секундами сложнее — надо дописывать программу

  5. Зачем всё так сложно?
    Зачем таймер хранить в минутах и секундах?
    Гораздо проще хранить его в виде количества секунд в integer…
    У вас практически идиентичный блок вывода на экран пять раз повторяется в коде, зачем?
    Напишите функцию вывода текущего времени на экран, в ней же преобразовывайте секунды в часы:минуты:секунды. В ней же обновляйте на экране только изменившиеся цифры чтобы весь экран не моргал каждую секунду от очистки…

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.