Помидорный таймер на Arduino

27 января 2023


Всем привет! Для рационального распределения времени была придумана техника помидорного таймера. Её суть состоит в том, чтобы определить задачи для выполнения, расставить приоритеты, после чего установить таймер 25 минут на одну задачу. Во время работы таймера выполнять задачу, не отвлекаясь на посторонние факторы. После окончания таймера сделать пяти минутный перерыв. После отдыха взяться за следующую задачу.

Чтобы сделать метод удобнее, попробуем создать DIY - фиджет (физический виджет), который бы позволил не отвлекаться на переключение вкладок в браузере или использование дополнительных приложений.

Для этого проекта нам понабиться следующая электроника:

Подключаем компоненты по схеме:

Для сборки прототипа я использовал макетную плату:

Перейдем к написанию скетча:

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

Для управления дисплеем, чтения показаний с кнопки, создания таймеров я использую библиотеки:

#include "GyverButton.h"
#include 
#include 

Объявим некоторые константы для пинов и параметров:

#define WORK_TIME 25  //Время работы в минутах
#define RELAX_TIME 5  //Время отдыха в минутах

#define MOTOR_PIN 5   //Пин вибро-двигателя
#define BTN_PIN 3     //Пин кнопки
#define LIGHT_PIN 7   //Пин свеиодиода

#define MOTOR_FORCE 240 //Сила вращения мотора
#define MOTOR_BEEP 1  //Количество повторений сигнала

int page = 0;
//переменные таймеров
uint32_t tam_w; 
uint32_t tam_r;

Инициализируем объекты:

GyverOLED oled; //дисплей
GButton ok(BTN_PIN, HIGH_PULL); //кнопка
TimerMs tmr_w(WORK_TIME * 60000, 0, 1);  //рабочий таймер
TimerMs tmr_r(RELAX_TIME * 60000, 0, 1); //таймер отдыха

Начальная настройка:

void setup() {
  oled.init(); //инициализация дисплея
  pinMode(MOTOR_PIN, OUTPUT); //выход мотора
  pinMode(LIGHT_PIN, OUTPUT); //выход светодиода
  analogWrite(MOTOR_PIN, 0);
  digitalWrite(LIGHT_PIN, LOW);
  ok.setClickTimeout(100);
  Wire.setClock(800000L); //Настройка частоты обновления дисплея
  oled.clear();
  oled.home();
  oled.setScale(3);
  oled.autoPrintln(true);
  oled.print("ТЕХНИКАПОМИДОРА");
  oled.update();
  delay(3 * 1000);
}

Цикл:

void loop() {
  ok.tick(); //проверяем состояние кнопки
  //проверяем таймеры
  tmr_w.tick();
  tmr_r.tick();

  oled.setScale(2);
  oled.clear();
  oled.home();

  switch (page) {
    case 0: //Стартовое меню
      oled.print("Нажми на  кнопку дляотсчета!");
      if (ok.isClick()) {
        tmr_w.start(); //Если кнопка нажата запускаем таймер
        page = 1;
      }
      break;

    case 1: //Меню рабочего таймера
      pause(); //проверка на остановку таймера
      if (tmr_w.elapsed()) { //Если время истекло запускаем 2й таймер
        sos(); //Сигнал
        tmr_r.start();
        page = 2; //переходим в меню отдыха
      }

      oled.setCursor(25, 0);
      oled.print("Работа");
      oled.setScale(3);
      oled.setCursor(0, 1 * 2);
      oled.print(tmr_w.timeLeft() / 1000); //Сколько осталось времени
      break;

    case 2: //меню отдыха
      pause(); //проверка на остановку таймера
      oled.setCursor(25, 0 * 2);
      oled.print("Отдых");
      oled.setScale(3);
      oled.setCursor(0, 1 * 2);
      oled.print(tmr_r.timeLeft() / 1000); //Сколько осталось времени

      if (tmr_r.elapsed()) { //если время вышло запускаем 1й таймер
        sos();
        tmr_w.start();
        page = 1;
      }
      break;
  }
  oled.update(); //обновление дисплея
}

Я добавил функцию паузы, чтобы можно было приостановить таймер:

void pause() {
  if (ok.isClick()) { //если кнопка нажата
    if (tmr_w.active()) { //и таймер работы активен
      tam_w = tmr_w.timeLeft();
      tmr_w.stop(); //остановить таймер
    } else {
      tmr_w.setTime(tam_w); 
      tmr_w.start(); //заново запустить
    }

    if (tmr_r.active()) { //если таймер отдыха активен
      tam_r = tmr_r.timeLeft();
      tmr_r.stop(); //остановить таймер
    } else {
      tmr_r.setTime(tam_r);
      tmr_r.start(); //заново запустить
    }
  }
}

И функция сигнализации при окончании времени:

void sos() {
  oled.home();
  oled.clear();
  oled.print("SOS");
  for (int i = 0; i < MOTOR_BEEP; i++) {
    analogWrite(MOTOR_PIN, MOTOR_FORCE); //Запускаем мотор
    digitalWrite(LIGHT_PIN, HIGH); //Включаем светодиод
    delay(1 * 1000);
    analogWrite(MOTOR_PIN, 0); //Останавливаем мотор
    digitalWrite(LIGHT_PIN, LOW); //Выключаем светодиод

    delay(1 * 1000);
  }
}

Загружаем...

Демонстрация работы представлена на видео:

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

Спасибо за внимание и удачи в ваших проектах!


Данная статья является собственностью Amperkot.ru. При перепечатке данного материала активная ссылка на первоисточник, не закрытая для индексации поисковыми системами, обязательна.


Поделиться: