#define CLK 36 // VP
#define DT 34
#define SW 35
#define OTMENA 10 // время ожидания отмены
#define PISK 5 // время после которого привлекаем внимание писком
#define OFF 15 // время до выключения индикатора (время ожидания отмены + время до выключения индикатора)
#define T_HISTORY 5 // время выхода из режима истории по бездействию
#include <Wire.h>
#include "GyverEncoder.h"
//#include <microDS3231.h>
//MicroDS3231 rtc;
//Encoder enc1(CLK, DT); // для работы без кнопки
Encoder enc1(CLK, DT, SW); // для работы c кнопкой
//Encoder enc1(CLK, DT, SW, TYPE2); // для работы c кнопкой и сразу выбираем тип
//Encoder enc1(CLK, DT, ENC_NO_BUTTON, TYPE2); // для работы без кнопки и сразу выбираем тип
// Варианты инициализации:
// Encoder enc; // не привязан к пину
// Encoder enc(пин CLK, пин DT); // энкодер без кнопки (ускоренный опрос)
// Encoder enc(пин CLK, пин DT, пин SW); // энкодер с кнопкой
// Encoder enc(пин CLK, пин DT, пин SW, тип); // энкодер с кнопкой и указанием типа
// Encoder enc(пин CLK, пин DT, ENC_NO_BUTTON, тип); // энкодер без кнопкой и с указанием типа
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
#include "RTClib.h"
RTC_DS1307 rtc;
bool fl_rabota=0; //флаг работающего двигателя
bool fl_chenge_rabota = 0; //флаг изменения состояния двигателя
bool fl_t_start=0; //флаг зафиксированного времени старта
bool fl_first_rec=1; //флаг работы с первой записью
bool key_flag = false; //флаг прошлого состояния зажигания
bool fl_bt_holed = false; //флаг удержания кнопки
bool fl_new_minute=false; //флаг новой минуты
bool fl_new_second=false; //флаг новой секунды
bool fl_new_hour = false; //флаг нового часа
bool fl_disp_clock = true; //флаг необходимости отображать текущее время
bool fl_start_clock_disp = true; //флаг необходимости начального вывода всего времени на дисплэй
bool old_key_flag=false; // флаг для отслеживания состояния замка зажигания
bool fl_old_rabota=false; // флаг предидущего состояния работы
bool fl_mig_indik=false; // флаг необходимости мигать индикатором
bool fl_status=false; // флаг показывающий отображаются ли символы при мигании
bool fl_bt_press=false; // флаг нажатия на кнопку
bool fl_backlight=false; // флаг работающей подсветки дисплея
bool fl_otloz=false; // флаг отсрочки события старт стоп
bool fl_top_string=true; // флаг вывода информации на верхнюю строку дисплея
bool fl_end_rec=false; // флаг финализации текущей записи
bool fl_history=false; // флаг работы с историей
bool fl_lcd_history=false; // флаг обновления экрана с историей
bool fl_menu=false; // флаг работы с меню
uint8_t isrunning(void); // Для DS1307
// Для DS3231 bool lostPower(void)
// Для PCF8523 boolean initialized(void)
byte hour, minute, seconds; // время расчитанное МК
byte work_hh, work_mm; // время события старт/стоп
byte count=0; // Номер элемента в массиве
byte count_history=0; // Номер элемента для истории
byte t_history=0; // таймер нахождения в режиме истории
byte count_ctasic_key=0; // количество совпадений состояния замка зажигания
byte count_mig=0; // количество миганий
byte count_off=0; // прошло секунд до выключения дислея
uint32_t seconds_Timer = 0; // таймер отсчета секунды для часов
uint32_t zaderzka = 0; // таймер задержки фиксации момента старта/стопа
struct time { // создаём ярлык структуры time
bool fl_start_set = 0;
bool fl_stop_set = 0;
byte count = 0;
byte start_hh;
byte start_mm;
byte stop_hh;
byte stop_mm;
};
time time_set[20]; // создаём массив структур время выезда доезда
void f_get_time(byte& hour, byte& minute, byte& seconds); // объявляем функцию получения времени из RTS
void f_printDigits(int digits); // функция добавления "0" перед единичным числом
void f_clock(byte& hour, byte& minute, byte& seconds); // функция счета текущего времени
void f_print_time_work(bool fl_rabota); // функция вывода на дисплей времени старта стопа
void f_set_time_arrey(bool fl_rabota, bool& fl_t_start, bool& fl_end_rec, byte& count);
void f_print_clock(bool& fl_new_hour, bool& fl_new_minute, bool& fl_start_clock_disp); // функция отображения времени на дисплее
void f_control_zamka (bool& old_key_flag, bool& fl_rabota, bool& fl_chenge_rabota, byte& count_ctasic_key); // функция контроля изменения замка зажигания
void f_print_time_start(byte count); //функция фывода на экран времени старта
void f_print_time_stop(); //функция фывода на экран времени стопа
void f_migalka(bool fl_rabota, bool& fl_status, bool& fl_mig_indik, byte& count_mig); // функция мигания соответствующим индикатором
void f_next_rec (bool& fl_first_rec, byte& count); // функция подготовки работы со следующей записью
void f_work_time(byte& work_hh, byte& work_mm); // функция запоминания рабочего времени
void f_print_string (bool fl_top_string, byte count); // функция вывода на дисплей строки верхней или нижней
bool f_reid_fl_start_stop (bool read_fl_start, byte count); // функция получающее значение флага старта или стопа из массива структур
void f_work_change (bool fl_rabota, bool fl_t_start, bool& fl_mig_indik, bool& fl_backlight, bool fl_end_rec); // функция обработки изменения замка зажигания
void f_lcd_pausa(bool start); // функция вывода на дисплей сообщения о запущенной паузе
void f_button_press(bool fl_rabota, bool& fl_otloz, bool& fl_mig_indik);
void f_lcd_menu (); // ф-я отображения меню на экране // Новая функция обработки нажатия кнопки
void setup() {
Serial.begin(9600);
pinMode(12, INPUT_PULLUP);
rtc.begin();
enc1.setType(TYPE2);
lcd.init(); // initialize the lcd
lcd.setBacklight(true);
lcd.home();
if (! rtc.isrunning()) {
lcd.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(__DATE__, __TIME__));
}
else {
lcd.println("RTC is running!");
lcd.setCursor(0,1) ;
lcd.println(" Starting");
delay(1000);
}
lcd.clear();
lcd.setBacklight(false);
f_get_time(hour, minute, seconds);
seconds_Timer = (millis()/1000);
}
void loop() {
enc1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
lcd.setBacklight (fl_backlight); // управляем подсветкой
//if (enc1.isPress()) { // было нажатие на кнопки (+ дебаунс)
//Serial.println("Pess");
if (enc1.isClick()) { // кнопку отпустили
//Serial.println("Click");
fl_bt_press=true; // фиксируем короткое нажатие
} // end кнопку отпустили
if (enc1.isHolded()) { // кнопку удержали
//Serial.println("Holded");
fl_bt_holed=true; // фиксируем удержание
} // end кнопку удержали
//} // end было нажатие на кнопки
//
if (millis() - (seconds_Timer * 1000) > 1000) { // если прошла секунда
f_control_zamka (old_key_flag, fl_rabota, fl_chenge_rabota, count_ctasic_key);
seconds_Timer = millis()/1000;
f_clock(hour, minute, seconds); // функция счета текущего времени
if (fl_disp_clock) f_print_clock(fl_new_hour, fl_new_minute, fl_start_clock_disp); // отображаем время на дисплее
if (fl_mig_indik) { // организуем мигание соответствующего раздяда
f_migalka(fl_rabota, fl_status, fl_mig_indik, count_mig);
} // end организуем мигание соответствующего раздяда
//Serial.print("fl_end_rec ");
//Serial.println(fl_end_rec);
if (fl_backlight) { // если подсветка еще не выключена
//Serial.print(" fl_backlight ");
//Serial.println(fl_backlight);
if (count_off < OFF) {
count_off++;
//Serial.print("count_off__ ");
//Serial.print(count_off);
}
else {
//Serial.println("else ");
count_off =0;
fl_backlight=false;
//lcd.setBacklight(false);
}
} //end если режим работы стоп
/*
Serial.print(" Mizalka=");
Serial.print(fl_mig_indik);
Serial.print(" First rec=");
Serial.println(fl_first_rec);
*/
//------ обработка задержки в режиме история
if (fl_history) { // если экран в режиме истории
if (t_history < T_HISTORY) t_history++; // если время не вышло продолжаем счет
else {
Serial.println(" else ");
lcd.clear();
fl_start_clock_disp=true;
fl_new_minute=true;
fl_new_hour=true;
fl_history=false;
fl_disp_clock=true;
if (fl_otloz) { // если была пауза
Serial.println(" pauza ");
f_lcd_pausa(fl_t_start); // функция вывода на дисплей сообщения о запущенной паузе
} // end если была пауза
else { // паузы небыло
fl_top_string=true;
f_print_clock(fl_new_hour, fl_new_minute, fl_start_clock_disp); // отображаем время на дисплее
f_print_string (fl_top_string, count); // функция вывода на дисплей верхней строки
} // end паузы небыло
} // end время вышло выходим их режима истории
} // end если экран в режиме истории
//------ end обработка задержки в режиме история
} // end если прошла секунда
if (fl_bt_press) { // если было нажатие кнопки
fl_bt_press = false; // сбрасываем нажатие
fl_backlight=true; // включаем подсветку дисплея
count_mig=0; // любое нажатие кнопки обнуляет задержку принятия решения
count_off=0; // обнуляем секунды до выключения дислея
f_button_press(fl_rabota, fl_otloz, fl_mig_indik); // обрабатываем нажатие
} // end если было нажатие кнопки
//-------- обрабатываем изменениен состояния замка зажигания
if (fl_chenge_rabota) { // если было изменение в режиме работы
if (fl_rabota) { // если было включение зажигания
fl_new_hour=1; fl_new_minute=1; fl_start_clock_disp=1; // выводим в нижнюю строку часы
lcd.clear(); // очищаем дисплей
} // end если было включение зажигания
f_work_change (fl_rabota, fl_t_start, fl_mig_indik, fl_backlight, fl_end_rec); // фунуция обработки смены состояния замка
fl_chenge_rabota = false; // сбрасываем флаг изменения режима работы
fl_otloz=false; // любое изменение отменяет паузу в режимах старт / стоп
f_work_time(work_hh, work_mm); // получаем время
work_hh = minute; //!!! исправить = hour
work_mm = seconds; //!!! исправить = minute
} // end если было изменение в режиме работы
//-------- end обрабатываем изменениен состояния замка зажигания
//-------- работа с меню истории
if (fl_history) {
//count_history=count;
if (fl_lcd_history) { // если нужно вывести на экран
lcd.clear();
if (count > 0) { // если запись не единственная
f_print_string (true, count_history-1); // выводим верхнюю строку
f_print_string (false, count_history); // выводим нижнюю строку
} // end если запись не единственная
else { // а когда единственная
if (fl_end_rec) {
f_print_string (true, count_history); // выводим только верхнюю строку
}
} // end а когда единственная
fl_lcd_history=false; // сбрасываем флаг необходимости вывода на экран
} // end если нужно вывести на экран
}
//-------- end работа с меню истории
// функция обработки поворота энкодера
if (enc1.isTurn() && (!fl_menu)) { // если был совершён поворот (индикатор поворота в любую сторону) не в режиме меню
t_history=0; // дюбой поворот энкодера продляет режим истории
fl_backlight=true; // включаем подсветку дисплея
count_off=0; // обнуляем секунды до выключения дислея
if (!fl_history) { // если еще не режим истории
count_history=count; // получаем кол-во записей для режима истории
fl_disp_clock=false; // убираем вывод часов на экран
fl_history=true; // переходим в режим истории
} // end если еще не режим истории
/*
lcd.clear(); // очищаем экран
if (count == 0) { // если запись единственная
fl_top_string=true; // выводим на экран верхнюю строку
f_print_string (fl_top_string, count); // функция вывода на дисплей верхней строки
lcd.setCursor(0, 6);
lcd.print("NO HISTORY");
Serial.println("NO HISTORY");
} // end если запись единственная
*/
else { // запись не единственная
if (enc1.isRight()) { // если был поворот вправо
if (count_history > 1) { // если отображаемая запись не первая
count_history--; // сдвигаем экран на одну запись вверх
} // если отображаемая запись не первая
} // end если был поворот вправо
if (enc1.isLeft()) { // усли был поворот влево
if (count > count_history) { // если выводимая на экран запись не последняя
count_history++; // сдвигаем экран на одну запись вниз
} // end если выводимая на экран запись не последняя
} // end если был поворот влево
} // end запись не единственная
fl_top_string=true; // выводим на экран верхнюю строку
if (count_history>0) { // если запись не единственная
f_print_string (fl_top_string, count_history-1); // функция вывода на дисплей верхней строки
fl_top_string=false; // выводим на экран нижнюю строку
f_print_string (fl_top_string, count_history); // функция вывода на дисплей нижней строки
} // end если запись не единственная
else { // запись единственная
fl_top_string=true; // выводим на экран верхнюю строку
f_print_string (fl_top_string, count); // функция вывода на дисплей верхней строки
lcd.setCursor(0,6);
lcd.print(" ");
lcd.setCursor(0,6);
lcd.print("NO HISTORY");
Serial.println("no HISTORY");
} // end запись единственная
} // end если был совершён поворот (индикатор поворота в любую сторону) не в режиме меню
if (enc1.isTurn() && (!fl_menu)) { // если был совершён поворот (индикатор поворота в любую сторону) в режиме меню
f_lcd_menu ();
} // end если был совершён поворот (индикатор поворота в любую сторону) в режиме меню
// end функция обработки поворота энкодера
// функция удержания кнопки
if (fl_bt_holed) { // если была удержана и энк не поворачивался
fl_bt_holed=false;
fl_backlight=true; // включаем подсветку дисплея
count_off=0; // обнуляем секунды до выключения дислея
fl_menu=true; // переходим в режим меню
fl_disp_clock=false; // убираем вывод часов на экран
} // end если была удержана и энк не поворачивался
// end функция удержания кнопки
// работа с меню
if (fl_menu) f_lcd_menu (); // если установлен флаг меню, работаем с меню
// end работа с меню
} // end loop
void f_get_time(byte& hour, byte& minute, byte& seconds) { // функция получения времени из RTS
DateTime now = rtc.now();
hour=now.hour();
minute=now.minute();
seconds=now.second();
} // end функция получения времени из RTS
void f_printDigits(int digits) { // функция добавления "0" перед единичным числом
// utility function for digital clock display: prints preceding colon and leading 0
if(digits < 10){
lcd.print('0');
}
lcd.print(digits);
} // end функция добавления "0" перед единичным числом
void f_clock(byte& hour, byte& minute, byte& seconds) { // функция хода часов
fl_new_second = true;
if (seconds < 59) seconds++;
else {
fl_new_minute = true;
seconds = 0;
if (minute < 59) minute++;
else {
minute = 0;
fl_new_hour = true;
if (hour < 23) hour++;
else hour=0;
}
}
}
void f_print_time_work(bool fl_rabota) { // функция вывода на дисплей времени старта стопа
if (fl_rabota) { // если это старт
f_print_time_start(count);
} // end если это старт
else { // если это был стоп
f_print_time_stop();
} // end если это был стоп
} // end функция вывода на дисплей времени старта стопа
void f_set_time_arrey(bool fl_rabota, bool& fl_t_start, bool& fl_end_rec, byte& count) { // функция сохранения времени старт/стоп в ячейку массива структур
if (!fl_t_start) { // если небыло старта
time_set[count].start_hh = work_hh; // тут исправить work_hh фиксируем время в ячейку массива
time_set[count].start_mm = work_mm; // тут исправить work_mm
time_set[count].fl_start_set = true;
fl_t_start=true;
fl_end_rec=false;
} // end если небыло старта
else { // если старт был
time_set[count].stop_hh = work_hh; // тут исправить work_hh фиксируем время в ячейку массива
time_set[count].stop_mm = work_mm; // тут исправить work_mm
time_set[count].fl_stop_set = true;
fl_t_start=false;
fl_end_rec=true; // поднимаем флаг финализации текущей записи
} // end если старт был
Serial.print("time_set[count].fl_start_set=");
Serial.println(time_set[count].fl_start_set);
Serial.print("time_set[count].fl_stop_set=");
Serial.println(time_set[count].fl_stop_set);
if ((time_set[count].fl_start_set) && (time_set[count].fl_stop_set)) { // есть запись старта и стопа
count++; // переходим к следующей записи
} // end есть запись старта и стопа
} // end функция сохранения времени старт/стоп в ячейку массива структур
void f_print_clock(bool& fl_new_hour, bool& fl_new_minute, bool& fl_start_clock_disp) { // функция отображения времени на дисплее
if (fl_start_clock_disp) { // если это первый вывод на дисплей
lcd.setCursor(4, 1);
f_printDigits(hour); // выводим на дисплей полную информацию
lcd.setCursor(6, 1);
lcd.println(":");
lcd.setCursor(7, 1);
f_printDigits(minute);
lcd.setCursor(9, 1);
lcd.println(":");
lcd.setCursor(10, 1);
f_printDigits(seconds);
fl_start_clock_disp = false;
} //end если это первый вывод на дисплей
else { // если на дисплее уже отображается время
lcd.setCursor(10, 1);
f_printDigits(seconds);
if (fl_new_minute) {
lcd.setCursor(7, 1);
f_printDigits(minute);
fl_new_minute = false;
}
if (fl_new_hour) {
lcd.setCursor(4, 1);
f_printDigits(hour);
fl_new_hour = false;
}
} // end если на дисплее уже отображается время
} // end функция отображения времени на дисплее
void f_control_zamka (bool& old_key_flag, bool& fl_rabota, bool& fl_chenge_rabota, byte& count_ctasic_key) { // функция контроля изменения замка зажигания
key_flag = digitalRead(12); // читаем состояние замка зажигания
if (key_flag != old_key_flag) { // если состояние замка изменилось
old_key_flag = key_flag; // изменяем старое состояние замке на новое
count_ctasic_key=0; // сбрасываем количество совпадений замке после изменения
} // end если состояние замка изменилось
else { // состояние замка не изменилось
if (count_ctasic_key <2) { // если число совпадений недостаточно
count_ctasic_key++;
}
else { // число совпадений достаточно
fl_rabota = key_flag; // устанавливаем флаг состояния работы двигателя в соответствии с текущим состоянием замка
if (fl_rabota != fl_old_rabota) { // если режим работы двигателя изменился
fl_chenge_rabota = true; // устанавливаем флаг наличия изменения реботы
fl_old_rabota = fl_rabota; // изменяем установившийся режим работы
//fl_backlight= true; // поднимаем флаг включения подсветки
count_ctasic_key=0; // сбрасываем счетчик совпадений
} // end если режим работы двигателя изменился
} // end число совпадений достаточно
}
} // end функция контроля изменения замка зажигания
void f_print_time_start(byte count) {
lcd.setCursor(0, 0);
lcd.println(" ");
lcd.setCursor(0, 0);
f_printDigits(count +1); // здесть должна быть функция Старта
lcd.setCursor(3, 0);
f_printDigits(work_hh);
lcd.setCursor(5, 0);
lcd.println(":");
lcd.setCursor(6, 0);
f_printDigits(work_mm);
}
void f_print_time_stop() {
lcd.setCursor(11, 0);
f_printDigits(work_hh);
lcd.setCursor(13, 0);
lcd.println(":");
lcd.setCursor(14, 0);
f_printDigits(work_mm);
}
void f_migalka(bool fl_rabota, bool& fl_status, bool& fl_mig_indik, byte& count_mig) { // функция мигания соответствующим индикатором
if (fl_rabota) { // если зажигание включено
if (fl_status) { // если сегменты времени старта на дисплее отображаются
lcd.setCursor(0, 0); // курсор в начало строки
lcd.println(" "); // закрашиваем сегменты пробелами
} // end если сегменты времени старта на дисплее отображаются
else f_print_time_start(count); // если сегменты времени старта на дисплее не отображаются выводим туда время
} // end если зажигание включено
else { // если зажигание выключено
if (fl_status) { // если сегменты времени стопа на дисплее отображаются
lcd.setCursor(0, 0); // курсор в начало строки
lcd.println(" "); // закрашиваем сегменты порядкового номера пробелами
lcd.setCursor(11, 0);
lcd.println(" "); // закрашиваем сегменты времени стопа пробелами
} // end если сегменты времени стопа на дисплее отображаются
else { // если сегменты времени стопа на дисплее не отображаются
lcd.setCursor(0, 0); // курсор в начало строки
f_printDigits(count +1); // выводим порядковый номер
f_print_time_stop(); // выводим время стопа
} // end если сегменты времени стопа на дисплее не отображаются
} // end если зажигание вылючено
fl_status = !fl_status; // меняем состояния статуса вывода/гашения символов на дисплее
if (count_mig < OTMENA) { // если не превышено число миганий (время принятия решения)
count_mig++; // продолжаем минать и ждать
if (count_mig > PISK) ; // тут можно немного попищать
} // end если не превышено число миганий (время принятия решения)
else { // если превышено число миганий (время принятия решения вышло)
count_mig = 0; // обнуляем счетчик миганий
fl_mig_indik=false; // сбрасываем флаг необходимости мигать индикатором
//if (fl_first_rec) fl_first_rec=0; // если это первая запись, то пропускаем увеличение счетчика записей
//else f_next_rec (fl_first_rec, count); // готовим счетчик к новой записи
f_set_time_arrey(fl_rabota, fl_t_start, fl_end_rec, count); // сохраняем время в структуру
if (fl_rabota) f_print_time_start(count); // если зажигание включено выводим на индикатор время старта
else { // если зажигание выключено
f_print_string (true, count); // выводим на экран полную строку старта и стопа
} // end если зажигание выключено
} // end если превышено число миганий (время принятия решения вышло)
} //end функция мигания соответствующим индикатором
void f_next_rec (bool& fl_first_rec, byte& count) { // функция подготовки работы со следующей записью
//Serial.print( "count_next_old=");
//Serial.println(count);
if (0) { // если это первая запись fl_first_rec
fl_first_rec=false;
} // end если это первая запись
else { // запись не первая
//count++;
} // end запись не первая
// Serial.print( "count_next_new=");
// Serial.println(count);
//fl_t_start=false;
//fl_t_stop=false;
} // end функция подготовки работы со следующей записью
void f_work_time(byte& work_hh, byte& work_mm) { // функция запоминания рабочего времени
work_hh = minute;
work_mm = seconds;
} // end функция запоминания рабочего времени
void f_print_string (bool fl_top_string, byte count) { // функция вывода на дисплей строки верхней или нижней
//Serial.println( "f_print_string");
if (fl_top_string) { // если выводим верхнюю строку
lcd.setCursor(0, 0);
lcd.println(" ");
lcd.setCursor(0, 0);
//Serial.print("count ");
//Serial.println(count);
f_printDigits(count+1);
lcd.setCursor(3, 0);
lcd.print(" ");
if (f_reid_fl_start_stop (true, count)) { // если был и старт и стоп
//Serial.println( "start+stop");
lcd.setCursor(3, 0);
f_printDigits(time_set[count].start_hh);
lcd.setCursor(5, 0);
lcd.println(":");
lcd.setCursor(6, 0);
f_printDigits(time_set[count].start_mm);
lcd.setCursor(11, 0);
f_printDigits(time_set[count].stop_hh); // тут исправить work_hh
lcd.setCursor(13, 0);
lcd.println(":");
lcd.setCursor(14, 0);
f_printDigits(time_set[count].stop_mm); // тут исправить work_mm
} // end если был текуший старт стоп
else { // когда старт и стоп не полный
//Serial.println( "start? stop?");
if (fl_t_start) { // если был старт и небыло стопа
//Serial.println( "start only");
lcd.setCursor(3, 0);
f_printDigits(time_set[count].start_hh);
lcd.setCursor(5, 0);
lcd.println(":");
lcd.setCursor(6, 0);
f_printDigits(time_set[count].start_mm);
}
} // end когда старт и стоп не полный
} // end если выводим верхнюю строку
else { // если выводим нижнюю строку
lcd.setCursor(0, 1);
lcd.println(" ");
lcd.setCursor(0, 1);
//Serial.print("count ");
//Serial.println(count);
f_printDigits(count+1);
lcd.setCursor(3, 1);
lcd.print(" ");
if (f_reid_fl_start_stop (true, count)) { // если был и старт и стоп
//Serial.println( "start+stop");
lcd.setCursor(3, 1);
f_printDigits(time_set[count].start_hh);
lcd.setCursor(5, 1);
lcd.println(":");
lcd.setCursor(6, 1);
f_printDigits(time_set[count].start_mm);
lcd.setCursor(11, 1);
f_printDigits(time_set[count].stop_hh); // тут исправить work_hh
lcd.setCursor(13, 1);
lcd.println(":");
lcd.setCursor(14, 1);
f_printDigits(time_set[count].stop_mm); // тут исправить work_mm
} // end если был текуший старт стоп
else { // когда старт и стоп не полный
//Serial.println( "start? stop?");
if (fl_t_start) { // если был старт и небыло стопа
//Serial.println( "start only");
lcd.setCursor(3, 1);
f_printDigits(time_set[count].start_hh);
lcd.setCursor(5, 1);
lcd.println(":");
lcd.setCursor(6, 1);
f_printDigits(time_set[count].start_mm);
}
} // end когда старт и стоп не полный
} // end если выводим нижнюю строку
} // end функция вывода на дисплей строки верхней или нижней
// функция получающее значение флага старта или стопа из массива структур
bool f_reid_fl_start_stop (bool read_fl_start, byte count) {
if (read_fl_start) return time_set[count].fl_start_set;
else return time_set[count].fl_stop_set;
} // end функция получающее значение флага старта или стопа из массива структур
void f_work_change (bool fl_rabota, bool fl_t_start, bool& fl_mig_indik, bool& fl_backlight, bool fl_end_rec) { // функция обработки изменения замка зажигания
fl_backlight=true; // включаем подсветку дисплея
count_mig=0; // любое изменение в режиме работы обнуляет задержку принятия решения
count_off=0; // обнуляем секунды до выключения дислея
if (fl_rabota) { // если замок включен
fl_backlight=true; // включаем подсветку
fl_disp_clock=true; // разрешаем вывод часов
fl_history=false; // если было меню истории выключаем его
f_print_clock(fl_new_hour, fl_new_minute, fl_start_clock_disp); // отображаем время на дисплее
if (!fl_t_start) { // если старта еще небыло
//f_next_rec (fl_first_rec,count); // создаем новую запись
fl_mig_indik = true; // запускаем мигание временем старта
} // end если старта еще небыло
/*
if (fl_end_rec) { // если есть сохраненный и старт и стоп
f_next_rec (fl_first_rec,count); // создаем новую запись
} // end если есть сохраненный и старт и стоп
*/
} // end если замок включен
else { // если замок выключен
if (fl_t_start) { // если старт был
fl_mig_indik = true; // запускаем мигание временем стопа
} // end если старт был
else { // если старта не было
fl_mig_indik = false; // выключаем мигание временем старта
f_print_string (fl_top_string, count); // на экране пустая почти строка
//fl_backlight = false; // выключаем подсветку
} // end если старта не было
} // end если замок выключен
} // end функция обработки изменения замка зажигания
void f_button_press(bool fl_rabota, bool& fl_otloz, bool& fl_mig_indik) { // Новая функция обработки нажатия кнопки
if (fl_rabota) { // если замок включен
Serial.println("rabota true");
if (fl_t_start) { // если был старт
Serial.println("start true");
f_work_time(work_hh, work_mm); // функция запоминания рабочего времени
Serial.print("old_count=");
Serial.println(count);
f_set_time_arrey(fl_rabota, fl_t_start, fl_end_rec, count); // сохраняем в массив время стопа
f_print_string (true, count-1); // выводим полную строку на экран
Serial.print("new_count=");
Serial.println(count);
} // end если был старт
else { // старта небыло
Serial.println("start false");
if (fl_mig_indik) { // если включена мигалка
Serial.println("mig true");
fl_otloz=true; // поднимаем флаг паузы
f_lcd_pausa(fl_t_start); // обрабатываем паузу старта
} // end если включена мигалка
else { // это режим ручного сохранения старта на паузе или при новой записи без выключения замка
Serial.println("mig false");
f_work_time(work_hh, work_mm); // функция запоминания рабочего времени
f_set_time_arrey(fl_rabota, fl_t_start, fl_end_rec, count); // сохраняем в массив время старта
f_print_time_start(count); // выводим на экран время старта
} // end режим ручного сохранения старта на паузе или при новой записи без выключения замка
}// end старта небыло
} // end если замок включен
else { // замок выключен
Serial.println("rabota false");
if (fl_t_start) { // если был старт
Serial.println("start true");
if (fl_mig_indik) { // если включена мигалка
Serial.println("mig true");
fl_otloz=true; // поднимаем флаг паузы
f_lcd_pausa(fl_t_start); // обрабатываем паузу стопа
} // end если включена мигалка
else { // мигалка выключена (пауза стопа)
Serial.println("pausa stop?");
f_work_time(work_hh, work_mm); // функция запоминания рабочего времени
f_set_time_arrey(fl_rabota, fl_t_start, fl_end_rec, count); // сохраняем в массив время стопа
f_print_string (true, count); // выводим полную строку на экран
} // end мигалка выключена
}// end если был старт
} // замок выключен
} // end Новая функция обработки нажатия кнопки
void f_lcd_pausa(bool start) { // функция вывода на дисплей сообщения о запущенной паузе
lcd.setCursor(0, 0);
f_printDigits(count +1);
lcd.setCursor(2, 0);
lcd.println(" ");
lcd.setCursor(2, 0);
fl_mig_indik = false;
if (!start) lcd.println(" PAUSA START ");
else lcd.println(" PAUSA STOP ");
} // end функция вывода на дисплей сообщения о запущенной паузе
void f_lcd_menu () { // ф-я отображения меню на экране
if (enc1.isTurn()) lcd.clear(); // если был поворот очищаем экран
lcd.setCursor(2, 0);
lcd.print("MENU: ");
if (enc1.isRight()) { // если был поворот вправо
lcd.setCursor(0, 2);
lcd.print("DELETE ");
} // end если был поворот вправо
if (enc1.isLeft()) { // если был поворот влево
lcd.setCursor(0, 2);
lcd.print("SETTINGS ");
} // end если был поворот влево
} // end ф-я отображения меню на экране
/*
f_history() { // функция вывода на экран истории
} // end функция вывода на экран истории
*/
/* обработка событий энкодера
if (enc1.isTurn()) { // если был совершён поворот (индикатор поворота в любую сторону)
// ваш код
}
if (enc1.isRight()) { // если был поворот
lcd.clear();
lcd.println("Right");
}
if (enc1.isLeft()) {
lcd.clear();
lcd.println("Left");
}
if (enc1.isRightH()) Serial.println("Right holded"); // если было удержание + поворот
if (enc1.isLeftH()) Serial.println("Left holded");
if (enc1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (enc1.isClick()) Serial.println("Click"); // отпускание кнопки (+ дебаунс)
//if (enc1.isRelease()) Serial.println("Release"); // то же самое, что isClick
if (enc1.isHolded()) Serial.println("Holded"); // если была удержана и энк не поворачивался
//if (enc1.isHold()) Serial.println("Hold"); // возвращает состояние кнопки
*/