Таймер обратного отсчета на Arduino


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

Внешний вид таймера обратного отсчета на Arduino

В этой статье мы рассмотрим создание таймера обратного отсчета на основе платы Arduino. Для получения информации о текущем времени в данном проекте мы не будем использовать модуль часов реального времени (Real Time Clock, RTC). Длительность временного промежутка для счета будет задаваться с помощью клавиатуры 4х4 и ЖК дисплея 16x2. Когда таймер будет досчитывать до нуля будет издаваться звуковой сигнал с помощью зуммера.

Необходимые компоненты

  1. Плата Arduino Uno (купить на AliExpress).
  2. ЖК дисплей 16х2 (купить на AliExpress).
  3. Клавиатура (клавишная панель) 4х4 (купить на AliExpress).
  4. Зуммер (Buzzer) (купить на AliExpress).
  5. Кнопка.
  6. Потенциометр (10 кОм) (купить на AliExpress).
  7. Резистор 10 кОм (купить на AliExpress).
  8. Резистор 100 Ом (купить на AliExpress).
  9. Соединительные провода.

Работа схемы

Схема таймера обратного отсчета на основе платы Arduino представлена на следующем рисунке.

Схема таймера обратного отсчета на основе платы ArduinoПлата Arduino Uno управляет всеми процессами в схеме. Клавиатура используется для ввода продолжительности временного интервала (откуда считать), а ЖК дисплей применяется для отображения обратного отсчета. Кнопка используется для запуска отсчета. Более подробно про подключение клавиатуры 4х4 к плате Arduino можно прочитать в этой статье, а про подключение ЖК дисплея к Arduino – в этой.

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

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

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

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

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

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

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

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

Принцип работы проекта достаточно прост. После запуска программы на экране ЖК дисплея высветится надпись “Arduino Timer” и она будет гореть до тех пор пока вы не нажмете кнопку. После нажатия кнопки программа попросит вас ввести время, с которого начнется обратный отсчет, при помощи вызова функции “setFeedingTime”. Время вводится с помощью клавиатуры. После ввода времени необходимо нажать клавишу ‘D’ на клавиатуре чтобы сохранить введенное время и начать обратный отсчет.

Начало обратного отсчета в нашем проекте

Далее в функции loop() мы будем выполнять ряд вычислений чтобы осуществить уменьшение счета (секунда за секундой) и показывать на ЖК дисплее оставшееся до истечения таймера время в формате HH:MM:SS. Более подробно все эти процессы показаны на видео, приведенном в конце статьи.

Когда таймер обратного отсчета достигнет нуля зуммер начнет издавать звуки (100 раз если его не прервать). Чтобы остановить сигнал зуммера необходимо нажать и удерживать кнопку. Также нажать кнопку можно в любое время если вы хотите остановить таймер.

Таймер обратного отсчета досчитал до нуля

Исходный код программы

Текст программы снабжен комментариями, помогающими легче понять его смысл.

(Проголосуй первым!)
Загрузка...
7 973 просмотров

Комментарии

Таймер обратного отсчета на Arduino — 17 комментариев

  1. Здравствуйте! Хотел спросиить насчет таймера - как увеличить его точность? Поможет ли в этом модуль реального времени? Спасибо!

    • Добрый вечер. Да, с помощью модуля реального времени увеличить точность можно. Пример его подключения к плате Ардуино можно посмотреть в этой статье.

    • А в чем конкретно возникает проблема? Посмотрел текст программы, вроде бы проблем не увидел чтобы дни добавить

      • Я дни добавил, но проблема с алгоритмом просчета времени..
        Вот скетч. Если не трудно, помогите с алгоритмом...

    • Извините, в первом не то скинул...
      Вот что получилось...

      #include
      #include
      const byte ROWS = 4; // четыре строки
      const byte COLS = 4; // четыре столбца
      long int set0;
      long int set1;
      long int set2;
      long int set3;
      long int set4;
      long int j;

      String days;
      String hours;
      String minutes;
      String seconds;
      char keys[ROWS][COLS] = { // Визначте розкладку клавіш
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
      };
      byte rowPins[ROWS] = { 6, 7, 8, 9 };// подсоедините контакты клавиатуры ROW0, ROW1, ROW2 и ROW3 к этим контактам Arduino
      byte colPins[COLS] = { 10, 11, 12, 13 };// подсоедините контакты клавиатуры COL0, COL1, COL2 и COL3 к этим контактам Arduino
      Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
      LiquidCrystal lcd(A0, A1, 5, 4, 3, 2); // создаем объект ЖК дисплея с параметрами (rs, enable, d4, d5, d6, d7)

      int t1, t2, t3, t4, t5, t6;
      int r1, r2, r3;

      boolean feed = true; // условие для срабатывания сигнализации
      char key;
      String r[9];

      void setFeedingTime()
      {
      feed = true;
      int i = 0;
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Setup Time");
      delay(500);
      lcd.clear();
      lcd.print("DD: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[i] = key - 48;
      i++;
      j++;
      if (j == 2 || j == 5 || j == 8)
      {
      lcd.print(":"); j++;
      }
      delay(500);
      }
      if (key == 'D')
      {
      key = 0;
      digitalWrite(A5, HIGH);
      break;
      }
      }
      lcd.clear();
      }

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

      void loop()
      {
      lcd.setCursor(5, 0);
      lcd.print("Timer"); //Serial.println(A3);
      if (digitalRead(A3) == 1)
      {
      lcd.clear();
      setFeedingTime();
      for (int i = 0; i = 0; j--) // этот цикл используется для уменьшения
      { //общего времени счета в секундах
      Serial.println(j);
      lcd.setCursor(0, 0);
      lcd.print("DD:HH:MM:SS");

      long int DD = (j / 86400); // конвертируем оставшееся время в дни
      lcd.setCursor(0, 1);
      Serial.println(DD);
      if (DD < 10) {
      lcd.print('0');
      }
      lcd.print(DD);
      lcd.print(":");

      long int HH = j / 3600; // конвертируем оставшееся время в часы
      lcd.setCursor(3, 1);
      Serial.println(HH);
      if (HH < 10) {
      lcd.print('0');
      }
      lcd.print(HH);
      lcd.print(":");

      long int MM = (j - (HH * 3600)) / 60 ; // конвертируем оставшееся время в минуты
      lcd.setCursor(6, 1);
      Serial.println(MM);
      if (MM < 10) {
      lcd.print('0');
      }
      lcd.print(MM);
      lcd.print(":");

      long int SS = j - ((HH * 3600) + (MM * 60)); // конвертируем оставшееся время в секунды
      lcd.setCursor(9, 1);
      Serial.println(SS);
      if (SS < 10) {
      lcd.print('0');
      }
      lcd.print(SS);
      delay(1000);
      if (j == 0)
      {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Timer Stop");
      lcd.setCursor(2, 1);
      lcd.print("-Ring-Ring-");

      for (int k = 0; k <= 3; k++) // этот цикл используется для того чтобы зуммер звучал 100 раз после того как таймер достигнет нуля
      {
      digitalWrite(A4, HIGH);
      delay(1000);
      digitalWrite(A4, LOW);
      delay(300);
      lcd.clear();
      if (digitalRead(A3) == 1) {
      break;
      }
      }
      }
      }
      }
      }

      • Ну как минимум у вас в этом цикле ошибка: for (int i = 0; i = 0; j--)
        Получается что он у вас не выполнится ни разу. И почему если цикл по i, то декрементируется переменная j? Явно что то не то

        • Это я исправил. Но вот когда я настраиваю, к примеру DD-01, HH-24, MM-00, SS-00, то дни остаются и в графе НН - часы умножаются на количество дней, и получается - DD-01, HH-48. Как это исправить? Благодарю?

          • А у вас массив r корректными значениями при этом заполняется или нет? Можете сказать что в нем после того как вы введете время

            • Да, масив r заполняется конкретными числами, и после запуска цикла кнопкой D, отсчет идет. Но если я использую только часы без дней, то процес происходит нормально. Если же ввожу данные в днях, к примеру DD-11 HH-00, то после запуска эквивалент точно такого же времени, но только в часах отображается и в часах - DD-11 и HH-264(24*11=264). А должно было бы быть - DD-10 HH-24 при отсчете. То есть программа дублирует дни в часах, чего не должно быть.
              Вот моя поблема при моем незнании как это исправить...

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

            • Огромное спасибо за подсказки. Решил проблему.

              От админа: хорошо, и вам успехов в дальнейших самоделках

  2. А почему не поставить ЖК дисплей на 4-ре вывода? Или как альтернативный вариант на TM1637.

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

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