ЭЛЕКТРОНИКА Очередной кухонный таймер

pi1985

★✩✩✩✩✩✩
2 Ноя 2018
21
15
Хочу поделиться ещё одним своим проектом - кухонным таймером.
В интернете довольно много такого рода проектов, но для себя я решил, что он должен быть не на ардуино, а на Atmega8, для установки времени должен быть энкодер, для отображения времени четырёхцифирный семисегментный индикатор и для автономности литиевый аккумулятор 18650.

В общем, устройство делает только обратный отсчёт от установленного времени. Можно установить время от 1 до 99 минут. По окончании обратного отсчёта звучит звонок и мигает индикатор.

Как это работает?
1. Включаем. Устройство ожидает установки времени для обратного отсчёта. Время можно выбрать с точностью до 10 секунд. Установили, нажали на энкодер.
2. Устройство отсчитывает по секунде, уменьшая время на индикаторе. Здесь можно нажать на энкодер и отстёт приостановится. Сейчас можно покрутить ручку и увеличить /уменьшить время. Нажали на энкодер ещё раз - продолжаем считать.
3. Как только досчитали до нуля, включается мигалка и пищалка и на индикаторе отображается начальное время. Через минуту таймер снова перейдёт к установке времени. То же самое произойдёт при нажатии на энкодер.

Устройство прибора.
Устройство основано на МК ATMega8A в корпусе QFN. Решил купить именно такие, так как с ними устройство получается наиболее компактным. Для программирования используется интерфейс ICSP, на всякий случай так же развёл и выводы RX/TX, но так и не использовал их. Все необходимые резисторы развёл в SMD варианте размера 0805.
Для вывода чисел используется четырёхцифирный семисегментный индикатор. Покупал целую кучу таких на AliExpress, но без контроллера. В последствии для них развёл плату контроллера на двух сдвиговых регистрах с возможностью соединения в цепочку.
Для установки времени используется китайский энкодер.
Для подачи звукового сигнала имеется выход на пищалку.
Так же имеется светодиод, который первоначально планировался для индикации разряда батареи, но после заказ плат заметил, что МК не имеет возможности контролировать напряжение батареи, так что пока он никак не используется.
Так же уже после приезда плат заметил, что неправильно развёл обвязку кнопки энкодера и не подтянул RESET к питанию. Два проводка и резистор на 10 кОм исправляют эти недостатки (На фото ниже это видно).

На данной схеме вышеперечисленные недостатки справлены.
kitchen.png

Схема контроллера индикатора (стандартная, вдруг кому нужна).
4dig7seg.png

Как устроена прошивка.
Мой любимый способ конструирования прошивки, это метод конечного автомата. У устройства есть несколько различных состояний.У каждого состояния есть действие по умолчанию и свои реакции на органы управления. Некоторые события приводят к переходу из одного состояния в другое. Действие по умолчанию - это действие, выполняемое по таймеру. В моём случае таймер установлен на 1 мс. Но таймер состояния срабатывает раз в 1 с.

У нас имеется три состояния устройства: настройка, отсчёт и сигнализация.
После включения попадаем в состояние настройка. У него нет действия по умолчанию, есть только реакции на события энкодера. Вращение ручки изменяет время, а нажатие на энкодер приводит к смене состояния в отсчёт.

В состоянии отсчёт есть действие по умолчанию - уменьшение времени на 1 секунду. Есть так же реакции на энкодер. Нажатие включает/выключает паузу, вращение в паузе изменяет время. А переход в состояние сигнализация происходит если досчитали до нуля.

В состоянии сигнализация действие по умолчанию переключает флаг включения дисплея создавая эффект мигания. Нажатие на энкодер приводит к перехоту в состояние настройка.

Аналогично происходит обработка энкодера. У каждого из его выводов есть несколько состояний:
C++:
enum BtnState{
  BTN_LOW,                  // Кнопка отпущена
  BTN_HIGH,                 // Кнопка нажата
  BTN_CHANGING_HIGH,        // Кнопка нажимается, защита от дребезга (первый цикл таймера)
  BTN_CHANGING_HIGH2,       // Кнопка нажимается, защита от дребезга (второй цикл таймера)
  BTN_CHANGING_LOW,         // Кнопка отпускается
};
Все выходы подтянуты к нулю. Соответственно начальное состояние каждого из них - BTN_LOW. Если на каком-либо из них замечается высокий сигнал, то вывод переходит в состояние сначала BTN_CHANGING_HIGH, затем в BTN_CHANGING_HIGH2 и далее в BTN_HIGH. Если в процессе перехода по этой цепочке состояний на выходе установится низкий уровень, то состояние снова станет BTN_LOW. Таким образом отрабатывает защита от дребезга. При переходе BTN_CHANGING_HIGH2 -> BTN_HIGH происходит событие нажатия кнопки или поворота энкодера в ту или иную сторону.
Здесь
C++:
btnCurState = PIND & (1 << 4);
это чтение состояния пина D4 и делает то же самое, что и функция digitalRead.
C++:
void processButton(){
  btnCurState = PIND & (1 << 4);
  if(btnCurState > 0) btnCurState = BTN_HIGH;
  else btnCurState = BTN_LOW;

  switch(btnState){
    case BTN_LOW:
      if(btnCurState == BTN_HIGH){
        btnState = BTN_CHANGING_HIGH;
      }
      break;
    
    case BTN_HIGH:
      if(btnCurState == BTN_LOW){
        btnState = BTN_CHANGING_LOW;
      }
      break;
    
    case BTN_CHANGING_HIGH:
      if(btnCurState == BTN_HIGH){
        btnState = BTN_CHANGING_HIGH2;
      }
      break;
    
    case BTN_CHANGING_HIGH2:
      if(btnCurState == BTN_HIGH){
        btnState = BTN_HIGH;
        //Тут вызвать обработчик нажатия
        encoderPress();
      }
      break;
    
    case BTN_CHANGING_LOW:
      btnState = BTN_LOW;
      //Тут вызвать обработчик отпускания
      break;
    
    default:
      btnState = BTN_LOW;
      break;
  }
}

Таймер без корпуса
IMG_3343.JPG

IMG_3344.JPG

IMG_3345.JPG

IMG_3346.JPG

Ну и видео как это всё работает.

Добавлено 27.12.2018:
Скачать прошивку.
Так же понадобится библиотека для работы с таймером MsTimer2.
 
Последнее редактирование:
  • Лойс +1
Реакции: Wan-Derer

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
1,491
319
Москва
wan-derer.ru
@pi1985, любишь ты вести дорожки в опасной близости друг к другу и к пятакам. Понятно что плата заводская, с маской и всё такое. Но здесь можно и не мельчить, места-то полно!
 

pi1985

★✩✩✩✩✩✩
2 Ноя 2018
21
15
Ну я учусь ещё. Я всего-то плат десяток развёл только. А эту я хочу переразвести, чтобы индикатор на той же плате был. Чтобы с проводами не париться. Хотя их у меня ещё 9 штук есть, так что не к спеху.
 

pi1985

★✩✩✩✩✩✩
2 Ноя 2018
21
15
Не могли бы вы поделиться скетчем?
Конечно, добавил ссылку в конец первого поста.

Там пока не выложен код работы с динамиком. Так как сами динамики пока ещё едут из Китая, то код я пока не отладил.