Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 63 additions & 47 deletions Chess_clock/Chess_clock.ino
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#include <GyverTM1637.h>
#include <GyverButton.h>

/*
Шахматные часы для контроля рабочего времени
Два потока времени - обратный отсчет рабочего времени и прямой счет перерывов
Expand Down Expand Up @@ -29,35 +26,38 @@
#define IDLE_ALERT_PERIOD 5 // Период оповещений в минутах
/*-----------------------------------------------------------------------------------------------*/

#include <GyverButton.h>
GButton big(BIG_BTN, HIGH_PULL);
GButton left(LEFT_BTN, HIGH_PULL);
GButton right(RIGHT_BTN, HIGH_PULL);

#include <GyverTM1637.h>
GyverTM1637 disp(CLK, DIO);

int8_t hours_need = 0; // Ввод часов
int8_t hours_left = 0; // Часы на обратный отсчет
int8_t hours_idle = 0; // Часы безделья
int8_t minutes_need = 0; // Ввод минут
int8_t minutes_left = 0; // Минуты на обратный отсчет
int8_t minutes_idle = 0; // Минуты безделья
int8_t hours_need; // Ввод часов
int8_t hours_left; // Часы на обратный отсчет
int8_t hours_idle; // Часы безделья
int8_t minutes_need; // Ввод минут
int8_t minutes_left; // Минуты на обратный отсчет
int8_t minutes_idle; // Минуты безделья

#if (CHECK_PERIOD_RAND == true)
uint32_t checkPeriod = random(CHECK_PERIOD_MIN * 60000UL, CHECK_PERIOD_MAX * 60000UL); // Если рандом период - получаем этот случайный период
#if CHECK_PERIOD_RAND
uint32_t checkPeriod = random(CHECK_PERIOD_MIN * 60000UL, CHECK_PERIOD_MAX * 60000UL); // Если рандом период - получаем этот случайный период
#else
uint32_t checkPeriod = CHECK_PERIOD * 60000UL; // А если постоянный - просто взять из константы
uint32_t checkPeriod = CHECK_PERIOD * 60000UL; // А если постоянный - просто взять из константы
#endif


void setup() {
disp.clear(); // Очистить дисп
disp.brightness(7); // Макс яркость (0-7)
disp.point(0); // Выкл точки
disp.clear(); // Очистить дисп
disp.brightness(7); // Макс яркость (0-7)
disp.point(0); // Выкл точки

big.setTimeout(1500); // Таймаут длительного удержания красной кнопки
left.setStepTimeout(120); // Таймаут инкремента при удержании других кнопок
big.setTimeout(1500); // Таймаут длительного удержания красной кнопки
left.setStepTimeout(120); // Таймаут инкремента при удержании других кнопок
right.setStepTimeout(120);

pinMode(BUZZER_PIN, OUTPUT); // Пин баззера как выход
pinMode(BUZZER_PIN, OUTPUT); // Пин баззера как выход
}

void loop() {
Expand Down Expand Up @@ -110,12 +110,15 @@ void loop() {
disp.displayClock(hours_need, minutes_need); // вывод вводимых часов/минут
}


void workCycle(void) { // цикл отсчета рабочего времени
static uint32_t minsTimer = 0;
static uint32_t checkTimer = 0;
static bool checkFlag = false;
static bool buzzerEnable = false; // переменные и флаги
#if CHECK_ENABLE
static uint32_t checkTimer = 0;
#endif
#if IDLE_ALERT
bool buzzerEnable = false; // переменные и флаги
#endif

hours_idle = 0; // передаем нужные значения и обнуляем перерывы
minutes_idle = 0;
Expand All @@ -126,10 +129,12 @@ void workCycle(void) { // цикл отсчета рабочего
disp.point(1); // вкл точку

minsTimer = millis();
checkTimer = millis(); // обновляем таймеры
#if CHECK_ENABLE
checkTimer = millis(); // обновляем таймеры
#endif

while (true) { // бесконечный цикл
big.tick(); // опрос кнопки
for (;;) { // бесконечный цикл
big.tick(); // опрос кнопки

if (big.isClick()) { // короткое нажатие
if (checkFlag) { // Если флаг установлен
Expand All @@ -144,7 +149,7 @@ void workCycle(void) { // цикл отсчета рабочего
return;
}

if (millis() - minsTimer >= 60000) { // минутный таймер
if (millis() - minsTimer >= 60000) { // минутный таймер
minsTimer = millis();
if (--minutes_left < 0) { // уменьшаем минуты и сравниваем, меньше нуля - идем дальше
if (hours_left-- > 0) { // Уменьшаем еще и часы и сравниваем, больше нуля - идем дальше
Expand All @@ -171,53 +176,64 @@ void workCycle(void) { // цикл отсчета рабочего
}
}

#if (CHECK_ENABLE == true) // Если проверка включена
#if CHECK_ENABLE // Если проверка включена
if (millis() - checkTimer >= checkPeriod) { // Таймер опроса
checkTimer = millis();
checkFlag = true;
buzzerEnable = true;
#if (CHECK_PERIOD_RAND == true)
#if IDLE_ALERT
buzzerEnable = true;
#endif
#if CHECK_PERIOD_RAND
checkPeriod = random(CHECK_PERIOD_MIN * 60000UL, CHECK_PERIOD_MAX * 60000UL); // получение случайного периода
#endif
#endif
tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR); // Подать первый сигнал
}

if (buzzerEnable and millis() - checkTimer >= BUZZER_DUR * 2UL) { // После окончания подать еще один сигнал по таймеру
#if IDLE_ALERT
buzzerEnable = false;
if (buzzerEnable and millis() - checkTimer >= BUZZER_DUR * 2UL) { // После окончания подать еще один сигнал по таймеру
#else
if (millis() - checkTimer >= BUZZER_DUR * 2UL) { // После окончания подать еще один сигнал по таймеру
#endif
tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR);
buzzerEnable = false; // Выкл баззер
// Выкл баззер
}

if (checkFlag and millis() - checkTimer >= CHECK_TIMEOUT * 1000UL) { // Таймаут нажатия на кнопку
if (checkFlag and millis() - checkTimer >= CHECK_TIMEOUT * 1000UL) { // Таймаут нажатия на кнопку
checkFlag = false;
idleCycle(); // автоматом идем в режим безделья
idleCycle(); // автоматом идем в режим безделья
}
#endif
#endif // CHECK_ENABLE


disp.displayClock(hours_left, minutes_left); // Вывод часов и минут обратного отсчета
disp.displayClock(hours_left, minutes_left); // Вывод часов и минут обратного отсчета
}
}

void idleCycle(void) {
static uint32_t pointTimer = 0;
static uint32_t minsTimer = 0;
static uint32_t alertTimer = 0;
static bool pointState = false;
static bool buzzerEnable = false; // переменные

disp.point(0); // выкл точку
disp.displayByte(_1, _d, _L, _E); // вывод надписи
tone(BUZZER_PIN, BUZZER_TONE); // подача сигнала
#if IDLE_ALERT
static uint32_t alertTimer = 0;
static bool buzzerEnable = false;
#endif

disp.point(0); // выкл точку
disp.displayByte(_1, _d, _L, _E); // вывод надписи
tone(BUZZER_PIN, BUZZER_TONE); // подача сигнала
delay(BUZZER_DUR);
noTone(BUZZER_PIN);
delay(BUZZER_DUR);

pointTimer = millis(); // апдейт таймеров
pointTimer = millis(); // апдейт таймеров
minsTimer = millis();
alertTimer = millis();
#if IDLE_ALERT
alertTimer = millis();
#endif

while (true) { // бесконечный цикл
big.tick(); // опрос кнопки
for(;;) { // бесконечный цикл
big.tick(); // опрос кнопки

if (big.isClick()) { // нажатие на кнопку
tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR); // подать сигнал
Expand All @@ -239,7 +255,7 @@ void idleCycle(void) {
disp.point(pointState);
}

#if (IDLE_ALERT == true) // если включено напоминание о длительном безделье
#if IDLE_ALERT // если включено напоминание о длительном безделье
if (millis() - alertTimer >= IDLE_ALERT_PERIOD * 60000UL) { // таймер опроса безделья
alertTimer = millis();
buzzerEnable = true;
Expand All @@ -250,7 +266,7 @@ void idleCycle(void) {
tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR); // Подача второго сигнала
buzzerEnable = false;
}
#endif
#endif

disp.displayClock(hours_idle, minutes_idle); // вывод часов и минут безделья в реальном времени
}
Expand Down