From 7f817f94c723121bcc31a3858ca8622ce2d98145 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 5 Sep 2024 00:23:20 +0300 Subject: [PATCH 01/28] =?UTF-8?q?=D0=A8=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 solarium/solarium.ino diff --git a/solarium/solarium.ino b/solarium/solarium.ino new file mode 100644 index 0000000..253a462 --- /dev/null +++ b/solarium/solarium.ino @@ -0,0 +1,13 @@ +/* + Управление соляриями +*/ + +void setup() { + // put your setup code here, to run once: + +} + +void loop() { + // put your main code here, to run repeatedly: + +} From 2d26cc0e50f4a2748150020c8bf425ab2cbc8075 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 10 Sep 2024 01:30:17 +0300 Subject: [PATCH 02/28] =?UTF-8?q?=D0=9A=D0=BD=D0=BE=D0=BF=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B7=D0=B0=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=BB=D0=B8,?= =?UTF-8?q?=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 130 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 253a462..326ce71 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -1,13 +1,139 @@ +#include + /* Управление соляриями */ +#include // Подключаем библиотеку для работы с шиной I2C +#include // Подключаем библиотеку для работы с LCD +#include + +// ===============================задаем константы ========================================================================= +const byte moneyPin = 2; // номер пина, к которому подключён купюроприемник, DB2 +const byte inhibitPin = 4; // +Inhibit (зеленый) на купюроприемник, DB4 +const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 +const byte buttonPin_Service = 13; // номер входа, подключенный к кнопке "Сервис", А1 +const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 +//const byte RelayPin = 17; // номер выхода, подключенный к реле, А3 +const byte Device_SerNum = 1; // серийный номер устройства +const char Device_Ver[] = "0.0"; // версия ПО устройства +const char Device_Date[] = "09/09/24"; // дата производства устройства +const unsigned long block = 500000; // блокировка устройства при превышении этой суммы денег + +boolean lastReading = false; // флаг предыдущего состояния кнопки +boolean buttonSingle = false; // флаг состояния "краткое нажатие" +boolean buttonDouble = false; // флаг состояния "двойное нажатие" +boolean buttonHold = false; // флаг состояния "долгое нажатие" +unsigned long onTime = 0; // переменная обработки временного интервала +unsigned long lastSwitchTime = 0; // переменная времени предыдущего переключения состояния +unsigned long ledStartTime = 0; // переменная-флаг времени начала включения LED + +const int bounceTime = 10; // задержка для подавления дребезга +const int holdTime = 1000; // время, в течение которого нажатие можно считать удержанием кнопки +const int doubleTime = 500; // время, в течение которого нажатия можно считать двойным + +// ============================== Описываем свой символ "Рубль" ======================================================================== +// Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными +byte rubl[8] = { + 0b00000, + 0b01110, + 0b01001, + 0b01001, + 0b01110, + 0b01000, + 0b11110, + 0b01000, +}; + +LiquidCrystal_I2C lcd(0x27, 16, 2); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки void setup() { - // put your setup code here, to run once: + Serial.begin(115200); + lcd.init(); // инициализация LCD + lcd.backlight(); // включаем подсветку + lcd.createChar(0, rubl); // создаем символ и записываем его в память LCD по 0 адресу + + pinMode(inhibitPin, OUTPUT); // устанавливает режим работы - выход + pinMode(moneyPin, INPUT_PULLUP); // устанавливает режим работы - вход, подтягиваем к +5В через встроенный подтягивающий резистор (на всякий случай) + pinMode(LEDPin, OUTPUT); // инициализируем пин, подключенный к светодиоду, как выход + pinMode(buttonPin_Service, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход + pinMode(buttonPin_Start, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход + + digitalWrite(LEDPin,LOW); // изначально светодиод погашен + digitalWrite(inhibitPin, LOW); // изначально разрешаем прием купюр +} + +void read_buttons(byte x) +{ + boolean reading = !digitalRead(x); + + if (reading && !lastReading) // проверка первичного нажатия + { + onTime = millis(); + } + if (reading && lastReading) // проверка удержания + { + if ((millis() - onTime) > holdTime) + { + buttonHold = true; + //digitalWrite(LEDPin, HIGH); // при удержании кнопки загорается светодиод + digitalWrite(LEDPin, !digitalRead(LEDPin)); // при удержании кнопки мигает светодиод + } + } + if (!reading && lastReading) // проверка отпускания кнопки + { + if (((millis() - onTime) > bounceTime) && !buttonHold) + { + if ((millis() - lastSwitchTime) >= doubleTime) + { + lastSwitchTime = millis(); + buttonSingle = true; + } + else + { + lastSwitchTime = millis(); + buttonDouble = true; + buttonSingle = false; + isButtonDouble(); + buttonDouble = false; // сброс состояния после выполнения команды + } + } + if (buttonHold) + { + buttonDouble = false; + isButtonHold(); + buttonHold = false; // сброс состояния после выполнения команды + } + } + lastReading = reading; + if (buttonSingle && (millis() - lastSwitchTime) > doubleTime) + { + buttonDouble = false; + isButtonSingle(); + buttonSingle = false; // сброс состояния после выполнения команды + } +} + +// ============================== удержание кнопки =============================================================================== +void isButtonHold() +{ + Serial.println( F("isButtonHold") ); +} + +// ============================== одиночное нажатие кнопки ======================================================================== +void isButtonSingle() +{ + Serial.println( F("isButtonSingle") ); +} + +// ================================ двойное нажатие кнопки ======================================================================== +void isButtonDouble() +{ + Serial.println( F("isButtonDouble") ); } void loop() { - // put your main code here, to run repeatedly: + + read_buttons(buttonPin_Service); } From 1978cc042f2334e9f53e419697b18d15687f1145 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Wed, 11 Sep 2024 02:25:29 +0300 Subject: [PATCH 03/28] =?UTF-8?q?=D0=91=D0=B0=D0=B7=D0=BE=D0=B2=D0=BE?= =?UTF-8?q?=D0=B5=20=D0=BC=D0=B5=D0=BD=D1=8E=20=D0=B7=D0=B0=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 226 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 214 insertions(+), 12 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 326ce71..5e17d49 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -1,5 +1,3 @@ -#include - /* Управление соляриями */ @@ -15,10 +13,11 @@ const byte buttonPin_Service = 13; // номер входа, п const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 //const byte RelayPin = 17; // номер выхода, подключенный к реле, А3 const byte Device_SerNum = 1; // серийный номер устройства -const char Device_Ver[] = "0.0"; // версия ПО устройства -const char Device_Date[] = "09/09/24"; // дата производства устройства +const PROGMEM char Device_Ver[] = "0.0"; // версия ПО устройства +const PROGMEM char Device_Date[] = "09/09/24"; // дата производства устройства const unsigned long block = 500000; // блокировка устройства при превышении этой суммы денег +//======Переменные обработки клавиш================= boolean lastReading = false; // флаг предыдущего состояния кнопки boolean buttonSingle = false; // флаг состояния "краткое нажатие" boolean buttonDouble = false; // флаг состояния "двойное нажатие" @@ -31,9 +30,18 @@ const int bounceTime = 10; // задержка для const int holdTime = 1000; // время, в течение которого нажатие можно считать удержанием кнопки const int doubleTime = 500; // время, в течение которого нажатия можно считать двойным +//======Переменные меню============================= +boolean menu_enable = false; // изначально не в МЕНЮ +byte menu_index = 0; +byte last_menu_index = 0; +byte line_index = 1; +byte cursor_index = 1; +byte last_cursor_index = 0; +byte show_window_first_line = 0; + // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными -byte rubl[8] = { +const PROGMEM byte rubl[8] = { 0b00000, 0b01110, 0b01001, @@ -44,7 +52,7 @@ byte rubl[8] = { 0b01000, }; -LiquidCrystal_I2C lcd(0x27, 16, 2); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки +LiquidCrystal_I2C lcd(0x27, 20, 4); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки void setup() { Serial.begin(115200); @@ -76,7 +84,6 @@ void read_buttons(byte x) if ((millis() - onTime) > holdTime) { buttonHold = true; - //digitalWrite(LEDPin, HIGH); // при удержании кнопки загорается светодиод digitalWrite(LEDPin, !digitalRead(LEDPin)); // при удержании кнопки мигает светодиод } } @@ -114,26 +121,221 @@ void read_buttons(byte x) } } +#define SIZE_SCREEN 4 + +enum type_menu_line { + MENU_LINE, + TEXT_LINE, + PARAM_LINE, + FIXED_LINE, +}; + +struct menu_line { + char string[20]; + type_menu_line type; + byte next_menu_index; +}; + +struct menu_screen { + menu_line menu_lines[5]; + byte count_lines; +}; + +const menu_screen menu_all[] = { + // Меню 0 + { + { + { + " MAIN MENU ", + FIXED_LINE, + 0 + }, + { + "Settings ", + MENU_LINE, + 1 + }, + { + "Statistic ", + MENU_LINE, + 2 + } + }, + 3 + }, + // Меню 1 + { + { + { + " SETTINGS ", + FIXED_LINE, + 0 + }, + { + "Solarium ", + MENU_LINE, + 1 + }, + { + "Bank ", + MENU_LINE, + 2 + }, + { + "Password ", + MENU_LINE, + 2 + }, + { + "Reset ", + MENU_LINE, + 2 + } + }, + 5 + }, + // Меню 2 + { + { + { + " STATISTIC ", + FIXED_LINE, + 0 + }, + { + "Long counters ", + MENU_LINE, + 1 + }, + { + "Short counters ", + MENU_LINE, + 2 + } + }, + 3 + }, +}; + // ============================== удержание кнопки =============================================================================== void isButtonHold() { - Serial.println( F("isButtonHold") ); + if(!menu_enable) + { + menu_index = 0; + menu_enable = true; + } + else + { + if(menu_index == 0) + { + menu_enable = false; + } + else + { + menu_index = last_menu_index; + lcd.clear(); + } + } } // ============================== одиночное нажатие кнопки ======================================================================== void isButtonSingle() { - Serial.println( F("isButtonSingle") ); + last_cursor_index = cursor_index; + cursor_index++; + line_index++; + + Serial.print(menu_all[menu_index].count_lines); + + if(cursor_index >= SIZE_SCREEN || cursor_index >= menu_all[menu_index].count_lines) + { + cursor_index = SIZE_SCREEN - 1; + show_window_first_line++; + + if(line_index >= menu_all[menu_index].count_lines) + { + byte cursor = 0; + for(cursor = 0; cursor < menu_all[menu_index].count_lines; cursor++) + { + if(menu_all[menu_index].menu_lines[cursor].type != FIXED_LINE) break; + } + cursor_index = (cursor_index >= SIZE_SCREEN ) ? SIZE_SCREEN - 1 : cursor; + line_index = cursor; + show_window_first_line = 0; + } + } } // ================================ двойное нажатие кнопки ======================================================================== void isButtonDouble() { - Serial.println( F("isButtonDouble") ); + if(menu_all[menu_index].menu_lines[line_index].type == MENU_LINE) + { + last_menu_index = menu_index; + menu_index = menu_all[menu_index].menu_lines[line_index].next_menu_index; + lcd.clear(); + } +} + +void show_line(byte index_line) +{ + lcd.print(menu_all[menu_index].menu_lines[index_line].string); +} + +void show_menu() +{ + for(byte i = 0; i < menu_all[menu_index].count_lines; i++) + { + if(show_window_first_line != 0 && i < show_window_first_line) continue; + if(i >= show_window_first_line + SIZE_SCREEN) break; + + lcd.setCursor(1, i - show_window_first_line); + show_line(i); + } +} + +void show_cursor() +{ + lcd.setCursor(0, last_cursor_index); + lcd.print(F(" ")); + lcd.setCursor(0, cursor_index); + lcd.print(F(">")); +} + +// ============================== процедура прорисовки меню и изменения значения параметров ======================================= +void menu () +{ + lcd.clear(); + digitalWrite(LEDPin, HIGH); + while (menu_enable == true) + { + read_buttons(buttonPin_Service); + //lcd.setCursor(0,0); + + show_menu(); + show_cursor(); + } + + lcd.clear(); + digitalWrite(LEDPin, LOW); } void loop() { - read_buttons(buttonPin_Service); - + if (menu_enable == true) // если флаг menu_enable = ИСТИНА, то входим в меню + { + menu(); + } + else + { + /*if (bill_enable == true && menu_enable == false) + { + get_money (); // принимаем деньги + }*/ + } + /*if (bill_enable == false && menu_enable == false) + { + countdown_timer(sek, minu); // запускаем таймер обратного отсчета + }*/ } From 57f80bc99e423ab9dea01951a96951c2e1b04250 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Wed, 11 Sep 2024 22:20:07 +0300 Subject: [PATCH 04/28] =?UTF-8?q?=D0=A1=20=D0=BC=D0=B5=D0=BD=D1=8E=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D0=BC=20=D0=B8=D1=85?= =?UTF-8?q?=20=D1=84=D0=BB=D0=B5=D1=88=20=D0=BF=D0=B0=D0=BC=D1=8F=D1=82?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 101 +++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 5e17d49..c1303d5 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -31,13 +31,18 @@ const int holdTime = 1000; // время, в течен const int doubleTime = 500; // время, в течение которого нажатия можно считать двойным //======Переменные меню============================= +#define MENU_INTER_COUNT 5 // количество возможных вложений меню +#define SIZE_SCREEN 4 // количество строк на экране +#define SIZE_SCREEN_LINE 20 // количество символов в строке на экране + boolean menu_enable = false; // изначально не в МЕНЮ -byte menu_index = 0; -byte last_menu_index = 0; -byte line_index = 1; -byte cursor_index = 1; -byte last_cursor_index = 0; -byte show_window_first_line = 0; +byte menu_index = 0; // текущий номер меню +byte menu_inter = 0; // индекс вложенности меню +byte last_menu_index[MENU_INTER_COUNT]; // стек переходов по меню +byte line_index = 1; // текущая выбранная строка меню +byte cursor_index = 1; // положение курсора на экране +byte last_cursor_index = 0; // предпоследнее положение курсора на экране +byte show_window_first_line = 0; // индекс первой отображаемой строки меню на экране // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными @@ -52,7 +57,7 @@ const PROGMEM byte rubl[8] = { 0b01000, }; -LiquidCrystal_I2C lcd(0x27, 20, 4); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки +LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки void setup() { Serial.begin(115200); @@ -121,8 +126,6 @@ void read_buttons(byte x) } } -#define SIZE_SCREEN 4 - enum type_menu_line { MENU_LINE, TEXT_LINE, @@ -131,7 +134,7 @@ enum type_menu_line { }; struct menu_line { - char string[20]; + char string[SIZE_SCREEN_LINE]; type_menu_line type; byte next_menu_index; }; @@ -141,7 +144,13 @@ struct menu_screen { byte count_lines; }; -const menu_screen menu_all[] = { +// текущее меню +menu_screen current_menu_screen; + +/* + описание меню +*/ +const menu_screen menu_all[] PROGMEM = { // Меню 0 { { @@ -217,12 +226,30 @@ const menu_screen menu_all[] = { }, }; -// ============================== удержание кнопки =============================================================================== +void find_first_line_menu() +{ + byte cursor = 0; + for(cursor = 0; cursor < current_menu_screen.count_lines; cursor++) + { + if(current_menu_screen.menu_lines[cursor].type != FIXED_LINE) break; + } + cursor_index = (cursor_index >= SIZE_SCREEN ) ? SIZE_SCREEN - 1 : cursor; + line_index = cursor; + show_window_first_line = 0; +} + +/* + удержание кнопки +*/ void isButtonHold() { if(!menu_enable) { menu_index = 0; + + memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + find_first_line_menu(); + menu_enable = true; } else @@ -233,59 +260,66 @@ void isButtonHold() } else { - menu_index = last_menu_index; + menu_index = last_menu_index[menu_inter]; + menu_inter--; + + memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + find_first_line_menu(); + lcd.clear(); } } } -// ============================== одиночное нажатие кнопки ======================================================================== +/* + одиночное нажатие кнопки +*/ void isButtonSingle() { last_cursor_index = cursor_index; cursor_index++; line_index++; - Serial.print(menu_all[menu_index].count_lines); - - if(cursor_index >= SIZE_SCREEN || cursor_index >= menu_all[menu_index].count_lines) + if(cursor_index >= SIZE_SCREEN || cursor_index >= current_menu_screen.count_lines) { cursor_index = SIZE_SCREEN - 1; show_window_first_line++; - if(line_index >= menu_all[menu_index].count_lines) + if(line_index >= current_menu_screen.count_lines) { - byte cursor = 0; - for(cursor = 0; cursor < menu_all[menu_index].count_lines; cursor++) - { - if(menu_all[menu_index].menu_lines[cursor].type != FIXED_LINE) break; - } - cursor_index = (cursor_index >= SIZE_SCREEN ) ? SIZE_SCREEN - 1 : cursor; - line_index = cursor; - show_window_first_line = 0; + find_first_line_menu(); } } } -// ================================ двойное нажатие кнопки ======================================================================== +/* + двойное нажатие кнопки +*/ void isButtonDouble() { - if(menu_all[menu_index].menu_lines[line_index].type == MENU_LINE) + if(current_menu_screen.menu_lines[line_index].type == MENU_LINE) { - last_menu_index = menu_index; - menu_index = menu_all[menu_index].menu_lines[line_index].next_menu_index; + last_menu_index[menu_inter] = menu_index; + menu_inter++; + menu_index = current_menu_screen.menu_lines[line_index].next_menu_index; + + memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + find_first_line_menu(); lcd.clear(); } } void show_line(byte index_line) { - lcd.print(menu_all[menu_index].menu_lines[index_line].string); + lcd.print(current_menu_screen.menu_lines[index_line].string); } +/* + Отображение текущего кадра меню +*/ void show_menu() { - for(byte i = 0; i < menu_all[menu_index].count_lines; i++) + for(byte i = 0; i < current_menu_screen.count_lines; i++) { if(show_window_first_line != 0 && i < show_window_first_line) continue; if(i >= show_window_first_line + SIZE_SCREEN) break; @@ -295,6 +329,9 @@ void show_menu() } } +/* + Отображение курсора в текущем положении +*/ void show_cursor() { lcd.setCursor(0, last_cursor_index); From 04b38893964bfc71211ea79ce9a82ddb91cac650 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 12 Sep 2024 02:20:34 +0300 Subject: [PATCH 05/28] =?UTF-8?q?=D0=A0=D0=B5=D0=B4=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=D1=82=D0=B5=D1=80=D0=BE=D0=B2=20=D0=B8=20?= =?UTF-8?q?=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 343 +++++++++++++++++++++++++++++++++++------- 1 file changed, 290 insertions(+), 53 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index c1303d5..4ad7e39 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -39,10 +39,23 @@ boolean menu_enable = false; // изначально не byte menu_index = 0; // текущий номер меню byte menu_inter = 0; // индекс вложенности меню byte last_menu_index[MENU_INTER_COUNT]; // стек переходов по меню -byte line_index = 1; // текущая выбранная строка меню +byte current_line_index = 1; // текущая выбранная строка меню byte cursor_index = 1; // положение курсора на экране byte last_cursor_index = 0; // предпоследнее положение курсора на экране byte show_window_first_line = 0; // индекс первой отображаемой строки меню на экране +boolean need_reload_menu = true; +boolean need_clear_menu = false; +boolean need_hide_cursor = false; +boolean start_edit_parameter = false; + +// Переменные для работы с соляриями + +byte all_parameters[10] = {11,22,50,0}; + +#define pause_before 0 +#define pause_after 1 +#define price 2 +#define remote_start 3 // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными @@ -74,6 +87,8 @@ void setup() { digitalWrite(LEDPin,LOW); // изначально светодиод погашен digitalWrite(inhibitPin, LOW); // изначально разрешаем прием купюр + + load_parameter(); } void read_buttons(byte x) @@ -126,17 +141,53 @@ void read_buttons(byte x) } } +#define MAIN_MENU 0 +#define SETTING_MENU 1 +#define STATISTIC_MENU 2 +#define SOLARIUM_MENU 3 + enum type_menu_line { - MENU_LINE, + MENU_LINE = 0, TEXT_LINE, - PARAM_LINE, + DIGIT_PARAM_LINE, FIXED_LINE, + LIST_PARAM_LINE, +}; + +struct param_limit { + byte min; + byte max; + byte default_value; +}; + +struct parameter_menu { + byte next_menu_index; +}; + +struct parameter_digit { + byte param_index; + param_limit limit; + char unit[5]; +}; + +struct parameter_list { + byte param_index; + param_limit limit; + + char list_data[10][4]; +}; + +union param_data { + parameter_list list; + parameter_digit digit; + parameter_menu menu; }; struct menu_line { char string[SIZE_SCREEN_LINE]; type_menu_line type; - byte next_menu_index; + + param_data parameter; }; struct menu_screen { @@ -155,19 +206,19 @@ const menu_screen menu_all[] PROGMEM = { { { { - " MAIN MENU ", + " MAIN MENU", FIXED_LINE, - 0 + {0} }, { - "Settings ", + "Settings", MENU_LINE, - 1 + {SETTING_MENU} }, { - "Statistic ", + "Statistic", MENU_LINE, - 2 + {STATISTIC_MENU} } }, 3 @@ -176,29 +227,29 @@ const menu_screen menu_all[] PROGMEM = { { { { - " SETTINGS ", + " SETTINGS", FIXED_LINE, - 0 + {0} }, { - "Solarium ", + "Solarium", MENU_LINE, - 1 + {SOLARIUM_MENU} }, { - "Bank ", + "Bank", MENU_LINE, - 2 + {2} }, { - "Password ", + "Password", MENU_LINE, - 2 + {2} }, { - "Reset ", + "Reset", MENU_LINE, - 2 + {2} } }, 5 @@ -207,23 +258,89 @@ const menu_screen menu_all[] PROGMEM = { { { { - " STATISTIC ", + " STATISTIC", FIXED_LINE, - 0 + {0} }, { - "Long counters ", + "Long counters", MENU_LINE, - 1 + {1} }, { - "Short counters ", + "Short counters", MENU_LINE, - 2 + {2} } }, 3 }, + // Меню 3 + { + { + { + " DEVICE", + FIXED_LINE, + {1} + }, + { + "Pause before", + DIGIT_PARAM_LINE, + { + pause_before, + { + 0, + 100, + 30 + }, + "sec" + } + }, + { + "Pause after", + DIGIT_PARAM_LINE, + { + pause_after, + { + 0, + 3, + 3 + }, + "min" + } + }, + { + "Price", + DIGIT_PARAM_LINE, + { + price, + { + 0, + 100, + 20 + }, + "rub" + } + }, + { + "Remote start", + LIST_PARAM_LINE, + { + remote_start, + { + 0, + 1, + 0 + }, + { + "Off", + "On " + } + } + } + }, + 5 + }, }; void find_first_line_menu() @@ -234,18 +351,36 @@ void find_first_line_menu() if(current_menu_screen.menu_lines[cursor].type != FIXED_LINE) break; } cursor_index = (cursor_index >= SIZE_SCREEN ) ? SIZE_SCREEN - 1 : cursor; - line_index = cursor; + current_line_index = cursor; show_window_first_line = 0; } +/* + Загрузка параметров из памяти +*/ +void load_parameter() +{ + +} + +/* + Сохранение параметра в память +*/ +void save_parameter(byte index_param) +{ + +} + /* удержание кнопки */ void isButtonHold() { + need_reload_menu = true; + if(!menu_enable) { - menu_index = 0; + menu_index = MAIN_MENU; memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); find_first_line_menu(); @@ -254,19 +389,36 @@ void isButtonHold() } else { - if(menu_index == 0) + if(start_edit_parameter) { - menu_enable = false; + start_edit_parameter = false; + need_hide_cursor = false; + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) + { + save_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + } + else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + { + save_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); + } } else { - menu_index = last_menu_index[menu_inter]; - menu_inter--; + if(menu_index == MAIN_MENU) + { + menu_enable = false; + } + else + { + menu_inter--; + menu_index = last_menu_index[menu_inter]; - memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); - find_first_line_menu(); + memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + find_first_line_menu(); - lcd.clear(); + digitalWrite(LEDPin, HIGH); + lcd.clear(); + } } } } @@ -276,19 +428,42 @@ void isButtonHold() */ void isButtonSingle() { - last_cursor_index = cursor_index; - cursor_index++; - line_index++; + need_reload_menu = true; - if(cursor_index >= SIZE_SCREEN || cursor_index >= current_menu_screen.count_lines) + if(start_edit_parameter) { - cursor_index = SIZE_SCREEN - 1; - show_window_first_line++; + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) + { + if(all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.max) + { + all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.min; + } + } + else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + { + if(all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.list.limit.max) + { + all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.list.limit.min; + } + } + } + else + { + last_cursor_index = cursor_index; + cursor_index++; + current_line_index++; - if(line_index >= current_menu_screen.count_lines) - { - find_first_line_menu(); - } + if(cursor_index >= SIZE_SCREEN || cursor_index >= current_menu_screen.count_lines) + { + cursor_index = SIZE_SCREEN - 1; + show_window_first_line++; + need_clear_menu = true; + + if(current_line_index >= current_menu_screen.count_lines) + { + find_first_line_menu(); + } + } } } @@ -297,21 +472,65 @@ void isButtonSingle() */ void isButtonDouble() { - if(current_menu_screen.menu_lines[line_index].type == MENU_LINE) + need_reload_menu = true; + + if(current_menu_screen.menu_lines[current_line_index].type == MENU_LINE) { last_menu_index[menu_inter] = menu_index; menu_inter++; - menu_index = current_menu_screen.menu_lines[line_index].next_menu_index; + menu_index = current_menu_screen.menu_lines[current_line_index].parameter.menu.next_menu_index; memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); find_first_line_menu(); lcd.clear(); - } + } + else if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE + || current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + { + if(!start_edit_parameter) + { + start_edit_parameter = true; + hide_cursor(); + need_hide_cursor = true; + } + } } void show_line(byte index_line) { - lcd.print(current_menu_screen.menu_lines[index_line].string); + if(current_menu_screen.menu_lines[index_line].type == MENU_LINE) + { + lcd.print(current_menu_screen.menu_lines[index_line].string); + } + else if(current_menu_screen.menu_lines[index_line].type == FIXED_LINE) + { + lcd.print(current_menu_screen.menu_lines[index_line].string); + } + else if(current_menu_screen.menu_lines[index_line].type == DIGIT_PARAM_LINE) + { + char line[21]; + char format[9] = "%s %d %s"; + if(start_edit_parameter && index_line == current_line_index) + { + format[2] = '>'; + } + sprintf(line,format, current_menu_screen.menu_lines[index_line].string, + all_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], + current_menu_screen.menu_lines[index_line].parameter.digit.unit); + lcd.print(line); + } + else if(current_menu_screen.menu_lines[index_line].type == LIST_PARAM_LINE) + { + char line[21]; + char format[6] = "%s %s"; + if(start_edit_parameter && index_line == current_line_index) + { + format[2] = '>'; + } + sprintf(line,format, current_menu_screen.menu_lines[index_line].string, + current_menu_screen.menu_lines[index_line].parameter.list.list_data[all_parameters[current_menu_screen.menu_lines[index_line].parameter.list.param_index]]); + lcd.print(line); + } } /* @@ -336,8 +555,18 @@ void show_cursor() { lcd.setCursor(0, last_cursor_index); lcd.print(F(" ")); + + if(!need_hide_cursor) + { + lcd.setCursor(0, cursor_index); + lcd.print(F(">")); + } +} + +void hide_cursor() +{ lcd.setCursor(0, cursor_index); - lcd.print(F(">")); + lcd.print(F(" ")); } // ============================== процедура прорисовки меню и изменения значения параметров ======================================= @@ -348,10 +577,18 @@ void menu () while (menu_enable == true) { read_buttons(buttonPin_Service); - //lcd.setCursor(0,0); - show_menu(); - show_cursor(); + if(need_clear_menu) + { + lcd.clear(); + need_clear_menu = false; + } + if(need_reload_menu) + { + show_menu(); + show_cursor(); + need_reload_menu = false; + } } lcd.clear(); From 398a4617c8b2ffeea5d7fc74fc08230ef4a40747 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 12 Sep 2024 23:15:10 +0300 Subject: [PATCH 06/28] =?UTF-8?q?=D0=9C=D0=B5=D0=BD=D1=8E=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E=20=D0=B3=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 344 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 308 insertions(+), 36 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 4ad7e39..72d7ba8 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -43,19 +43,44 @@ byte current_line_index = 1; // текущая выбра byte cursor_index = 1; // положение курсора на экране byte last_cursor_index = 0; // предпоследнее положение курсора на экране byte show_window_first_line = 0; // индекс первой отображаемой строки меню на экране -boolean need_reload_menu = true; -boolean need_clear_menu = false; -boolean need_hide_cursor = false; -boolean start_edit_parameter = false; +boolean need_reload_menu = true; // флаг перерисовки экрана +boolean need_clear_menu = false; // флаг очистки экрана +boolean need_hide_cursor = false; // флаг скытия курсора на экране +boolean start_edit_parameter = false; // флаг старта редактирования параметра // Переменные для работы с соляриями +#define pause_before 0 +#define pause_after 1 +#define price 2 +#define remote_start 3 +#define solarium_type 4 +#define work_regime 5 +#define signal_rele 6 +#define weight_impulse 7 +#define reset_device 8 +#define COUNT_BYTE_PARAMETER 9 +byte all_byte_parameters[COUNT_BYTE_PARAMETER]; -byte all_parameters[10] = {11,22,50,0}; +const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { + 30, + 3, + 20, + 0, + 0, + 0, + 0, + 10, + 0 +}; -#define pause_before 0 -#define pause_after 1 -#define price 2 -#define remote_start 3 +#define long_starts_counter 0 +#define long_money_counter 1 +#define long_time_counter 2 +#define short_starts_counter 3 +#define short_money_counter 4 +#define short_time_counter 5 +#define COUNT_LONG_PARAMETER 6 +unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными @@ -145,6 +170,10 @@ void read_buttons(byte x) #define SETTING_MENU 1 #define STATISTIC_MENU 2 #define SOLARIUM_MENU 3 +#define BANK_MENU 4 +#define PASSWORD_MENU 5 +#define LONG_COUNTER_MENU 6 +#define SHORT_COUNTER_MENU 7 enum type_menu_line { MENU_LINE = 0, @@ -152,12 +181,13 @@ enum type_menu_line { DIGIT_PARAM_LINE, FIXED_LINE, LIST_PARAM_LINE, + TEXT_PARAM_LINE, + DIGIT_VIEW_LINE, }; struct param_limit { byte min; byte max; - byte default_value; }; struct parameter_menu { @@ -173,13 +203,18 @@ struct parameter_digit { struct parameter_list { byte param_index; param_limit limit; + char list_data[4][13]; +}; - char list_data[10][4]; +struct parameter_header { + byte param_index; + param_limit limit; }; union param_data { parameter_list list; parameter_digit digit; + parameter_header header; parameter_menu menu; }; @@ -191,7 +226,7 @@ struct menu_line { }; struct menu_screen { - menu_line menu_lines[5]; + menu_line menu_lines[8]; byte count_lines; }; @@ -239,18 +274,28 @@ const menu_screen menu_all[] PROGMEM = { { "Bank", MENU_LINE, - {2} + {BANK_MENU} }, { "Password", MENU_LINE, - {2} + {PASSWORD_MENU} }, { "Reset", - MENU_LINE, - {2} - } + LIST_PARAM_LINE, + { + reset_device, + { + 0, + 1, + }, + { + " ", + "start" + } + } + }, }, 5 }, @@ -265,12 +310,12 @@ const menu_screen menu_all[] PROGMEM = { { "Long counters", MENU_LINE, - {1} + {LONG_COUNTER_MENU} }, { "Short counters", MENU_LINE, - {2} + {SHORT_COUNTER_MENU} } }, 3 @@ -291,7 +336,6 @@ const menu_screen menu_all[] PROGMEM = { { 0, 100, - 30 }, "sec" } @@ -304,7 +348,6 @@ const menu_screen menu_all[] PROGMEM = { { 0, 3, - 3 }, "min" } @@ -317,7 +360,6 @@ const menu_screen menu_all[] PROGMEM = { { 0, 100, - 20 }, "rub" } @@ -330,16 +372,202 @@ const menu_screen menu_all[] PROGMEM = { { 0, 1, - 0 }, { "Off", "On " } } - } + }, + { + "Type", + LIST_PARAM_LINE, + { + solarium_type, + { + 0, + 3, + }, + { + "Luxura ", + "FireSun UV ", + "FireSun UV+K", + "SunFlower " + } + } + }, + { + "Regime", + LIST_PARAM_LINE, + { + work_regime, + { + 0, + 1, + }, + { + "Kollaten", + "UV " + } + } + }, + { + "Signal", + LIST_PARAM_LINE, + { + signal_rele, + { + 0, + 1, + }, + { + "high", + "low " + } + } + }, }, - 5 + 8 + }, + // Меню 4 + { + { + { + " BANK", + FIXED_LINE, + {0} + }, + { + "Rub/imp", + DIGIT_PARAM_LINE, + { + weight_impulse, + { + 0, + 100, + }, + "" + } + }, + }, + 2 + }, + // Меню 5 + { + { + { + " PASSWORD", + FIXED_LINE, + {0} + }, + { + "", + DIGIT_PARAM_LINE, + { + weight_impulse, + { + 0, + 100, + }, + "" + } + }, + }, + 2 + }, + // Меню 6 + { + { + { + "LONG COUNTERS", + FIXED_LINE, + {0} + }, + { + "Starts", + DIGIT_VIEW_LINE, + { + long_starts_counter, + { + 0, + 0, + }, + "" + } + }, + { + "Money", + DIGIT_VIEW_LINE, + { + long_money_counter, + { + 0, + 0, + }, + "rub" + } + }, + { + "Time", + DIGIT_VIEW_LINE, + { + long_time_counter, + { + 0, + 0, + }, + "sec" + } + }, + }, + 4 + }, + // Меню 7 + { + { + { + "SHORT COUNTERS", + FIXED_LINE, + {0} + }, + { + "Starts", + DIGIT_VIEW_LINE, + { + short_starts_counter, + { + 0, + 0, + }, + "" + } + }, + { + "Money", + DIGIT_VIEW_LINE, + { + short_money_counter, + { + 0, + 0, + }, + "rub" + } + }, + { + "Time", + DIGIT_VIEW_LINE, + { + short_time_counter, + { + 0, + 0, + }, + "sec" + } + }, + }, + 4 }, }; @@ -360,15 +588,46 @@ void find_first_line_menu() */ void load_parameter() { - + for(int i = 0; i < COUNT_BYTE_PARAMETER; i++ ) + { + all_byte_parameters[i] = EEPROM.readByte(i); + } + for(int i = COUNT_BYTE_PARAMETER, j = 0; j < COUNT_LONG_PARAMETER; i += 4, j++ ) + { + all_long_parameters[j] = EEPROM.readLong(i); + } } /* Сохранение параметра в память */ -void save_parameter(byte index_param) +void save_byte_parameter(byte index_param) { + EEPROM.updateByte(index_param, all_byte_parameters[index_param]); +} +/* + Сохранение параметра в память +*/ +void save_long_parameter(byte index_param) +{ + EEPROM.updateLong(COUNT_BYTE_PARAMETER + index_param * 4, all_long_parameters[index_param]); +} + +/* + Сброс параметров в памяти +*/ +void reset_parameter() +{ + for(int i = 0; i < COUNT_BYTE_PARAMETER; i++) + { + all_byte_parameters[i] = all_byte_parameters_default[i]; + EEPROM.updateByte(i, all_byte_parameters_default[i]); + } + + all_long_parameters[short_starts_counter] = 0; + all_long_parameters[short_money_counter] = 0; + all_long_parameters[short_time_counter] = 0; } /* @@ -395,11 +654,11 @@ void isButtonHold() need_hide_cursor = false; if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) { - save_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); } else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) { - save_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); + save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); } } else @@ -434,16 +693,16 @@ void isButtonSingle() { if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) { - if(all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.max) + if(all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.max) { - all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.min; + all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.min; } } else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) { - if(all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.list.limit.max) + if(all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.list.limit.max) { - all_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.list.limit.min; + all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.list.limit.min; } } } @@ -515,7 +774,7 @@ void show_line(byte index_line) format[2] = '>'; } sprintf(line,format, current_menu_screen.menu_lines[index_line].string, - all_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], + all_byte_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], current_menu_screen.menu_lines[index_line].parameter.digit.unit); lcd.print(line); } @@ -528,9 +787,17 @@ void show_line(byte index_line) format[2] = '>'; } sprintf(line,format, current_menu_screen.menu_lines[index_line].string, - current_menu_screen.menu_lines[index_line].parameter.list.list_data[all_parameters[current_menu_screen.menu_lines[index_line].parameter.list.param_index]]); + current_menu_screen.menu_lines[index_line].parameter.list.list_data[all_byte_parameters[current_menu_screen.menu_lines[index_line].parameter.list.param_index]]); lcd.print(line); } + else if(current_menu_screen.menu_lines[index_line].type == DIGIT_VIEW_LINE) + { + char line[21]; + sprintf(line,"%s %ld %s", current_menu_screen.menu_lines[index_line].string, + all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], + current_menu_screen.menu_lines[index_line].parameter.digit.unit); + lcd.print(line); + } } /* @@ -570,7 +837,7 @@ void hide_cursor() } // ============================== процедура прорисовки меню и изменения значения параметров ======================================= -void menu () +void menu() { lcd.clear(); digitalWrite(LEDPin, HIGH); @@ -589,6 +856,11 @@ void menu () show_cursor(); need_reload_menu = false; } + if(all_byte_parameters[reset_device]) + { + reset_parameter(); + all_byte_parameters[reset_device] = 0; + } } lcd.clear(); From 655be76f831323b5375e0532416791d746cea982 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 13 Sep 2024 01:48:20 +0300 Subject: [PATCH 07/28] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D0=B0=20=D0=B4=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=B3=20=D0=B8=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=BC=D0=B5=D0=BD=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 233 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 200 insertions(+), 33 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 72d7ba8..321790e 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -11,10 +11,10 @@ const byte inhibitPin = 4; // +Inhibit (зеленый) const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 const byte buttonPin_Service = 13; // номер входа, подключенный к кнопке "Сервис", А1 const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 -//const byte RelayPin = 17; // номер выхода, подключенный к реле, А3 +//const byte RelayPin = 17; // номер выхода, подключенный к реле, А3 const byte Device_SerNum = 1; // серийный номер устройства -const PROGMEM char Device_Ver[] = "0.0"; // версия ПО устройства -const PROGMEM char Device_Date[] = "09/09/24"; // дата производства устройства +const PROGMEM char Device_Ver[] = "0.0"; // версия ПО устройства +const PROGMEM char Device_Date[] = "09/09/24"; // дата производства устройства const unsigned long block = 500000; // блокировка устройства при превышении этой суммы денег //======Переменные обработки клавиш================= @@ -30,6 +30,20 @@ const int bounceTime = 10; // задержка для const int holdTime = 1000; // время, в течение которого нажатие можно считать удержанием кнопки const int doubleTime = 500; // время, в течение которого нажатия можно считать двойным +// Переменные приема денег +boolean bill_enable = true; // изначально купюроприемник принимает деньги + +// Данные сеанса +int minute = 0; +int remain = 0; +int second = 0; + +volatile unsigned int impulseCounter = 0; // счетчик импульсов от купюроприемника (1 = 10 руб.). volatile для видимости переменной и в функции обработки прерывания +byte debounceDelay = 10; // для устранения дребезга устанавливаем мин. длительность принимаемого импульса +int trueState = LOW; +int lastState = LOW; +unsigned long lastStateChangeTime = 0; // положительные целые числа (4 байта) + //======Переменные меню============================= #define MENU_INTER_COUNT 5 // количество возможных вложений меню #define SIZE_SCREEN 4 // количество строк на экране @@ -79,9 +93,14 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { #define short_starts_counter 3 #define short_money_counter 4 #define short_time_counter 5 -#define COUNT_LONG_PARAMETER 6 +#define impulse_counter 6 +#define COUNT_LONG_PARAMETER 7 unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; +#define time_seance 0 +#define COUNT_TEXT_PARAMETER 1 +char text_parameters[COUNT_TEXT_PARAMETER][6]; + // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными const PROGMEM byte rubl[8] = { @@ -97,25 +116,6 @@ const PROGMEM byte rubl[8] = { LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки -void setup() { - Serial.begin(115200); - - lcd.init(); // инициализация LCD - lcd.backlight(); // включаем подсветку - lcd.createChar(0, rubl); // создаем символ и записываем его в память LCD по 0 адресу - - pinMode(inhibitPin, OUTPUT); // устанавливает режим работы - выход - pinMode(moneyPin, INPUT_PULLUP); // устанавливает режим работы - вход, подтягиваем к +5В через встроенный подтягивающий резистор (на всякий случай) - pinMode(LEDPin, OUTPUT); // инициализируем пин, подключенный к светодиоду, как выход - pinMode(buttonPin_Service, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход - pinMode(buttonPin_Start, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход - - digitalWrite(LEDPin,LOW); // изначально светодиод погашен - digitalWrite(inhibitPin, LOW); // изначально разрешаем прием купюр - - load_parameter(); -} - void read_buttons(byte x) { boolean reading = !digitalRead(x); @@ -211,9 +211,16 @@ struct parameter_header { param_limit limit; }; +struct parameter_text { + byte param_index; + param_limit limit; + char unit[5]; +}; + union param_data { parameter_list list; parameter_digit digit; + parameter_text text; parameter_header header; parameter_menu menu; }; @@ -234,9 +241,64 @@ struct menu_screen { menu_screen current_menu_screen; /* - описание меню + Описание основного меню */ -const menu_screen menu_all[] PROGMEM = { +const menu_screen menu_main[] PROGMEM = { + { + { + { + "", + FIXED_LINE, + {0} + }, + { + " BHECEHO", + FIXED_LINE, + {0} + }, + { + " ", + DIGIT_VIEW_LINE, + { + impulse_counter, + { + 0, + 0, + }, + "rub" + } + }, + }, + 3 + }, + { + { + { + "", + FIXED_LINE, + {0} + }, + { + " ", + TEXT_PARAM_LINE, + { + time_seance, + { + 0, + 0, + }, + "MUH" + }, + }, + }, + 2 + }, +}; + +/* + описание настроечного меню +*/ +const menu_screen menu_settings[] PROGMEM = { // Меню 0 { { @@ -626,8 +688,16 @@ void reset_parameter() } all_long_parameters[short_starts_counter] = 0; + save_long_parameter(short_starts_counter); + all_long_parameters[short_money_counter] = 0; + save_long_parameter(short_money_counter); + all_long_parameters[short_time_counter] = 0; + save_long_parameter(short_time_counter); + + all_long_parameters[impulse_counter] = 0; + save_long_parameter(impulse_counter); } /* @@ -641,7 +711,7 @@ void isButtonHold() { menu_index = MAIN_MENU; - memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + memcpy_P( ¤t_menu_screen, &menu_settings[menu_index], sizeof(menu_screen)); find_first_line_menu(); menu_enable = true; @@ -672,7 +742,7 @@ void isButtonHold() menu_inter--; menu_index = last_menu_index[menu_inter]; - memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + memcpy_P( ¤t_menu_screen, &menu_settings[menu_index], sizeof(menu_screen)); find_first_line_menu(); digitalWrite(LEDPin, HIGH); @@ -739,7 +809,7 @@ void isButtonDouble() menu_inter++; menu_index = current_menu_screen.menu_lines[current_line_index].parameter.menu.next_menu_index; - memcpy_P( ¤t_menu_screen, &menu_all[menu_index], sizeof(menu_screen)); + memcpy_P( ¤t_menu_screen, &menu_settings[menu_index], sizeof(menu_screen)); find_first_line_menu(); lcd.clear(); } @@ -798,6 +868,14 @@ void show_line(byte index_line) current_menu_screen.menu_lines[index_line].parameter.digit.unit); lcd.print(line); } + else if(current_menu_screen.menu_lines[index_line].type == TEXT_PARAM_LINE) + { + char line[21]; + sprintf(line,"%s %s %s", current_menu_screen.menu_lines[index_line].string, + text_parameters[current_menu_screen.menu_lines[index_line].parameter.text.param_index], + current_menu_screen.menu_lines[index_line].parameter.text.unit); + lcd.print(line); + } } /* @@ -836,11 +914,70 @@ void hide_cursor() lcd.print(F(" ")); } +/* + * Функция подсчета импульсов от купюроприемника + * Когда импульсов нет, записываются значения reading = trueState = lastState = HIGH, при поступлении импульса reading = LOW, + * фиксируется время появления импульса в lastStateChangeTime. Если длительность импульса > debounceDelay (время дребезга), + * значит это полезный импульс, значения изменяются reading = trueState = lastState = LOW + */ +void read_money_impulse () +{ + int reading = digitalRead(moneyPin); + if (reading != lastState) + { + lastStateChangeTime = millis(); + } + if ((millis() - lastStateChangeTime) > debounceDelay) + { + if (reading != trueState) + { + trueState = reading; + if (trueState == LOW) + { + all_long_parameters[impulse_counter] += all_byte_parameters[weight_impulse]; + } + } + } + lastState = reading; +} + +/* + Прием денег +*/ +void get_money () +{ + read_money_impulse (); + + minute = all_long_parameters[impulse_counter] / all_byte_parameters[price]; + remain = all_long_parameters[impulse_counter] % all_byte_parameters[price]; + second = remain * 60 / all_byte_parameters[price]; + + sprintf(text_parameters[time_seance],"%02d:%02d",minute, second); + + if (all_long_parameters[impulse_counter] >= all_byte_parameters[price]) + { + // достаточно денег для оказания услуги + memcpy_P( ¤t_menu_screen, &menu_main[1], sizeof(menu_screen)); + + digitalWrite(LEDPin, HIGH); + + if (digitalRead(buttonPin_Start) == HIGH) + { + digitalWrite(inhibitPin, HIGH); // выставляем запрет приема монет + digitalWrite(LEDPin, LOW); // гасим светодиод + + } + } +} + // ============================== процедура прорисовки меню и изменения значения параметров ======================================= void menu() { lcd.clear(); digitalWrite(LEDPin, HIGH); + show_cursor(); + need_hide_cursor = false; + while (menu_enable == true) { read_buttons(buttonPin_Service); @@ -867,18 +1004,48 @@ void menu() digitalWrite(LEDPin, LOW); } +void setup() { + Serial.begin(115200); + + lcd.init(); // инициализация LCD + lcd.backlight(); // включаем подсветку + lcd.createChar(0, rubl); // создаем символ и записываем его в память LCD по 0 адресу + + pinMode(inhibitPin, OUTPUT); // устанавливает режим работы - выход + pinMode(moneyPin, INPUT_PULLUP); // устанавливает режим работы - вход, подтягиваем к +5В через встроенный подтягивающий резистор (на всякий случай) + pinMode(LEDPin, OUTPUT); // инициализируем пин, подключенный к светодиоду, как выход + pinMode(buttonPin_Service, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход + pinMode(buttonPin_Start, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход + + digitalWrite(LEDPin,LOW); // изначально светодиод погашен + digitalWrite(inhibitPin, LOW); // изначально разрешаем прием купюр + + load_parameter(); + memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); +} + void loop() { read_buttons(buttonPin_Service); + hide_cursor(); + need_hide_cursor = true; + if (menu_enable == true) // если флаг menu_enable = ИСТИНА, то входим в меню { - menu(); + menu(); + need_reload_menu = true; + memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); } else - { - /*if (bill_enable == true && menu_enable == false) + { + if (bill_enable == true && menu_enable == false) { - get_money (); // принимаем деньги - }*/ + get_money(); + } + if(need_reload_menu) + { + show_menu(); + need_reload_menu = false; + } } /*if (bill_enable == false && menu_enable == false) { From eb203bfb286f4db00338cbc4e124bead23fae489 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Mon, 16 Sep 2024 22:30:35 +0300 Subject: [PATCH 08/28] =?UTF-8?q?=D0=A0=D0=B8=D1=81=D1=83=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8E=20=D1=81=D0=B5=D0=B0=D0=BD=D1=81=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 124 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 15 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 321790e..4f4703e 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -44,6 +44,9 @@ int trueState = LOW; int lastState = LOW; unsigned long lastStateChangeTime = 0; // положительные целые числа (4 байта) +boolean counter = false; // счетчик для полусекунд +unsigned long previousMillis = 0; // переменная для хранения значений таймера + //======Переменные меню============================= #define MENU_INTER_COUNT 5 // количество возможных вложений меню #define SIZE_SCREEN 4 // количество строк на экране @@ -98,7 +101,9 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; #define time_seance 0 -#define COUNT_TEXT_PARAMETER 1 +#define time_delay 1 +#define time_delay 1 +#define COUNT_TEXT_PARAMETER 2 char text_parameters[COUNT_TEXT_PARAMETER][6]; // ============================== Описываем свой символ "Рубль" ======================================================================== @@ -244,6 +249,7 @@ menu_screen current_menu_screen; Описание основного меню */ const menu_screen menu_main[] PROGMEM = { + // Меню внесения денег и отображения времени сеанкса { { { @@ -253,11 +259,6 @@ const menu_screen menu_main[] PROGMEM = { }, { " BHECEHO", - FIXED_LINE, - {0} - }, - { - " ", DIGIT_VIEW_LINE, { impulse_counter, @@ -268,9 +269,22 @@ const menu_screen menu_main[] PROGMEM = { "rub" } }, + { + "", + DIGIT_VIEW_LINE, + { + time_seance, + { + 0, + 0, + }, + "" + } + }, }, 3 }, + // Время задержки до { { { @@ -281,6 +295,34 @@ const menu_screen menu_main[] PROGMEM = { { " ", TEXT_PARAM_LINE, + { + time_delay, + { + 0, + 0, + }, + "CEK" + }, + }, + }, + 2 + }, + // Меню ведения сеанса + { + { + { + "", + FIXED_LINE, + {0} + }, + { + " CEAHC", + FIXED_LINE, + {0} + }, + { + " ", + DIGIT_VIEW_LINE, { time_seance, { @@ -288,7 +330,23 @@ const menu_screen menu_main[] PROGMEM = { 0, }, "MUH" - }, + } + }, + }, + 3 + }, + // Меню окончания сеанса + { + { + { + "", + FIXED_LINE, + {0} + }, + { + " KOHEU", + FIXED_LINE, + {0} }, }, 2 @@ -952,20 +1010,24 @@ void get_money () remain = all_long_parameters[impulse_counter] % all_byte_parameters[price]; second = remain * 60 / all_byte_parameters[price]; - sprintf(text_parameters[time_seance],"%02d:%02d",minute, second); - if (all_long_parameters[impulse_counter] >= all_byte_parameters[price]) { // достаточно денег для оказания услуги - memcpy_P( ¤t_menu_screen, &menu_main[1], sizeof(menu_screen)); + sprintf(text_parameters[time_seance]," CEAHC %02d:%02d MUH", minute, second); + + digitalWrite(LEDPin, HIGH); // зажигаем светодиод - digitalWrite(LEDPin, HIGH); if (digitalRead(buttonPin_Start) == HIGH) { digitalWrite(inhibitPin, HIGH); // выставляем запрет приема монет digitalWrite(LEDPin, LOW); // гасим светодиод + lcd.clear(); + sprintf(text_parameters[time_seance],"%2d", all_byte_parameters[pause_before]); + delay(all_byte_parameters[pause_before]); + + bill_enable =! bill_enable; // устанавливаем флаг: не принимаем деньги } } } @@ -1004,6 +1066,37 @@ void menu() digitalWrite(LEDPin, LOW); } +/* + Событие полусекунды +*/ +void one_half_second() +{ + +} + +/* + Событие секунды +*/ +void second_event() +{ + +} + +void countdown_timer() +{ + if (millis() - previousMillis > 500) + { + one_half_second(); + + previousMillis = millis(); + counter = !counter; + if (counter == false) + { + second_event(); + } + } +} + void setup() { Serial.begin(115200); @@ -1024,7 +1117,8 @@ void setup() { memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); } -void loop() { +void loop() +{ read_buttons(buttonPin_Service); hide_cursor(); need_hide_cursor = true; @@ -1047,8 +1141,8 @@ void loop() { need_reload_menu = false; } } - /*if (bill_enable == false && menu_enable == false) + if (bill_enable == false && menu_enable == false) { - countdown_timer(sek, minu); // запускаем таймер обратного отсчета - }*/ + countdown_timer(); // запускаем таймер обратного отсчета + } } From 362aeb6ae5e9c360e2f44b262a36042caf3d196a Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 17 Sep 2024 00:26:56 +0300 Subject: [PATCH 09/28] =?UTF-8?q?=D0=A1=D0=BA=D0=B5=D0=BB=D0=B5=D1=82=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20=D1=81=D0=BE?= =?UTF-8?q?=D0=BB=D1=8F=D1=80=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 127 +++++++++++++++++++++++++++++++++--------- 1 file changed, 100 insertions(+), 27 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 4f4703e..73b0c10 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -11,7 +11,12 @@ const byte inhibitPin = 4; // +Inhibit (зеленый) const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 const byte buttonPin_Service = 13; // номер входа, подключенный к кнопке "Сервис", А1 const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 -//const byte RelayPin = 17; // номер выхода, подключенный к реле, А3 + +// ноги управления соляриями +const byte lamp_start_pin = 5; // Запуск солярия Luxura. Включение ламп солярия FireSun, SunFlower +const byte vent_pin = 6; // Включение вентиляторов солярия FireSun, SunFlower +const byte start_solarium = 7; // Удаленный старт от солярия + const byte Device_SerNum = 1; // серийный номер устройства const PROGMEM char Device_Ver[] = "0.0"; // версия ПО устройства const PROGMEM char Device_Date[] = "09/09/24"; // дата производства устройства @@ -96,15 +101,14 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { #define short_starts_counter 3 #define short_money_counter 4 #define short_time_counter 5 -#define impulse_counter 6 +#define money_counter 6 #define COUNT_LONG_PARAMETER 7 unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; #define time_seance 0 #define time_delay 1 -#define time_delay 1 #define COUNT_TEXT_PARAMETER 2 -char text_parameters[COUNT_TEXT_PARAMETER][6]; +char text_parameters[COUNT_TEXT_PARAMETER][20]; // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными @@ -258,10 +262,10 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " BHECEHO", + " BHECEHO", DIGIT_VIEW_LINE, { - impulse_counter, + money_counter, { 0, 0, @@ -271,7 +275,7 @@ const menu_screen menu_main[] PROGMEM = { }, { "", - DIGIT_VIEW_LINE, + TEXT_PARAM_LINE, { time_seance, { @@ -316,13 +320,13 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " CEAHC", + " CEAHC", FIXED_LINE, {0} }, { - " ", - DIGIT_VIEW_LINE, + " ", + TEXT_PARAM_LINE, { time_seance, { @@ -754,8 +758,8 @@ void reset_parameter() all_long_parameters[short_time_counter] = 0; save_long_parameter(short_time_counter); - all_long_parameters[impulse_counter] = 0; - save_long_parameter(impulse_counter); + all_long_parameters[money_counter] = 0; + save_long_parameter(money_counter); } /* @@ -978,9 +982,10 @@ void hide_cursor() * фиксируется время появления импульса в lastStateChangeTime. Если длительность импульса > debounceDelay (время дребезга), * значит это полезный импульс, значения изменяются reading = trueState = lastState = LOW */ -void read_money_impulse () +bool read_money_impulse () { int reading = digitalRead(moneyPin); + bool impulse = false; if (reading != lastState) { lastStateChangeTime = millis(); @@ -992,42 +997,74 @@ void read_money_impulse () trueState = reading; if (trueState == LOW) { - all_long_parameters[impulse_counter] += all_byte_parameters[weight_impulse]; + all_long_parameters[money_counter] += all_byte_parameters[weight_impulse]; + impulse = true; } } } - lastState = reading; -} + lastState = reading; + + return impulse; +} /* Прием денег */ void get_money () { - read_money_impulse (); + bool impulse = read_money_impulse(); - minute = all_long_parameters[impulse_counter] / all_byte_parameters[price]; - remain = all_long_parameters[impulse_counter] % all_byte_parameters[price]; + minute = all_long_parameters[money_counter] / all_byte_parameters[price]; + remain = all_long_parameters[money_counter] % all_byte_parameters[price]; second = remain * 60 / all_byte_parameters[price]; - if (all_long_parameters[impulse_counter] >= all_byte_parameters[price]) + if(impulse) need_reload_menu = true; + + if (all_long_parameters[money_counter] >= all_byte_parameters[price]) { // достаточно денег для оказания услуги sprintf(text_parameters[time_seance]," CEAHC %02d:%02d MUH", minute, second); digitalWrite(LEDPin, HIGH); // зажигаем светодиод - - if (digitalRead(buttonPin_Start) == HIGH) + if (digitalRead(buttonPin_Start) == LOW) { digitalWrite(inhibitPin, HIGH); // выставляем запрет приема монет - digitalWrite(LEDPin, LOW); // гасим светодиод - lcd.clear(); + digitalWrite(LEDPin, LOW); // гасим светодиод - sprintf(text_parameters[time_seance],"%2d", all_byte_parameters[pause_before]); - delay(all_byte_parameters[pause_before]); + // сохраняем статистику + { + all_long_parameters[long_starts_counter]++; + save_long_parameter(long_starts_counter); + all_long_parameters[short_starts_counter]++; + save_long_parameter(short_starts_counter); + all_long_parameters[long_time_counter] += minute * 60 + second; + save_long_parameter(long_time_counter); + all_long_parameters[short_time_counter] += minute * 60 + second; + save_long_parameter(short_time_counter); + all_long_parameters[long_money_counter] += all_long_parameters[money_counter]; + save_long_parameter(long_money_counter); + all_long_parameters[short_money_counter] += all_long_parameters[money_counter]; + save_long_parameter(short_money_counter); + all_long_parameters[money_counter] = 0; + save_long_parameter(money_counter); + } + + // задержка до запуска + memcpy_P( ¤t_menu_screen, &menu_main[1], sizeof(menu_screen)); + sprintf(text_parameters[time_delay],"%2d", all_byte_parameters[pause_before]); + lcd.clear(); + show_menu(); + delay(all_byte_parameters[pause_before] * 1000); + + memcpy_P( ¤t_menu_screen, &menu_main[2], sizeof(menu_screen)); + menu_index = 2; + sprintf(text_parameters[time_seance]," %02d:%02d", minute, second); + need_clear_menu = true; + need_reload_menu = true; bill_enable =! bill_enable; // устанавливаем флаг: не принимаем деньги + // Запускаем работу солярия } } } @@ -1079,7 +1116,35 @@ void one_half_second() */ void second_event() { + unsigned long time_remain = minute * 60 + second - 1; + minute = time_remain / 60; + second = time_remain % 60; + + sprintf(text_parameters[time_seance]," %02d:%02d", minute, second); + need_reload_menu = true; + + if(menu_index == 3 && time_remain == 0) + { + memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); + sprintf(text_parameters[time_seance],""); + menu_index = 0; + + need_clear_menu = true; + need_reload_menu = true; + + bill_enable =! bill_enable; + } + if(menu_index == 2 && time_remain == 0) + { + memcpy_P( ¤t_menu_screen, &menu_main[3], sizeof(menu_screen)); + menu_index = 3; + + need_clear_menu = true; + need_reload_menu = true; + + second = 10; + } } void countdown_timer() @@ -1097,7 +1162,8 @@ void countdown_timer() } } -void setup() { +void setup() +{ Serial.begin(115200); lcd.init(); // инициализация LCD @@ -1115,6 +1181,8 @@ void setup() { load_parameter(); memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); + sprintf(text_parameters[time_seance],""); + menu_index = 0; } void loop() @@ -1135,6 +1203,11 @@ void loop() { get_money(); } + if(need_clear_menu) + { + lcd.clear(); + need_clear_menu = false; + } if(need_reload_menu) { show_menu(); From d105199434eabfe95a732f192d1d41caa1b729ca Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 17 Sep 2024 02:02:50 +0300 Subject: [PATCH 10/28] =?UTF-8?q?=D0=92=D1=81=D0=B5=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20=D0=B2=D1=81=D0=B5=20=D0=BA?= =?UTF-8?q?=D1=80=D0=BE=D0=BC=D0=B5=20=D1=81=D0=BE=D0=BB=D1=8F=D1=80=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BA=D0=BE=D0=BB=D0=BB=D0=B0=D1=82=D0=B5=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 210 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 181 insertions(+), 29 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 73b0c10..07c5ab9 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -70,17 +70,27 @@ boolean need_clear_menu = false; // флаг очистки boolean need_hide_cursor = false; // флаг скытия курсора на экране boolean start_edit_parameter = false; // флаг старта редактирования параметра +bool enable_reset = false; // разрешение сброса настроек + // Переменные для работы с соляриями #define pause_before 0 #define pause_after 1 #define price 2 #define remote_start 3 + +#define LUXURA_SOL 0 +#define FIRESUN_UV_SOL 1 +#define FIRESUN_UV_K_SOL 2 +#define SUNFLOWER_SOL 3 + #define solarium_type 4 #define work_regime 5 #define signal_rele 6 #define weight_impulse 7 #define reset_device 8 -#define COUNT_BYTE_PARAMETER 9 +#define reset_counters 9 +#define password 10 +#define COUNT_BYTE_PARAMETER 11 byte all_byte_parameters[COUNT_BYTE_PARAMETER]; const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { @@ -92,7 +102,9 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { 0, 0, 10, - 0 + 0, + 0, + 0, }; #define long_starts_counter 0 @@ -112,7 +124,7 @@ char text_parameters[COUNT_TEXT_PARAMETER][20]; // ============================== Описываем свой символ "Рубль" ======================================================================== // Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными -const PROGMEM byte rubl[8] = { +const byte rubl[8] = { 0b00000, 0b01110, 0b01001, @@ -270,7 +282,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - "rub" + 0 } }, { @@ -282,7 +294,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - "" + " " } }, }, @@ -339,6 +351,34 @@ const menu_screen menu_main[] PROGMEM = { }, 3 }, + // Меню паузы после сеанса + { + { + { + "", + FIXED_LINE, + {0} + }, + { + " PAUSE", + FIXED_LINE, + {0} + }, + { + "", + TEXT_PARAM_LINE, + { + time_seance, + { + 0, + 0, + }, + " " + } + }, + }, + 3 + }, // Меню окончания сеанса { { @@ -485,7 +525,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - "rub" + 0 } }, { @@ -570,7 +610,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - "" + " " } }, }, @@ -585,15 +625,15 @@ const menu_screen menu_settings[] PROGMEM = { {0} }, { - "", + "Pasword", DIGIT_PARAM_LINE, { - weight_impulse, + password, { 0, - 100, + 255, }, - "" + " " } }, }, @@ -616,7 +656,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - "" + " " } }, { @@ -628,7 +668,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - "rub" + 0 } }, { @@ -663,7 +703,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - "" + " " } }, { @@ -675,7 +715,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - "rub" + 0 } }, { @@ -758,10 +798,31 @@ void reset_parameter() all_long_parameters[short_time_counter] = 0; save_long_parameter(short_time_counter); + all_long_parameters[long_starts_counter] = 0; + save_long_parameter(long_starts_counter); + + all_long_parameters[long_money_counter] = 0; + save_long_parameter(long_money_counter); + + all_long_parameters[long_time_counter] = 0; + save_long_parameter(long_time_counter); + all_long_parameters[money_counter] = 0; save_long_parameter(money_counter); } +void reset_short_counters() +{ + all_long_parameters[short_starts_counter] = 0; + save_long_parameter(short_starts_counter); + + all_long_parameters[short_money_counter] = 0; + save_long_parameter(short_money_counter); + + all_long_parameters[short_time_counter] = 0; + save_long_parameter(short_time_counter); +} + /* удержание кнопки */ @@ -927,8 +988,11 @@ void show_line(byte index_line) char line[21]; sprintf(line,"%s %ld %s", current_menu_screen.menu_lines[index_line].string, all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], - current_menu_screen.menu_lines[index_line].parameter.digit.unit); - lcd.print(line); + current_menu_screen.menu_lines[index_line].parameter.digit.unit[0] >= 0x20 ? + current_menu_screen.menu_lines[index_line].parameter.digit.unit : + ""); + lcd.print(line); + current_menu_screen.menu_lines[index_line].parameter.digit.unit[0] < 0x20 ? lcd.write(0) : 0; } else if(current_menu_screen.menu_lines[index_line].type == TEXT_PARAM_LINE) { @@ -936,7 +1000,7 @@ void show_line(byte index_line) sprintf(line,"%s %s %s", current_menu_screen.menu_lines[index_line].string, text_parameters[current_menu_screen.menu_lines[index_line].parameter.text.param_index], current_menu_screen.menu_lines[index_line].parameter.text.unit); - lcd.print(line); + lcd.print(line); } } @@ -1007,6 +1071,49 @@ bool read_money_impulse () return impulse; } +void start_solarium_work() +{ + if(all_byte_parameters[signal_rele]) digitalWrite(lamp_start_pin, HIGH); + else digitalWrite(lamp_start_pin, LOW); + + switch(all_byte_parameters[solarium_type]) + { + case LUXURA_SOL: + break; + case FIRESUN_UV_SOL: + digitalWrite(vent_pin, HIGH); + break; + case FIRESUN_UV_K_SOL: + break; + case SUNFLOWER_SOL: + digitalWrite(vent_pin, HIGH); + break; + } +} + +void stop_solarium_work() +{ + if(all_byte_parameters[signal_rele]) digitalWrite(lamp_start_pin, LOW); + else digitalWrite(lamp_start_pin, HIGH); +} + +void stop_vent_work() +{ + switch(all_byte_parameters[solarium_type]) + { + case LUXURA_SOL: + break; + case FIRESUN_UV_SOL: + digitalWrite(vent_pin, LOW); + break; + case FIRESUN_UV_K_SOL: + break; + case SUNFLOWER_SOL: + digitalWrite(vent_pin, LOW); + break; + } +} + /* Прием денег */ @@ -1063,8 +1170,10 @@ void get_money () need_clear_menu = true; need_reload_menu = true; - bill_enable =! bill_enable; // устанавливаем флаг: не принимаем деньги + bill_enable = !bill_enable; // устанавливаем флаг: не принимаем деньги + // Запускаем работу солярия + start_solarium_work(); } } } @@ -1094,9 +1203,20 @@ void menu() } if(all_byte_parameters[reset_device]) { - reset_parameter(); + if(enable_reset) reset_parameter(); all_byte_parameters[reset_device] = 0; } + if(all_byte_parameters[reset_counters]) + { + if(enable_reset) reset_short_counters(); + all_byte_parameters[reset_counters] = 0; + } + if(all_byte_parameters[password] == 22) + { + enable_reset = true; + all_byte_parameters[password] = 0; + save_byte_parameter(password); + } } lcd.clear(); @@ -1111,6 +1231,18 @@ void one_half_second() } +void restart_menu() +{ + memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); + sprintf(text_parameters[time_seance],""); + menu_index = 0; + + need_clear_menu = true; + need_reload_menu = true; + + bill_enable = !bill_enable; +} + /* Событие секунды */ @@ -1124,26 +1256,40 @@ void second_event() sprintf(text_parameters[time_seance]," %02d:%02d", minute, second); need_reload_menu = true; + if(menu_index == 4 && time_remain == 0) + { + restart_menu(); + } if(menu_index == 3 && time_remain == 0) { - memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); - sprintf(text_parameters[time_seance],""); - menu_index = 0; + stop_vent_work(); + + memcpy_P( ¤t_menu_screen, &menu_main[4], sizeof(menu_screen)); + menu_index = 4; + second = 10; need_clear_menu = true; need_reload_menu = true; - - bill_enable =! bill_enable; } if(menu_index == 2 && time_remain == 0) { - memcpy_P( ¤t_menu_screen, &menu_main[3], sizeof(menu_screen)); - menu_index = 3; + stop_solarium_work(); + + if(all_byte_parameters[solarium_type] == LUXURA_SOL) + { + memcpy_P( ¤t_menu_screen, &menu_main[4], sizeof(menu_screen)); + menu_index = 4; + second = 10; + } + else + { + memcpy_P( ¤t_menu_screen, &menu_main[3], sizeof(menu_screen)); + menu_index = 3; + minute = all_byte_parameters[pause_after] * 60; + } need_clear_menu = true; need_reload_menu = true; - - second = 10; } } @@ -1175,14 +1321,20 @@ void setup() pinMode(LEDPin, OUTPUT); // инициализируем пин, подключенный к светодиоду, как выход pinMode(buttonPin_Service, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход pinMode(buttonPin_Start, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход + pinMode(lamp_start_pin, OUTPUT); // управление лампами + pinMode(vent_pin, OUTPUT); // управление вентиляторами digitalWrite(LEDPin,LOW); // изначально светодиод погашен digitalWrite(inhibitPin, LOW); // изначально разрешаем прием купюр + digitalWrite(lamp_start_pin, LOW); // изначально выключен + digitalWrite(vent_pin, LOW); // изначально выключен load_parameter(); memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); sprintf(text_parameters[time_seance],""); menu_index = 0; + + all_long_parameters[money_counter] = 0; } void loop() From 08fea0bdfccb2ff04ae200e00ff3bc623192dfb3 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 17 Sep 2024 02:09:56 +0300 Subject: [PATCH 11/28] =?UTF-8?q?=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 07c5ab9..2d583d0 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -1241,6 +1241,8 @@ void restart_menu() need_reload_menu = true; bill_enable = !bill_enable; + + digitalWrite(inhibitPin, LOW); } /* From 00dd5c8d7a691973bd7f6c069a2e5199822c2cf2 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Wed, 18 Sep 2024 22:57:46 +0300 Subject: [PATCH 12/28] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B0=20=D1=80=D1=83=D1=81=D1=81=D0=BA=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 271 +++++++++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 84 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 2d583d0..25dfdfd 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -120,20 +120,7 @@ unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; #define time_seance 0 #define time_delay 1 #define COUNT_TEXT_PARAMETER 2 -char text_parameters[COUNT_TEXT_PARAMETER][20]; - -// ============================== Описываем свой символ "Рубль" ======================================================================== -// Просто "рисуем" символ единицами. Единицы при выводе на экран окажутся закрашенными точками, нули - не закрашенными -const byte rubl[8] = { - 0b00000, - 0b01110, - 0b01001, - 0b01001, - 0b01110, - 0b01000, - 0b11110, - 0b01000, -}; +char text_parameters[COUNT_TEXT_PARAMETER][SIZE_SCREEN_LINE]; LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки @@ -218,7 +205,7 @@ struct parameter_menu { struct parameter_digit { byte param_index; param_limit limit; - char unit[5]; + char unit[8]; }; struct parameter_list { @@ -235,7 +222,7 @@ struct parameter_header { struct parameter_text { byte param_index; param_limit limit; - char unit[5]; + char unit[8]; }; union param_data { @@ -247,7 +234,7 @@ union param_data { }; struct menu_line { - char string[SIZE_SCREEN_LINE]; + char string[SIZE_SCREEN_LINE * 2]; type_menu_line type; param_data parameter; @@ -274,7 +261,7 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " BHECEHO", + " ВНЕСЕНО", DIGIT_VIEW_LINE, { money_counter, @@ -282,7 +269,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - 0 + "руб" } }, { @@ -317,7 +304,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - "CEK" + "СЕК" }, }, }, @@ -345,7 +332,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - "MUH" + "МИН" } }, }, @@ -360,12 +347,12 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " PAUSE", + " ПАУЗА", FIXED_LINE, {0} }, { - "", + " ", TEXT_PARAM_LINE, { time_seance, @@ -388,7 +375,7 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " KOHEU", + " КОНЕЦ", FIXED_LINE, {0} }, @@ -405,17 +392,17 @@ const menu_screen menu_settings[] PROGMEM = { { { { - " MAIN MENU", + "ГЛАВНОЕ МЕНЮ", FIXED_LINE, {0} }, { - "Settings", + "Настройки", MENU_LINE, {SETTING_MENU} }, { - "Statistic", + "Статистика", MENU_LINE, {STATISTIC_MENU} } @@ -426,27 +413,27 @@ const menu_screen menu_settings[] PROGMEM = { { { { - " SETTINGS", + "НАСТРОЙКИ", FIXED_LINE, {0} }, { - "Solarium", + "Солярий", MENU_LINE, {SOLARIUM_MENU} }, { - "Bank", + "Банк", MENU_LINE, {BANK_MENU} }, { - "Password", + "Пароль", MENU_LINE, {PASSWORD_MENU} }, { - "Reset", + "Сброс", LIST_PARAM_LINE, { reset_device, @@ -456,7 +443,7 @@ const menu_screen menu_settings[] PROGMEM = { }, { " ", - "start" + "запуск" } } }, @@ -467,17 +454,17 @@ const menu_screen menu_settings[] PROGMEM = { { { { - " STATISTIC", + "СТАТИСТИКА", FIXED_LINE, {0} }, { - "Long counters", + "Длинные счетчики", MENU_LINE, {LONG_COUNTER_MENU} }, { - "Short counters", + "Короткие счетчики", MENU_LINE, {SHORT_COUNTER_MENU} } @@ -488,12 +475,12 @@ const menu_screen menu_settings[] PROGMEM = { { { { - " DEVICE", + "СОЛЯРИЙ", FIXED_LINE, {1} }, { - "Pause before", + "Пауза до", DIGIT_PARAM_LINE, { pause_before, @@ -501,11 +488,11 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - "sec" + "сек" } }, { - "Pause after", + "Пауза после", DIGIT_PARAM_LINE, { pause_after, @@ -513,11 +500,11 @@ const menu_screen menu_settings[] PROGMEM = { 0, 3, }, - "min" + "мин" } }, { - "Price", + "Цена", DIGIT_PARAM_LINE, { price, @@ -525,11 +512,11 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - 0 + "руб" } }, { - "Remote start", + "Удален.старт", LIST_PARAM_LINE, { remote_start, @@ -538,13 +525,13 @@ const menu_screen menu_settings[] PROGMEM = { 1, }, { - "Off", - "On " + "Вкл ", + "Выкл" } } }, { - "Type", + "Тип", LIST_PARAM_LINE, { solarium_type, @@ -561,7 +548,7 @@ const menu_screen menu_settings[] PROGMEM = { } }, { - "Regime", + "Режим", LIST_PARAM_LINE, { work_regime, @@ -576,7 +563,7 @@ const menu_screen menu_settings[] PROGMEM = { } }, { - "Signal", + "Реле", LIST_PARAM_LINE, { signal_rele, @@ -597,12 +584,12 @@ const menu_screen menu_settings[] PROGMEM = { { { { - " BANK", + "БАНК", FIXED_LINE, {0} }, { - "Rub/imp", + "Руб/имп", DIGIT_PARAM_LINE, { weight_impulse, @@ -620,12 +607,12 @@ const menu_screen menu_settings[] PROGMEM = { { { { - " PASSWORD", + "УСТАНОВКА ПАРОЛЯ", FIXED_LINE, {0} }, { - "Pasword", + "Пароль", DIGIT_PARAM_LINE, { password, @@ -643,12 +630,12 @@ const menu_screen menu_settings[] PROGMEM = { { { { - "LONG COUNTERS", + "ДЛИННЫЕ СЧЕТЧИКИ", FIXED_LINE, {0} }, { - "Starts", + "Запуски", DIGIT_VIEW_LINE, { long_starts_counter, @@ -660,7 +647,7 @@ const menu_screen menu_settings[] PROGMEM = { } }, { - "Money", + "Деньги", DIGIT_VIEW_LINE, { long_money_counter, @@ -668,11 +655,11 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - 0 + "руб" } }, { - "Time", + "Время", DIGIT_VIEW_LINE, { long_time_counter, @@ -680,7 +667,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - "sec" + "сек" } }, }, @@ -690,12 +677,12 @@ const menu_screen menu_settings[] PROGMEM = { { { { - "SHORT COUNTERS", + "КОРОТКИЕ СЧЕТЧИКИ", FIXED_LINE, {0} }, { - "Starts", + "Запуски", DIGIT_VIEW_LINE, { short_starts_counter, @@ -707,7 +694,7 @@ const menu_screen menu_settings[] PROGMEM = { } }, { - "Money", + "Деньги", DIGIT_VIEW_LINE, { short_money_counter, @@ -715,11 +702,11 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - 0 + "руб" } }, { - "Time", + "Время", DIGIT_VIEW_LINE, { short_time_counter, @@ -727,7 +714,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 0, }, - "sec" + "сек" } }, }, @@ -952,15 +939,15 @@ void show_line(byte index_line) { if(current_menu_screen.menu_lines[index_line].type == MENU_LINE) { - lcd.print(current_menu_screen.menu_lines[index_line].string); + lcd.print(convertCyr( utf8rus( current_menu_screen.menu_lines[index_line].string))); } else if(current_menu_screen.menu_lines[index_line].type == FIXED_LINE) { - lcd.print(current_menu_screen.menu_lines[index_line].string); + lcd.print(convertCyr( utf8rus( current_menu_screen.menu_lines[index_line].string))); } else if(current_menu_screen.menu_lines[index_line].type == DIGIT_PARAM_LINE) { - char line[21]; + char line[SIZE_SCREEN_LINE * 2]; char format[9] = "%s %d %s"; if(start_edit_parameter && index_line == current_line_index) { @@ -969,11 +956,11 @@ void show_line(byte index_line) sprintf(line,format, current_menu_screen.menu_lines[index_line].string, all_byte_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], current_menu_screen.menu_lines[index_line].parameter.digit.unit); - lcd.print(line); + lcd.print(convertCyr( utf8rus( line ))); } else if(current_menu_screen.menu_lines[index_line].type == LIST_PARAM_LINE) { - char line[21]; + char line[SIZE_SCREEN_LINE * 2]; char format[6] = "%s %s"; if(start_edit_parameter && index_line == current_line_index) { @@ -981,26 +968,23 @@ void show_line(byte index_line) } sprintf(line,format, current_menu_screen.menu_lines[index_line].string, current_menu_screen.menu_lines[index_line].parameter.list.list_data[all_byte_parameters[current_menu_screen.menu_lines[index_line].parameter.list.param_index]]); - lcd.print(line); + lcd.print(convertCyr( utf8rus( line ))); } else if(current_menu_screen.menu_lines[index_line].type == DIGIT_VIEW_LINE) { - char line[21]; + char line[SIZE_SCREEN_LINE * 2]; sprintf(line,"%s %ld %s", current_menu_screen.menu_lines[index_line].string, - all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], - current_menu_screen.menu_lines[index_line].parameter.digit.unit[0] >= 0x20 ? - current_menu_screen.menu_lines[index_line].parameter.digit.unit : - ""); - lcd.print(line); - current_menu_screen.menu_lines[index_line].parameter.digit.unit[0] < 0x20 ? lcd.write(0) : 0; + all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], + current_menu_screen.menu_lines[index_line].parameter.digit.unit); + lcd.print(convertCyr( utf8rus( line ))); } else if(current_menu_screen.menu_lines[index_line].type == TEXT_PARAM_LINE) { - char line[21]; + char line[SIZE_SCREEN_LINE * 2]; sprintf(line,"%s %s %s", current_menu_screen.menu_lines[index_line].string, text_parameters[current_menu_screen.menu_lines[index_line].parameter.text.param_index], current_menu_screen.menu_lines[index_line].parameter.text.unit); - lcd.print(line); + lcd.print(convertCyr( utf8rus( line ))); } } @@ -1125,12 +1109,15 @@ void get_money () remain = all_long_parameters[money_counter] % all_byte_parameters[price]; second = remain * 60 / all_byte_parameters[price]; - if(impulse) need_reload_menu = true; + if(impulse) + { + need_reload_menu = true; + } if (all_long_parameters[money_counter] >= all_byte_parameters[price]) { // достаточно денег для оказания услуги - sprintf(text_parameters[time_seance]," CEAHC %02d:%02d MUH", minute, second); + sprintf(text_parameters[time_seance],"СЕАНС %02d:%02d МИН", minute, second); digitalWrite(LEDPin, HIGH); // зажигаем светодиод @@ -1287,7 +1274,7 @@ void second_event() { memcpy_P( ¤t_menu_screen, &menu_main[3], sizeof(menu_screen)); menu_index = 3; - minute = all_byte_parameters[pause_after] * 60; + minute = all_byte_parameters[pause_after]; } need_clear_menu = true; @@ -1316,7 +1303,6 @@ void setup() lcd.init(); // инициализация LCD lcd.backlight(); // включаем подсветку - lcd.createChar(0, rubl); // создаем символ и записываем его в память LCD по 0 адресу pinMode(inhibitPin, OUTPUT); // устанавливает режим работы - выход pinMode(moneyPin, INPUT_PULLUP); // устанавливает режим работы - вход, подтягиваем к +5В через встроенный подтягивающий резистор (на всякий случай) @@ -1373,3 +1359,120 @@ void loop() countdown_timer(); // запускаем таймер обратного отсчета } } + +String utf8rus(String source) { + int i,k; + String target; + unsigned char n; + char m[2] = { '0', '\0' }; + + k = source.length(); i = 0; + + while (i < k) { + n = source[i]; i++; + + if (n >= 0xC0) { + switch (n) { + case 0xD0: { + n = source[i]; i++; + if (n == 0x81) { n = 0xA8; break; } + if (n >= 0x90 && n <= 0xBF) n = n + 0x30; + break; + } + case 0xD1: { + n = source[i]; i++; + if (n == 0x91) { n = 0xB8; break; } + if (n >= 0x80 && n <= 0x8F) n = n + 0x70; + break; + } + } + } + m[0] = n; target = target + String(m); + } + return target; +} + +String convertCyr( const String &s ){ + String target = s; + for( int idx = 0; idx Date: Wed, 18 Sep 2024 23:56:06 +0300 Subject: [PATCH 13/28] =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 25dfdfd..8006a5a 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -8,6 +8,9 @@ // ===============================задаем константы ========================================================================= const byte moneyPin = 2; // номер пина, к которому подключён купюроприемник, DB2 const byte inhibitPin = 4; // +Inhibit (зеленый) на купюроприемник, DB4 +//const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 +//const byte buttonPin_Service = 14; // номер входа, подключенный к кнопке "Сервис", А1 +//const byte LEDPin = 13; // номер выхода светодиода кнопки Старт, DB13 const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 const byte buttonPin_Service = 13; // номер входа, подключенный к кнопке "Сервис", А1 const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 @@ -442,7 +445,7 @@ const menu_screen menu_settings[] PROGMEM = { 1, }, { - " ", + " ", "запуск" } } @@ -467,9 +470,24 @@ const menu_screen menu_settings[] PROGMEM = { "Короткие счетчики", MENU_LINE, {SHORT_COUNTER_MENU} - } + }, + { + "Сброс", + LIST_PARAM_LINE, + { + reset_counters, + { + 0, + 1, + }, + { + " ", + "запуск" + } + } + }, }, - 3 + 4 }, // Меню 3 { @@ -525,8 +543,8 @@ const menu_screen menu_settings[] PROGMEM = { 1, }, { - "Вкл ", - "Выкл" + "Выкл", + "Вкл " } } }, From 7ff4431a9742d92d372fd80c0eb7549813256dc5 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Mon, 23 Sep 2024 23:46:00 +0300 Subject: [PATCH 14/28] =?UTF-8?q?=D0=A3=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D1=81=D0=B5=D0=B0=D0=BD=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 85 ++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 21 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 8006a5a..0544c39 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -18,7 +18,7 @@ const byte LEDPin = 14; // номер выхода // ноги управления соляриями const byte lamp_start_pin = 5; // Запуск солярия Luxura. Включение ламп солярия FireSun, SunFlower const byte vent_pin = 6; // Включение вентиляторов солярия FireSun, SunFlower -const byte start_solarium = 7; // Удаленный старт от солярия +const byte start_solarium_pin = 7; // Удаленный старт от солярия, DB7 const byte Device_SerNum = 1; // серийный номер устройства const PROGMEM char Device_Ver[] = "0.0"; // версия ПО устройства @@ -251,6 +251,13 @@ struct menu_screen { // текущее меню menu_screen current_menu_screen; +#define WAIT_MONEY 0 +#define WAIT_BEFORE 1 +#define SEANCE_SCREEN 2 +#define WAIT_AFTER 3 +#define SCREEN_END 4 +#define SCREEN_START_SOL 5 + /* Описание основного меню */ @@ -385,6 +392,22 @@ const menu_screen menu_main[] PROGMEM = { }, 2 }, + // Удаленный запуск + { + { + { + "", + FIXED_LINE, + {0} + }, + { + "ОТЛОЖЕННЫЙ СТАРТ", + FIXED_LINE, + {0} + }, + }, + 2 + }, }; /* @@ -534,7 +557,7 @@ const menu_screen menu_settings[] PROGMEM = { } }, { - "Удален.старт", + "Отложен.старт", LIST_PARAM_LINE, { remote_start, @@ -1162,14 +1185,33 @@ void get_money () save_long_parameter(money_counter); } - // задержка до запуска - memcpy_P( ¤t_menu_screen, &menu_main[1], sizeof(menu_screen)); - sprintf(text_parameters[time_delay],"%2d", all_byte_parameters[pause_before]); - lcd.clear(); - show_menu(); - delay(all_byte_parameters[pause_before] * 1000); + if(all_byte_parameters[remote_start]) + { + // удаленный старт кнопкой + memcpy_P( ¤t_menu_screen, &menu_main[SCREEN_START_SOL], sizeof(menu_screen)); + lcd.clear(); + show_menu(); - memcpy_P( ¤t_menu_screen, &menu_main[2], sizeof(menu_screen)); + while(1) + { + if (digitalRead(start_solarium_pin) == LOW) + { + break; + } + delay(1); + } + } + else + { + // задержка до запуска + memcpy_P( ¤t_menu_screen, &menu_main[WAIT_BEFORE], sizeof(menu_screen)); + sprintf(text_parameters[time_delay],"%2d", all_byte_parameters[pause_before]); + lcd.clear(); + show_menu(); + delay(all_byte_parameters[pause_before] * 1000); + } + + memcpy_P( ¤t_menu_screen, &menu_main[SEANCE_SCREEN], sizeof(menu_screen)); menu_index = 2; sprintf(text_parameters[time_seance]," %02d:%02d", minute, second); need_clear_menu = true; @@ -1238,7 +1280,7 @@ void one_half_second() void restart_menu() { - memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); + memcpy_P( ¤t_menu_screen, &menu_main[WAIT_MONEY], sizeof(menu_screen)); sprintf(text_parameters[time_seance],""); menu_index = 0; @@ -1263,35 +1305,35 @@ void second_event() sprintf(text_parameters[time_seance]," %02d:%02d", minute, second); need_reload_menu = true; - if(menu_index == 4 && time_remain == 0) + if(menu_index == SCREEN_END && time_remain == 0) { restart_menu(); } - if(menu_index == 3 && time_remain == 0) + if(menu_index == WAIT_AFTER && time_remain == 0) { stop_vent_work(); - memcpy_P( ¤t_menu_screen, &menu_main[4], sizeof(menu_screen)); - menu_index = 4; + memcpy_P( ¤t_menu_screen, &menu_main[SCREEN_END], sizeof(menu_screen)); + menu_index = SCREEN_END; second = 10; need_clear_menu = true; need_reload_menu = true; } - if(menu_index == 2 && time_remain == 0) + if(menu_index == SEANCE_SCREEN && time_remain == 0) { stop_solarium_work(); if(all_byte_parameters[solarium_type] == LUXURA_SOL) { - memcpy_P( ¤t_menu_screen, &menu_main[4], sizeof(menu_screen)); - menu_index = 4; + memcpy_P( ¤t_menu_screen, &menu_main[SCREEN_END], sizeof(menu_screen)); + menu_index = SCREEN_END; second = 10; } else { - memcpy_P( ¤t_menu_screen, &menu_main[3], sizeof(menu_screen)); - menu_index = 3; + memcpy_P( ¤t_menu_screen, &menu_main[WAIT_AFTER], sizeof(menu_screen)); + menu_index = WAIT_AFTER; minute = all_byte_parameters[pause_after]; } @@ -1329,6 +1371,7 @@ void setup() pinMode(buttonPin_Start, INPUT_PULLUP); // инициализируем пин, подключенный к кнопке, как вход pinMode(lamp_start_pin, OUTPUT); // управление лампами pinMode(vent_pin, OUTPUT); // управление вентиляторами + pinMode(start_solarium_pin, INPUT_PULLUP); // удаленный старт солярия digitalWrite(LEDPin,LOW); // изначально светодиод погашен digitalWrite(inhibitPin, LOW); // изначально разрешаем прием купюр @@ -1336,7 +1379,7 @@ void setup() digitalWrite(vent_pin, LOW); // изначально выключен load_parameter(); - memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); + memcpy_P( ¤t_menu_screen, &menu_main[WAIT_MONEY], sizeof(menu_screen)); sprintf(text_parameters[time_seance],""); menu_index = 0; @@ -1353,7 +1396,7 @@ void loop() { menu(); need_reload_menu = true; - memcpy_P( ¤t_menu_screen, &menu_main[0], sizeof(menu_screen)); + memcpy_P( ¤t_menu_screen, &menu_main[WAIT_MONEY], sizeof(menu_screen)); } else { From c85da270c25749ee31158755186436b71e32eb0f Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 24 Sep 2024 00:28:20 +0300 Subject: [PATCH 15/28] =?UTF-8?q?=D0=A3=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BE=D0=BB=D1=8F=D1=80=D0=B8?= =?UTF-8?q?=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 71 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 0544c39..7467440 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -87,6 +87,11 @@ bool enable_reset = false; // разрешение сб #define SUNFLOWER_SOL 3 #define solarium_type 4 + +#define UV_REGIME 0 +#define COLLATEN_REGIME 1 +#define UV_COLLATEN_REGIME 2 + #define work_regime 5 #define signal_rele 6 #define weight_impulse 7 @@ -599,7 +604,8 @@ const menu_screen menu_settings[] PROGMEM = { }, { "Kollaten", - "UV " + "UV ", + "UV+Koll " } } }, @@ -1096,44 +1102,85 @@ bool read_money_impulse () return impulse; } +/* + Запуск работы соляриев +*/ void start_solarium_work() { - if(all_byte_parameters[signal_rele]) digitalWrite(lamp_start_pin, HIGH); - else digitalWrite(lamp_start_pin, LOW); - switch(all_byte_parameters[solarium_type]) { case LUXURA_SOL: + if(all_byte_parameters[signal_rele]) digitalWrite(lamp_start_pin, HIGH); + else digitalWrite(lamp_start_pin, LOW); break; case FIRESUN_UV_SOL: digitalWrite(vent_pin, HIGH); + digitalWrite(lamp_start_pin, HIGH); + delay(500); + digitalWrite(lamp_start_pin, LOW); + delay(1000); break; case FIRESUN_UV_K_SOL: + digitalWrite(vent_pin, HIGH); + digitalWrite(lamp_start_pin, HIGH); + switch(all_byte_parameters[work_regime]) + { + case UV_REGIME: + delay(500); + digitalWrite(lamp_start_pin, LOW); + delay(1000); + break; + case COLLATEN_REGIME: + delay(500); + digitalWrite(lamp_start_pin, LOW); + delay(500); + digitalWrite(lamp_start_pin, HIGH); + delay(500); + digitalWrite(lamp_start_pin, LOW); + delay(500); + break; + case UV_COLLATEN_REGIME: + delay(500); + digitalWrite(lamp_start_pin, LOW); + delay(500); + break; + } + digitalWrite(lamp_start_pin, HIGH); break; case SUNFLOWER_SOL: digitalWrite(vent_pin, HIGH); + digitalWrite(lamp_start_pin, HIGH); break; } } +/* + Остановка ламп соляриев +*/ void stop_solarium_work() { - if(all_byte_parameters[signal_rele]) digitalWrite(lamp_start_pin, LOW); - else digitalWrite(lamp_start_pin, HIGH); + switch(all_byte_parameters[solarium_type]) + { + case LUXURA_SOL: + if(all_byte_parameters[signal_rele]) digitalWrite(lamp_start_pin, LOW); + else digitalWrite(lamp_start_pin, HIGH); + break; + default: + digitalWrite(lamp_start_pin, LOW); + break; + } } +/* + Остановка вентилятора +*/ void stop_vent_work() { switch(all_byte_parameters[solarium_type]) { case LUXURA_SOL: break; - case FIRESUN_UV_SOL: - digitalWrite(vent_pin, LOW); - break; - case FIRESUN_UV_K_SOL: - break; - case SUNFLOWER_SOL: + default: digitalWrite(vent_pin, LOW); break; } From c2072b26f94812b667fe1cadf3c9c50ae5bd9d30 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 19 Nov 2024 02:11:11 +0300 Subject: [PATCH 16/28] =?UTF-8?q?=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=BB=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=BA=D0=BD=D0=BE=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=20=D0=B2=20=D0=BC=D0=B5=D0=BD=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 160 +++++++++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 57 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 7467440..aabe007 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -26,13 +26,12 @@ const PROGMEM char Device_Date[] = "09/09/24"; // дата производ const unsigned long block = 500000; // блокировка устройства при превышении этой суммы денег //======Переменные обработки клавиш================= -boolean lastReading = false; // флаг предыдущего состояния кнопки -boolean buttonSingle = false; // флаг состояния "краткое нажатие" -boolean buttonDouble = false; // флаг состояния "двойное нажатие" -boolean buttonHold = false; // флаг состояния "долгое нажатие" -unsigned long onTime = 0; // переменная обработки временного интервала -unsigned long lastSwitchTime = 0; // переменная времени предыдущего переключения состояния -unsigned long ledStartTime = 0; // переменная-флаг времени начала включения LED +boolean lastReading[2] = {false, false}; // флаг предыдущего состояния кнопки +boolean buttonSingle[2] = {false, false}; // флаг состояния "краткое нажатие" +boolean buttonDouble[2] = {false, false}; // флаг состояния "двойное нажатие" +boolean buttonHold[2] = {false, false}; // флаг состояния "долгое нажатие" +unsigned long onTime[2] = {0, 0}; // переменная обработки временного интервала +unsigned long lastSwitchTime[2] = {0, 0}; // переменная времени предыдущего переключения состояния const int bounceTime = 10; // задержка для подавления дребезга const int holdTime = 1000; // время, в течение которого нажатие можно считать удержанием кнопки @@ -135,50 +134,56 @@ LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // void read_buttons(byte x) { boolean reading = !digitalRead(x); + int index = (x == buttonPin_Service ? 0 : 1); - if (reading && !lastReading) // проверка первичного нажатия + if (reading && !lastReading[index]) // проверка первичного нажатия { - onTime = millis(); + onTime[index] = millis(); + !index ? Serial.println("click button Service") : Serial.println("click button Start"); } - if (reading && lastReading) // проверка удержания + if (reading && lastReading[index]) // проверка удержания { - if ((millis() - onTime) > holdTime) + if ((millis() - onTime[index]) > holdTime) { - buttonHold = true; + buttonHold[index] = true; + !index ? Serial.println("buttonHold Service") : Serial.println("buttonHold Start"); digitalWrite(LEDPin, !digitalRead(LEDPin)); // при удержании кнопки мигает светодиод + isButtonHoldRepeate(x); } } - if (!reading && lastReading) // проверка отпускания кнопки + if (!reading && lastReading[index]) // проверка отпускания кнопки { - if (((millis() - onTime) > bounceTime) && !buttonHold) + if (((millis() - onTime[index]) > bounceTime) && !buttonHold[index]) { - if ((millis() - lastSwitchTime) >= doubleTime) + if ((millis() - lastSwitchTime[index]) >= doubleTime) { - lastSwitchTime = millis(); - buttonSingle = true; + lastSwitchTime[index] = millis(); + buttonSingle[index] = true; + !index ? Serial.println("buttonSingle Service") : Serial.println("buttonSingle Start"); } else { - lastSwitchTime = millis(); - buttonDouble = true; - buttonSingle = false; - isButtonDouble(); - buttonDouble = false; // сброс состояния после выполнения команды + lastSwitchTime[index] = millis(); + buttonDouble[index] = true; + !index ? Serial.println("buttonDouble Service") : Serial.println("buttonDouble Start"); + buttonSingle[index] = false; + buttonDouble[index] = false; // сброс состояния после выполнения команды + isButtonDouble(x); } } - if (buttonHold) + if (buttonHold[index]) { - buttonDouble = false; - isButtonHold(); - buttonHold = false; // сброс состояния после выполнения команды + buttonDouble[index] = false; + buttonHold[index] = false; // сброс состояния после выполнения команды + isButtonHold(x); } } - lastReading = reading; - if (buttonSingle && (millis() - lastSwitchTime) > doubleTime) + lastReading[index] = reading; + if (buttonSingle[index] && (millis() - lastSwitchTime[index]) > doubleTime) { - buttonDouble = false; - isButtonSingle(); - buttonSingle = false; // сброс состояния после выполнения команды + buttonDouble[index] = false; + buttonSingle[index] = false; // сброс состояния после выполнения команды + isButtonSingle(x); } } @@ -219,7 +224,7 @@ struct parameter_digit { struct parameter_list { byte param_index; param_limit limit; - char list_data[4][13]; + char list_data[4][11]; }; struct parameter_header { @@ -586,10 +591,10 @@ const menu_screen menu_settings[] PROGMEM = { 3, }, { - "Luxura ", - "FireSun UV ", - "FireSun UV+K", - "SunFlower " + "Luxura ", + "FS UV ", + "FS UV+K ", + "SunFlower" } } }, @@ -857,13 +862,50 @@ void reset_short_counters() save_long_parameter(short_time_counter); } +/* + удержание кнопки на повторе +*/ +void isButtonHoldRepeate(byte x) +{ + need_reload_menu = true; + + if(x == buttonPin_Start) + { + if(start_edit_parameter) + { + Serial.println("isButtonHoldRepeate"); + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) + { + if(all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.max) + { + all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.digit.limit.min; + } + } + else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + { + if(all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index]++ >= current_menu_screen.menu_lines[current_line_index].parameter.list.limit.max) + { + all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.list.limit.min; + } + } + } + + return; + } +} + /* удержание кнопки */ -void isButtonHold() +void isButtonHold(byte x) { need_reload_menu = true; + if(x == buttonPin_Start) + { + return; + } + if(!menu_enable) { menu_index = MAIN_MENU; @@ -875,20 +917,7 @@ void isButtonHold() } else { - if(start_edit_parameter) - { - start_edit_parameter = false; - need_hide_cursor = false; - if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) - { - save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); - } - else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) - { - save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); - } - } - else + if(!start_edit_parameter) { if(menu_index == MAIN_MENU) { @@ -912,11 +941,11 @@ void isButtonHold() /* одиночное нажатие кнопки */ -void isButtonSingle() +void isButtonSingle(byte x) { need_reload_menu = true; - if(start_edit_parameter) + if(start_edit_parameter && (x == buttonPin_Start || x == buttonPin_Service)) { if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) { @@ -933,7 +962,7 @@ void isButtonSingle() } } } - else + else if(x == buttonPin_Service) { last_cursor_index = cursor_index; cursor_index++; @@ -956,10 +985,14 @@ void isButtonSingle() /* двойное нажатие кнопки */ -void isButtonDouble() +void isButtonDouble(byte x) { need_reload_menu = true; + if(x == buttonPin_Start) { + return; + } + if(current_menu_screen.menu_lines[current_line_index].type == MENU_LINE) { last_menu_index[menu_inter] = menu_index; @@ -978,6 +1011,17 @@ void isButtonDouble() start_edit_parameter = true; hide_cursor(); need_hide_cursor = true; + } else { + start_edit_parameter = false; + need_hide_cursor = false; + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) + { + save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + } + else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + { + save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); + } } } } @@ -995,7 +1039,7 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == DIGIT_PARAM_LINE) { char line[SIZE_SCREEN_LINE * 2]; - char format[9] = "%s %d %s"; + char format[11] = "%s %d %s "; if(start_edit_parameter && index_line == current_line_index) { format[2] = '>'; @@ -1008,7 +1052,7 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == LIST_PARAM_LINE) { char line[SIZE_SCREEN_LINE * 2]; - char format[6] = "%s %s"; + char format[8] = "%s %s "; if(start_edit_parameter && index_line == current_line_index) { format[2] = '>'; @@ -1283,6 +1327,7 @@ void menu() while (menu_enable == true) { read_buttons(buttonPin_Service); + read_buttons(buttonPin_Start); if(need_clear_menu) { @@ -1436,6 +1481,7 @@ void setup() void loop() { read_buttons(buttonPin_Service); + read_buttons(buttonPin_Start); hide_cursor(); need_hide_cursor = true; From e5d412ca6a9db5e017cf82b29572c39231dd842e Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Wed, 20 Nov 2024 02:42:38 +0300 Subject: [PATCH 17/28] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BD=D0=B0=D0=B4=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B0=D0=BC=D0=B8=20-=20=D0=B2=D0=B2=D0=B5=D0=BB=20?= =?UTF-8?q?=D0=B2=D0=B2=D0=BE=D0=B4=20=D0=BF=D0=B0=D1=80=D0=BE=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 382 +++++++++++++++++++++++++++++------------- 1 file changed, 261 insertions(+), 121 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index aabe007..eb17b98 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -66,6 +66,7 @@ byte last_menu_index[MENU_INTER_COUNT]; // стек переходо byte current_line_index = 1; // текущая выбранная строка меню byte cursor_index = 1; // положение курсора на экране byte last_cursor_index = 0; // предпоследнее положение курсора на экране +byte last_menu_cursor_index[MENU_INTER_COUNT]; // положение курсора на экране c предыдущего экрана byte show_window_first_line = 0; // индекс первой отображаемой строки меню на экране boolean need_reload_menu = true; // флаг перерисовки экрана boolean need_clear_menu = false; // флаг очистки экрана @@ -96,8 +97,7 @@ bool enable_reset = false; // разрешение сб #define weight_impulse 7 #define reset_device 8 #define reset_counters 9 -#define password 10 -#define COUNT_BYTE_PARAMETER 11 +#define COUNT_BYTE_PARAMETER 10 byte all_byte_parameters[COUNT_BYTE_PARAMETER]; const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { @@ -111,7 +111,6 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { 10, 0, 0, - 0, }; #define long_starts_counter 0 @@ -121,7 +120,8 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { #define short_money_counter 4 #define short_time_counter 5 #define money_counter 6 -#define COUNT_LONG_PARAMETER 7 +#define password 7 +#define COUNT_LONG_PARAMETER 8 unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; #define time_seance 0 @@ -187,14 +187,18 @@ void read_buttons(byte x) } } -#define MAIN_MENU 0 -#define SETTING_MENU 1 -#define STATISTIC_MENU 2 -#define SOLARIUM_MENU 3 -#define BANK_MENU 4 -#define PASSWORD_MENU 5 -#define LONG_COUNTER_MENU 6 -#define SHORT_COUNTER_MENU 7 +#define MAIN_MENU 0 +#define SETTING_MENU 1 +#define STATISTIC_MENU 2 +#define SOLARIUM_MENU_PAUSE 3 +#define BANK_MENU 4 +#define PASSWORD_MENU 5 +#define LONG_COUNTER_MENU 6 +#define SHORT_COUNTER_MENU 7 +#define SOLARIUM_MENU 8 +#define SOLARIUM_MENU_PAY 9 +#define SOLARIUM_MENU_DEV 10 +#define RESET_MENU 11 enum type_menu_line { MENU_LINE = 0, @@ -204,6 +208,8 @@ enum type_menu_line { LIST_PARAM_LINE, TEXT_PARAM_LINE, DIGIT_VIEW_LINE, + PASSWORD_SET_LINE, + PASSWORD_VERIFY_LINE, }; struct param_limit { @@ -254,7 +260,7 @@ struct menu_line { }; struct menu_screen { - menu_line menu_lines[8]; + menu_line menu_lines[5]; byte count_lines; }; @@ -469,19 +475,9 @@ const menu_screen menu_settings[] PROGMEM = { {PASSWORD_MENU} }, { - "Сброс", - LIST_PARAM_LINE, - { - reset_device, - { - 0, - 1, - }, - { - " ", - "запуск" - } - } + "Сброс настроек", + MENU_LINE, + {RESET_MENU} }, }, 5 @@ -505,7 +501,7 @@ const menu_screen menu_settings[] PROGMEM = { {SHORT_COUNTER_MENU} }, { - "Сброс", + "Обнуление", LIST_PARAM_LINE, { reset_counters, @@ -526,12 +522,12 @@ const menu_screen menu_settings[] PROGMEM = { { { { - "СОЛЯРИЙ", + "COЛЯРИЙ ПАУЗА", FIXED_LINE, {1} }, { - "Пауза до", + "Пaузa дo", DIGIT_PARAM_LINE, { pause_before, @@ -543,7 +539,7 @@ const menu_screen menu_settings[] PROGMEM = { } }, { - "Пауза после", + "Пaузa пocлe", DIGIT_PARAM_LINE, { pause_after, @@ -551,86 +547,11 @@ const menu_screen menu_settings[] PROGMEM = { 0, 3, }, - "мин" - } - }, - { - "Цена", - DIGIT_PARAM_LINE, - { - price, - { - 0, - 100, - }, - "руб" - } - }, - { - "Отложен.старт", - LIST_PARAM_LINE, - { - remote_start, - { - 0, - 1, - }, - { - "Выкл", - "Вкл " - } - } - }, - { - "Тип", - LIST_PARAM_LINE, - { - solarium_type, - { - 0, - 3, - }, - { - "Luxura ", - "FS UV ", - "FS UV+K ", - "SunFlower" - } - } - }, - { - "Режим", - LIST_PARAM_LINE, - { - work_regime, - { - 0, - 1, - }, - { - "Kollaten", - "UV ", - "UV+Koll " - } - } - }, - { - "Реле", - LIST_PARAM_LINE, - { - signal_rele, - { - 0, - 1, - }, - { - "high", - "low " - } + "mин" } }, }, - 8 + 3 }, // Меню 4 { @@ -659,18 +580,18 @@ const menu_screen menu_settings[] PROGMEM = { { { { - "УСТАНОВКА ПАРОЛЯ", + "ПАРОЛЬ", FIXED_LINE, {0} }, { - "Пароль", - DIGIT_PARAM_LINE, + "", + PASSWORD_SET_LINE, { password, { 0, - 255, + 9999, }, " " } @@ -772,6 +693,152 @@ const menu_screen menu_settings[] PROGMEM = { }, 4 }, + // Меню 8 + { + { + { + "COЛЯРИЙ", + FIXED_LINE, + {1} + }, + { + "Пауза", + MENU_LINE, + {SOLARIUM_MENU_PAUSE} + }, + { + "Цена", + MENU_LINE, + {SOLARIUM_MENU_PAY} + }, + { + "Доп.настройки", + MENU_LINE, + {SOLARIUM_MENU_DEV} + }, + }, + 4 + }, + // Меню 9 + { + { + { + "COЛЯРИЙ ЦЕНА", + FIXED_LINE, + {1} + }, + { + "Цeнa", + DIGIT_PARAM_LINE, + { + price, + { + 0, + 100, + }, + "руб" + } + }, + }, + 2 + }, + // Меню 10 + { + { + { + "ДОП.НАСТРОЙКИ", + FIXED_LINE, + {1} + }, + { + "Отложен.старт", + LIST_PARAM_LINE, + { + remote_start, + { + 0, + 1, + }, + { + "Выкл", + "Вкл " + } + } + }, + { + "Тип", + LIST_PARAM_LINE, + { + solarium_type, + { + 0, + 3, + }, + { + "Luxura ", + "FS UV ", + "FS UV+K ", + "SunFlower" + } + } + }, + { + "Режим", + LIST_PARAM_LINE, + { + work_regime, + { + 0, + 1, + }, + { + "Kollaten", + "UV ", + "UV+Koll " + } + } + }, + { + "Реле", + LIST_PARAM_LINE, + { + signal_rele, + { + 0, + 1, + }, + { + "high", + "low " + } + } + }, + }, + 5 + }, + // Меню 11 + { + { + { + "", + FIXED_LINE, + {1} + }, + { + "", + PASSWORD_VERIFY_LINE, + { + password, + { + 0, + 9999, + }, + "" + } + }, + }, + 2 + }, }; void find_first_line_menu() @@ -862,6 +929,12 @@ void reset_short_counters() save_long_parameter(short_time_counter); } +// временный пароль для проверки +unsigned long temp_password = 0; +// уровень проверки пароля +byte password_stage = 0; +// текущая редактируемая цифра пароля +int current_digit = 0; /* удержание кнопки на повторе */ @@ -929,7 +1002,10 @@ void isButtonHold(byte x) menu_index = last_menu_index[menu_inter]; memcpy_P( ¤t_menu_screen, &menu_settings[menu_index], sizeof(menu_screen)); - find_first_line_menu(); + + cursor_index = (last_menu_cursor_index[menu_inter] >= SIZE_SCREEN ) ? SIZE_SCREEN - 1 : last_menu_cursor_index[menu_inter]; + current_line_index = last_menu_cursor_index[menu_inter]; + show_window_first_line = 0; digitalWrite(LEDPin, HIGH); lcd.clear(); @@ -961,6 +1037,24 @@ void isButtonSingle(byte x) all_byte_parameters[current_menu_screen.menu_lines[current_line_index].parameter.list.param_index] = current_menu_screen.menu_lines[current_line_index].parameter.list.limit.min; } } + + if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE + || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) + { + if(x == buttonPin_Service) + { + byte dig = current_digit - 1; + int scale = 1; + + while(dig--) { scale *= 10; } + + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] += scale; + } + else + { + if(--current_digit == 0) { current_digit = 4; } + } + } } else if(x == buttonPin_Service) { @@ -996,6 +1090,7 @@ void isButtonDouble(byte x) if(current_menu_screen.menu_lines[current_line_index].type == MENU_LINE) { last_menu_index[menu_inter] = menu_index; + last_menu_cursor_index[menu_inter] = current_line_index; menu_inter++; menu_index = current_menu_screen.menu_lines[current_line_index].parameter.menu.next_menu_index; @@ -1004,10 +1099,29 @@ void isButtonDouble(byte x) lcd.clear(); } else if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE - || current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + || current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE + || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE + || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) { if(!start_edit_parameter) { + if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE) + { + temp_password = all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]; + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; + + password_stage = 0; + current_digit = 4; + } + else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) + { + temp_password = all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]; + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; + + password_stage = 0; + current_digit = 4; + } + start_edit_parameter = true; hide_cursor(); need_hide_cursor = true; @@ -1022,6 +1136,10 @@ void isButtonDouble(byte x) { save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); } + else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE) + { + save_long_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + } } } } @@ -1049,6 +1167,34 @@ void show_line(byte index_line) current_menu_screen.menu_lines[index_line].parameter.digit.unit); lcd.print(convertCyr( utf8rus( line ))); } + else if(current_menu_screen.menu_lines[index_line].type == PASSWORD_SET_LINE) + { + char line[SIZE_SCREEN_LINE * 2]; + if(start_edit_parameter && index_line == current_line_index) + { + char format[6] = "%04ld"; + sprintf(line,format, all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index]); + } + else + { + sprintf(line,"****"); + } + lcd.print(convertCyr( utf8rus( line ))); + } + else if(current_menu_screen.menu_lines[index_line].type == PASSWORD_VERIFY_LINE) + { + char line[SIZE_SCREEN_LINE * 2]; + if(start_edit_parameter && index_line == current_line_index) + { + char format[8] = "%s%04ld"; + sprintf(line,format, " ", all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index]); + } + else + { + sprintf(line," 0000"); + } + lcd.print(convertCyr( utf8rus( line ))); + } else if(current_menu_screen.menu_lines[index_line].type == LIST_PARAM_LINE) { char line[SIZE_SCREEN_LINE * 2]; @@ -1064,8 +1210,8 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == DIGIT_VIEW_LINE) { char line[SIZE_SCREEN_LINE * 2]; - sprintf(line,"%s %ld %s", current_menu_screen.menu_lines[index_line].string, - all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], + sprintf(line,"%s %ld %s", current_menu_screen.menu_lines[index_line].string, + all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], current_menu_screen.menu_lines[index_line].parameter.digit.unit); lcd.print(convertCyr( utf8rus( line ))); } @@ -1350,12 +1496,6 @@ void menu() if(enable_reset) reset_short_counters(); all_byte_parameters[reset_counters] = 0; } - if(all_byte_parameters[password] == 22) - { - enable_reset = true; - all_byte_parameters[password] = 0; - save_byte_parameter(password); - } } lcd.clear(); From 27c33b2fe2587b885636859526afd89f279304ed Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 21 Nov 2024 00:33:41 +0300 Subject: [PATCH 18/28] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D0=BF=D0=B0=D1=80=D0=BE=D0=BB=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 179 ++++++++++++++++++++++++++++++++---------- 1 file changed, 139 insertions(+), 40 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index eb17b98..2ee9d5f 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -73,8 +73,6 @@ boolean need_clear_menu = false; // флаг очистки boolean need_hide_cursor = false; // флаг скытия курсора на экране boolean start_edit_parameter = false; // флаг старта редактирования параметра -bool enable_reset = false; // разрешение сброса настроек - // Переменные для работы с соляриями #define pause_before 0 #define pause_after 1 @@ -95,9 +93,7 @@ bool enable_reset = false; // разрешение сб #define work_regime 5 #define signal_rele 6 #define weight_impulse 7 -#define reset_device 8 -#define reset_counters 9 -#define COUNT_BYTE_PARAMETER 10 +#define COUNT_BYTE_PARAMETER 8 byte all_byte_parameters[COUNT_BYTE_PARAMETER]; const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { @@ -109,8 +105,6 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { 0, 0, 10, - 0, - 0, }; #define long_starts_counter 0 @@ -125,9 +119,10 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; #define time_seance 0 -#define time_delay 1 -#define COUNT_TEXT_PARAMETER 2 -char text_parameters[COUNT_TEXT_PARAMETER][SIZE_SCREEN_LINE]; +#define time_delay 0 +#define stage_password 0 +#define COUNT_TEXT_PARAMETER 1 +char text_parameters[COUNT_TEXT_PARAMETER][SIZE_SCREEN_LINE*2]; LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки @@ -198,7 +193,8 @@ void read_buttons(byte x) #define SOLARIUM_MENU 8 #define SOLARIUM_MENU_PAY 9 #define SOLARIUM_MENU_DEV 10 -#define RESET_MENU 11 +#define RESET_DEVICE_MENU 11 +#define RESET_COUNTER_MENU 12 enum type_menu_line { MENU_LINE = 0, @@ -477,7 +473,7 @@ const menu_screen menu_settings[] PROGMEM = { { "Сброс настроек", MENU_LINE, - {RESET_MENU} + {RESET_DEVICE_MENU} }, }, 5 @@ -502,18 +498,8 @@ const menu_screen menu_settings[] PROGMEM = { }, { "Обнуление", - LIST_PARAM_LINE, - { - reset_counters, - { - 0, - 1, - }, - { - " ", - "запуск" - } - } + MENU_LINE, + {RESET_COUNTER_MENU} }, }, 4 @@ -596,8 +582,20 @@ const menu_screen menu_settings[] PROGMEM = { " " } }, + { + "", + TEXT_PARAM_LINE, + { + stage_password, + { + 0, + 0, + }, + "" + }, + }, }, - 2 + 3 }, // Меню 6 { @@ -836,8 +834,55 @@ const menu_screen menu_settings[] PROGMEM = { "" } }, + { + "", + TEXT_PARAM_LINE, + { + stage_password, + { + 0, + 0, + }, + "" + }, + }, }, - 2 + 3 + }, + // Меню 12 + { + { + { + "", + FIXED_LINE, + {1} + }, + { + "", + PASSWORD_VERIFY_LINE, + { + password, + { + 0, + 9999, + }, + "" + } + }, + { + "", + TEXT_PARAM_LINE, + { + stage_password, + { + 0, + 0, + }, + "" + }, + }, + }, + 3 }, }; @@ -1049,6 +1094,10 @@ void isButtonSingle(byte x) while(dig--) { scale *= 10; } all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] += scale; + + Serial.print(all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]); + Serial.println(""); + Serial.print(temp_password); } else { @@ -1089,6 +1138,8 @@ void isButtonDouble(byte x) if(current_menu_screen.menu_lines[current_line_index].type == MENU_LINE) { + sprintf(text_parameters[stage_password],""); + last_menu_index[menu_inter] = menu_index; last_menu_cursor_index[menu_inter] = current_line_index; menu_inter++; @@ -1109,16 +1160,16 @@ void isButtonDouble(byte x) { temp_password = all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]; all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; - password_stage = 0; + sprintf(text_parameters[stage_password],"Введите старый"); current_digit = 4; } else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) { temp_password = all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]; all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; - password_stage = 0; + sprintf(text_parameters[stage_password],"Введите пароль"); current_digit = 4; } @@ -1128,6 +1179,7 @@ void isButtonDouble(byte x) } else { start_edit_parameter = false; need_hide_cursor = false; + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) { save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); @@ -1138,7 +1190,55 @@ void isButtonDouble(byte x) } else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE) { - save_long_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + if(password_stage == 0) + { + if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) + { + start_edit_parameter = true; + hide_cursor(); + need_hide_cursor = true; + + sprintf(text_parameters[stage_password],"Введите новый"); + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; + password_stage = 1; + } + else + { + sprintf(text_parameters[stage_password],"Неверный пароль"); + password_stage = 0; + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; + } + } + else if(password_stage == 1) + { + password_stage = 0; + save_long_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + sprintf(text_parameters[stage_password],"Пароль обновлен"); + } + } + else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) + { + if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) + { + sprintf(text_parameters[stage_password]," Сброс прошел"); + + if(menu_index == RESET_DEVICE_MENU) + { + reset_parameter(); + Serial.println("reset_parameter"); + } + else if(menu_index == RESET_COUNTER_MENU) + { + reset_short_counters(); + Serial.println("reset_short_counters"); + } + } + else + { + sprintf(text_parameters[stage_password],"Неверный пароль"); + } + + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; } } } @@ -1486,16 +1586,6 @@ void menu() show_cursor(); need_reload_menu = false; } - if(all_byte_parameters[reset_device]) - { - if(enable_reset) reset_parameter(); - all_byte_parameters[reset_device] = 0; - } - if(all_byte_parameters[reset_counters]) - { - if(enable_reset) reset_short_counters(); - all_byte_parameters[reset_counters] = 0; - } } lcd.clear(); @@ -1615,13 +1705,22 @@ void setup() sprintf(text_parameters[time_seance],""); menu_index = 0; + if(!digitalRead(buttonPin_Start)) + { // сброс пароля по умолчанию + all_long_parameters[password] = 1111; + save_long_parameter(password); + + Serial.println("reset password"); + } + all_long_parameters[money_counter] = 0; } void loop() { read_buttons(buttonPin_Service); - read_buttons(buttonPin_Start); + //read_buttons(buttonPin_Start); + hide_cursor(); need_hide_cursor = true; From a5c3cd14eec53f0500f83b47958acb95b7a2cc6e Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 21 Nov 2024 02:17:21 +0300 Subject: [PATCH 19/28] =?UTF-8?q?=D0=9F=D0=BE=D1=87=D1=82=D0=B8=20=D0=B2?= =?UTF-8?q?=D1=81=D0=B5=20=D0=B7=D0=B0=D0=BA=D1=80=D1=8B=D0=BB.=20=D0=9E?= =?UTF-8?q?=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 145 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 130 insertions(+), 15 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 2ee9d5f..f2bdedb 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -73,6 +73,22 @@ boolean need_clear_menu = false; // флаг очистки boolean need_hide_cursor = false; // флаг скытия курсора на экране boolean start_edit_parameter = false; // флаг старта редактирования параметра +const PROGMEM char sprintf_format[][SIZE_SCREEN_LINE*2] = { + "ver %s %s", + "Введите старый", + "Введите пароль", + "Введите новый", + "Неверный пароль", + "Пароль обновлен", + " Сброс прошел", + "Неверный пароль", + "%s %d %s ", + "%04ld", + "%s%04ld", + "не требуется", //11 + "требуется", //12 +}; + // Переменные для работы с соляриями #define pause_before 0 #define pause_after 1 @@ -115,13 +131,16 @@ const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { #define short_time_counter 5 #define money_counter 6 #define password 7 -#define COUNT_LONG_PARAMETER 8 +#define serial_number 8 +#define COUNT_LONG_PARAMETER 9 unsigned long all_long_parameters[COUNT_LONG_PARAMETER]; #define time_seance 0 #define time_delay 0 #define stage_password 0 -#define COUNT_TEXT_PARAMETER 1 +#define version_date 0 +#define service_line 1 +#define COUNT_TEXT_PARAMETER 2 char text_parameters[COUNT_TEXT_PARAMETER][SIZE_SCREEN_LINE*2]; LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // устанавливаем адрес 0x27, и дисплей 16 символов 2 строки @@ -195,6 +214,7 @@ void read_buttons(byte x) #define SOLARIUM_MENU_DEV 10 #define RESET_DEVICE_MENU 11 #define RESET_COUNTER_MENU 12 +#define DEVICE_SETTING_MENU 13 enum type_menu_line { MENU_LINE = 0, @@ -206,6 +226,8 @@ enum type_menu_line { DIGIT_VIEW_LINE, PASSWORD_SET_LINE, PASSWORD_VERIFY_LINE, + INTEGER_PARAM_LINE, + STRING_PARAM_LINE, }; struct param_limit { @@ -434,6 +456,11 @@ const menu_screen menu_settings[] PROGMEM = { FIXED_LINE, {0} }, + { + "Устройство", + MENU_LINE, + {DEVICE_SETTING_MENU} + }, { "Настройки", MENU_LINE, @@ -445,7 +472,7 @@ const menu_screen menu_settings[] PROGMEM = { {STATISTIC_MENU} } }, - 3 + 4 }, // Меню 1 { @@ -734,7 +761,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - "руб" + "руб/мин" } }, }, @@ -884,6 +911,53 @@ const menu_screen menu_settings[] PROGMEM = { }, 3 }, + // Меню 13 + { + { + { + "УСТРОЙСТВО", + FIXED_LINE, + {1} + }, + { + "SN", + DIGIT_VIEW_LINE, + { + serial_number, + { + 0, + 9999, + }, + "" + } + }, + { + "", + TEXT_PARAM_LINE, + { + version_date, + { + 0, + 0, + }, + "" + } + }, + { + "Обсл.", + TEXT_PARAM_LINE, + { + service_line, + { + 0, + 0, + }, + "" + } + }, + }, + 4 + }, }; void find_first_line_menu() @@ -1145,6 +1219,26 @@ void isButtonDouble(byte x) menu_inter++; menu_index = current_menu_screen.menu_lines[current_line_index].parameter.menu.next_menu_index; + if(menu_index == DEVICE_SETTING_MENU) + { + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[0], SIZE_SCREEN_LINE); + char ver[4]; + memcpy_P( &ver, Device_Ver, 4 ); + char date[9]; + memcpy_P( &date, Device_Date, 9 ); + + sprintf(text_parameters[version_date],format, ver, date); + + if(block > all_long_parameters[long_money_counter]) { + memcpy_P( &format, &sprintf_format[11], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[service_line],format); + } else { + memcpy_P( &format, &sprintf_format[12], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[service_line],format); + } + } + memcpy_P( ¤t_menu_screen, &menu_settings[menu_index], sizeof(menu_screen)); find_first_line_menu(); lcd.clear(); @@ -1161,7 +1255,10 @@ void isButtonDouble(byte x) temp_password = all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]; all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; password_stage = 0; - sprintf(text_parameters[stage_password],"Введите старый"); + + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[1], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); current_digit = 4; } else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) @@ -1169,7 +1266,10 @@ void isButtonDouble(byte x) temp_password = all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]; all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; password_stage = 0; - sprintf(text_parameters[stage_password],"Введите пароль"); + + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[2], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); current_digit = 4; } @@ -1198,13 +1298,17 @@ void isButtonDouble(byte x) hide_cursor(); need_hide_cursor = true; - sprintf(text_parameters[stage_password],"Введите новый"); + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[3], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; password_stage = 1; } else { - sprintf(text_parameters[stage_password],"Неверный пароль"); + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[4], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); password_stage = 0; all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; } @@ -1213,14 +1317,19 @@ void isButtonDouble(byte x) { password_stage = 0; save_long_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); - sprintf(text_parameters[stage_password],"Пароль обновлен"); + + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[5], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); } } else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) { if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) { - sprintf(text_parameters[stage_password]," Сброс прошел"); + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[6], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); if(menu_index == RESET_DEVICE_MENU) { @@ -1235,7 +1344,9 @@ void isButtonDouble(byte x) } else { - sprintf(text_parameters[stage_password],"Неверный пароль"); + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[7], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); } all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; @@ -1257,7 +1368,8 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == DIGIT_PARAM_LINE) { char line[SIZE_SCREEN_LINE * 2]; - char format[11] = "%s %d %s "; + char format[11]; + memcpy_P( &format, &sprintf_format[8], 11); if(start_edit_parameter && index_line == current_line_index) { format[2] = '>'; @@ -1272,7 +1384,8 @@ void show_line(byte index_line) char line[SIZE_SCREEN_LINE * 2]; if(start_edit_parameter && index_line == current_line_index) { - char format[6] = "%04ld"; + char format[6]; + memcpy_P( &format, &sprintf_format[9], 6); sprintf(line,format, all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index]); } else @@ -1286,7 +1399,8 @@ void show_line(byte index_line) char line[SIZE_SCREEN_LINE * 2]; if(start_edit_parameter && index_line == current_line_index) { - char format[8] = "%s%04ld"; + char format[8]; + memcpy_P( &format, &sprintf_format[10], 8); sprintf(line,format, " ", all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index]); } else @@ -1322,7 +1436,7 @@ void show_line(byte index_line) text_parameters[current_menu_screen.menu_lines[index_line].parameter.text.param_index], current_menu_screen.menu_lines[index_line].parameter.text.unit); lcd.print(convertCyr( utf8rus( line ))); - } + } } /* @@ -1714,6 +1828,7 @@ void setup() } all_long_parameters[money_counter] = 0; + all_long_parameters[serial_number] = Device_SerNum; } void loop() From 90b7b60e8355841da19feaca0eda832f652848b1 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 21 Nov 2024 23:07:47 +0300 Subject: [PATCH 20/28] =?UTF-8?q?=D0=9D=D0=B0=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=B9=D0=BA=D0=B0=20=D1=83=D1=80=D0=BE=D0=B2=D0=BD=D0=B5=D0=B9?= =?UTF-8?q?=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index f2bdedb..9bf8fa5 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -5,15 +5,21 @@ #include // Подключаем библиотеку для работы с LCD #include +// активный уровень кнопок +#define KEY_LEVEL 1 + // ===============================задаем константы ========================================================================= const byte moneyPin = 2; // номер пина, к которому подключён купюроприемник, DB2 const byte inhibitPin = 4; // +Inhibit (зеленый) на купюроприемник, DB4 -//const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 -//const byte buttonPin_Service = 14; // номер входа, подключенный к кнопке "Сервис", А1 -//const byte LEDPin = 13; // номер выхода светодиода кнопки Старт, DB13 +#if KEY_LEVEL == 1 const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 const byte buttonPin_Service = 13; // номер входа, подключенный к кнопке "Сервис", А1 const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 +#elif +const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 +const byte buttonPin_Service = 14; // номер входа, подключенный к кнопке "Сервис", А1 +const byte LEDPin = 13; // номер выхода светодиода кнопки Старт, DB13 +#endif // ноги управления соляриями const byte lamp_start_pin = 5; // Запуск солярия Luxura. Включение ламп солярия FireSun, SunFlower @@ -147,7 +153,12 @@ LiquidCrystal_I2C lcd(0x27, SIZE_SCREEN_LINE, SIZE_SCREEN); // void read_buttons(byte x) { + #if KEY_LEVEL == 1 boolean reading = !digitalRead(x); + #elif + boolean reading = digitalRead(x); + #endif + int index = (x == buttonPin_Service ? 0 : 1); if (reading && !lastReading[index]) // проверка первичного нажатия @@ -1613,7 +1624,11 @@ void get_money () digitalWrite(LEDPin, HIGH); // зажигаем светодиод + #if KEY_LEVEL == 1 if (digitalRead(buttonPin_Start) == LOW) + #elif + if (digitalRead(buttonPin_Start) == HIGH) + #endif { digitalWrite(inhibitPin, HIGH); // выставляем запрет приема монет digitalWrite(LEDPin, LOW); // гасим светодиод From 72dc1045158dea12201646057c99a0e543ce2e8e Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 21 Nov 2024 23:11:38 +0300 Subject: [PATCH 21/28] =?UTF-8?q?=D0=BD=D0=B0=D0=B2=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 9bf8fa5..8c1cd28 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -1834,7 +1834,11 @@ void setup() sprintf(text_parameters[time_seance],""); menu_index = 0; + #if KEY_LEVEL == 1 if(!digitalRead(buttonPin_Start)) + #elif + if(digitalRead(buttonPin_Start)) + #endif { // сброс пароля по умолчанию all_long_parameters[password] = 1111; save_long_parameter(password); From d2ed390c5ea38ab1a649b666e5a25fa5c48784d9 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 22 Nov 2024 00:03:17 +0300 Subject: [PATCH 22/28] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=82=D1=81=D1=87=D0=B5=D1=82=20=D0=B2=20=D0=BE?= =?UTF-8?q?=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 8c1cd28..348a4b1 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -402,7 +402,7 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " ПАУЗА", + " ВЕНТИЛЯЦИЯ", FIXED_LINE, {0} }, @@ -1109,8 +1109,8 @@ void isButtonHold(byte x) return; } - if(!menu_enable) - { + if(!menu_enable && (all_long_parameters[money_counter] == 0) || (bill_enable == false)) + { // в меню входим только если нет внесенных денег и не запрещен прием денег, тк идет работа соляриев menu_index = MAIN_MENU; memcpy_P( ¤t_menu_screen, &menu_settings[menu_index], sizeof(menu_screen)); @@ -1674,7 +1674,13 @@ void get_money () sprintf(text_parameters[time_delay],"%2d", all_byte_parameters[pause_before]); lcd.clear(); show_menu(); - delay(all_byte_parameters[pause_before] * 1000); + + for(int i = 0; i < all_byte_parameters[pause_before]; i++) + { + delay(1000); + sprintf(text_parameters[time_delay],"%2d", all_byte_parameters[pause_before] - i); + show_menu(); + } } memcpy_P( ¤t_menu_screen, &menu_main[SEANCE_SCREEN], sizeof(menu_screen)); @@ -1858,7 +1864,7 @@ void loop() hide_cursor(); need_hide_cursor = true; - if (menu_enable == true) // если флаг menu_enable = ИСТИНА, то входим в меню + if (menu_enable == true) { menu(); need_reload_menu = true; @@ -1866,7 +1872,7 @@ void loop() } else { - if (bill_enable == true && menu_enable == false) + if (bill_enable == true && menu_enable == false) { get_money(); } From 454925483af8101061a109218f13ccd5d12ea2ad Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 22 Nov 2024 00:08:02 +0300 Subject: [PATCH 23/28] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B5=D0=B5=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 348a4b1..63464a1 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -300,8 +300,7 @@ menu_screen current_menu_screen; #define WAIT_BEFORE 1 #define SEANCE_SCREEN 2 #define WAIT_AFTER 3 -#define SCREEN_END 4 -#define SCREEN_START_SOL 5 +#define SCREEN_START_SOL 4 /* Описание основного меню @@ -421,22 +420,6 @@ const menu_screen menu_main[] PROGMEM = { }, 3 }, - // Меню окончания сеанса - { - { - { - "", - FIXED_LINE, - {0} - }, - { - " КОНЕЦ", - FIXED_LINE, - {0} - }, - }, - 2 - }, // Удаленный запуск { { @@ -1092,7 +1075,6 @@ void isButtonHoldRepeate(byte x) } } } - return; } } @@ -1762,17 +1744,10 @@ void second_event() sprintf(text_parameters[time_seance]," %02d:%02d", minute, second); need_reload_menu = true; - if(menu_index == SCREEN_END && time_remain == 0) - { - restart_menu(); - } if(menu_index == WAIT_AFTER && time_remain == 0) { stop_vent_work(); - - memcpy_P( ¤t_menu_screen, &menu_main[SCREEN_END], sizeof(menu_screen)); - menu_index = SCREEN_END; - second = 10; + restart_menu(); need_clear_menu = true; need_reload_menu = true; @@ -1783,9 +1758,7 @@ void second_event() if(all_byte_parameters[solarium_type] == LUXURA_SOL) { - memcpy_P( ¤t_menu_screen, &menu_main[SCREEN_END], sizeof(menu_screen)); - menu_index = SCREEN_END; - second = 10; + restart_menu(); } else { From 6cdd367aed8950d5e56575f9cd08799fd08d18b2 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 22 Nov 2024 00:11:32 +0300 Subject: [PATCH 24/28] =?UTF-8?q?=D0=9D=D0=B0=D0=B2=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 63464a1..3f7f7d1 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -1107,6 +1107,7 @@ void isButtonHold(byte x) if(menu_index == MAIN_MENU) { menu_enable = false; + sprintf(text_parameters[stage_password],""); } else { From 56eb42e75a6576cba5671eaabd2472d8552242ae Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 22 Nov 2024 00:14:02 +0300 Subject: [PATCH 25/28] =?UTF-8?q?=D0=BD=D0=B0=D0=B2=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 3f7f7d1..231e00a 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -15,7 +15,7 @@ const byte inhibitPin = 4; // +Inhibit (зеленый) const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 const byte buttonPin_Service = 13; // номер входа, подключенный к кнопке "Сервис", А1 const byte LEDPin = 14; // номер выхода светодиода кнопки Старт, DB13 -#elif +#else const byte buttonPin_Start = 15; // номер входа, подключенный к кнопке "Старт", А0 const byte buttonPin_Service = 14; // номер входа, подключенный к кнопке "Сервис", А1 const byte LEDPin = 13; // номер выхода светодиода кнопки Старт, DB13 @@ -155,7 +155,7 @@ void read_buttons(byte x) { #if KEY_LEVEL == 1 boolean reading = !digitalRead(x); - #elif + #else boolean reading = digitalRead(x); #endif @@ -1609,7 +1609,7 @@ void get_money () #if KEY_LEVEL == 1 if (digitalRead(buttonPin_Start) == LOW) - #elif + #else if (digitalRead(buttonPin_Start) == HIGH) #endif { @@ -1816,7 +1816,7 @@ void setup() #if KEY_LEVEL == 1 if(!digitalRead(buttonPin_Start)) - #elif + #else if(digitalRead(buttonPin_Start)) #endif { // сброс пароля по умолчанию From 2c8a682acba5e598d6d6dcdffca24d0cad82e89a Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Tue, 17 Dec 2024 01:54:37 +0300 Subject: [PATCH 26/28] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D0=B0=D1=8F=20=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 246 +++++++++++++++++++++++++----------------- 1 file changed, 149 insertions(+), 97 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 231e00a..675fe56 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -239,6 +239,7 @@ enum type_menu_line { PASSWORD_VERIFY_LINE, INTEGER_PARAM_LINE, STRING_PARAM_LINE, + DIGIT_INT_VIEW_LINE, }; struct param_limit { @@ -310,9 +311,16 @@ const menu_screen menu_main[] PROGMEM = { { { { - "", - FIXED_LINE, - {0} + " ЦЕНА", + DIGIT_INT_VIEW_LINE, + { + price, + { + 0, + 0, + }, + "руб/мин" + } }, { " ВНЕСЕНО", @@ -338,14 +346,26 @@ const menu_screen menu_main[] PROGMEM = { " " } }, + { + "", + TEXT_PARAM_LINE, + { + service_line, + { + 0, + 0, + }, + " " + } + }, }, - 3 + 4 }, // Время задержки до { { { - "", + " ДО СТАРТА", FIXED_LINE, {0} }, @@ -373,7 +393,7 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " CEAHC", + " СЕАНС ЗАГАРА", FIXED_LINE, {0} }, @@ -1123,6 +1143,87 @@ void isButtonHold(byte x) digitalWrite(LEDPin, HIGH); lcd.clear(); } + } else { + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE + || current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE + || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE + || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) + { + start_edit_parameter = false; + need_hide_cursor = false; + + if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) + { + save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + } + else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) + { + save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); + } + else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE) + { + if(password_stage == 0) + { + if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) + { + start_edit_parameter = true; + hide_cursor(); + need_hide_cursor = true; + + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[3], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; + password_stage = 1; + } + else + { + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[4], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); + password_stage = 0; + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; + } + } + else if(password_stage == 1) + { + password_stage = 0; + save_long_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); + + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[5], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); + } + } + else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) + { + if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) + { + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[6], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); + + if(menu_index == RESET_DEVICE_MENU) + { + reset_parameter(); + Serial.println("reset_parameter"); + } + else if(menu_index == RESET_COUNTER_MENU) + { + reset_short_counters(); + Serial.println("reset_short_counters"); + } + } + else + { + char format[SIZE_SCREEN_LINE*2]; + memcpy_P( &format, &sprintf_format[7], SIZE_SCREEN_LINE*2); + sprintf(text_parameters[stage_password], format); + } + + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; + } + } } } } @@ -1134,7 +1235,7 @@ void isButtonSingle(byte x) { need_reload_menu = true; - if(start_edit_parameter && (x == buttonPin_Start || x == buttonPin_Service)) + if(start_edit_parameter && x == buttonPin_Start) { if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) { @@ -1154,23 +1255,36 @@ void isButtonSingle(byte x) if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) { - if(x == buttonPin_Service) + if(--current_digit == 0) { current_digit = 4; } + } + } + else if(start_edit_parameter && x == buttonPin_Service) + { + if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE + || current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) + { + byte dig = current_digit - 1; + int scale = 1; + + while(dig--) { scale *= 10; } + + switch(current_digit - 1) { - byte dig = current_digit - 1; - int scale = 1; - - while(dig--) { scale *= 10; } - - all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] += scale; - - Serial.print(all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]); - Serial.println(""); - Serial.print(temp_password); - } - else - { - if(--current_digit == 0) { current_digit = 4; } + case 0: + if(all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] % 10 >= 9) scale = -9; + break; + case 1: + if(all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] % 100 >= 90) scale = -90; + break; + case 2: + if(all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] % 1000 >= 900) scale = -900; + break; + case 3: + if(all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] % 10000 >= 9000) scale = -9000; + break; } + + all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] += scale; } } else if(x == buttonPin_Service) @@ -1270,81 +1384,6 @@ void isButtonDouble(byte x) start_edit_parameter = true; hide_cursor(); need_hide_cursor = true; - } else { - start_edit_parameter = false; - need_hide_cursor = false; - - if(current_menu_screen.menu_lines[current_line_index].type == DIGIT_PARAM_LINE) - { - save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); - } - else if(current_menu_screen.menu_lines[current_line_index].type == LIST_PARAM_LINE) - { - save_byte_parameter(current_menu_screen.menu_lines[current_line_index].parameter.list.param_index); - } - else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_SET_LINE) - { - if(password_stage == 0) - { - if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) - { - start_edit_parameter = true; - hide_cursor(); - need_hide_cursor = true; - - char format[SIZE_SCREEN_LINE*2]; - memcpy_P( &format, &sprintf_format[3], SIZE_SCREEN_LINE*2); - sprintf(text_parameters[stage_password], format); - all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = 0; - password_stage = 1; - } - else - { - char format[SIZE_SCREEN_LINE*2]; - memcpy_P( &format, &sprintf_format[4], SIZE_SCREEN_LINE*2); - sprintf(text_parameters[stage_password], format); - password_stage = 0; - all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; - } - } - else if(password_stage == 1) - { - password_stage = 0; - save_long_parameter(current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index); - - char format[SIZE_SCREEN_LINE*2]; - memcpy_P( &format, &sprintf_format[5], SIZE_SCREEN_LINE*2); - sprintf(text_parameters[stage_password], format); - } - } - else if(current_menu_screen.menu_lines[current_line_index].type == PASSWORD_VERIFY_LINE) - { - if(temp_password == all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index]) - { - char format[SIZE_SCREEN_LINE*2]; - memcpy_P( &format, &sprintf_format[6], SIZE_SCREEN_LINE*2); - sprintf(text_parameters[stage_password], format); - - if(menu_index == RESET_DEVICE_MENU) - { - reset_parameter(); - Serial.println("reset_parameter"); - } - else if(menu_index == RESET_COUNTER_MENU) - { - reset_short_counters(); - Serial.println("reset_short_counters"); - } - } - else - { - char format[SIZE_SCREEN_LINE*2]; - memcpy_P( &format, &sprintf_format[7], SIZE_SCREEN_LINE*2); - sprintf(text_parameters[stage_password], format); - } - - all_long_parameters[current_menu_screen.menu_lines[current_line_index].parameter.digit.param_index] = temp_password; - } } } } @@ -1431,6 +1470,14 @@ void show_line(byte index_line) current_menu_screen.menu_lines[index_line].parameter.text.unit); lcd.print(convertCyr( utf8rus( line ))); } + else if(current_menu_screen.menu_lines[index_line].type == DIGIT_INT_VIEW_LINE) + { + char line[SIZE_SCREEN_LINE * 2]; + sprintf(line,"%s %d %s", current_menu_screen.menu_lines[index_line].string, + all_byte_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], + current_menu_screen.menu_lines[index_line].parameter.digit.unit); + lcd.print(convertCyr( utf8rus( line ))); + } } /* @@ -1604,6 +1651,7 @@ void get_money () { // достаточно денег для оказания услуги sprintf(text_parameters[time_seance],"СЕАНС %02d:%02d МИН", minute, second); + sprintf(text_parameters[service_line]," НАЖМИТЕ СТАРТ"); digitalWrite(LEDPin, HIGH); // зажигаем светодиод @@ -1678,6 +1726,10 @@ void get_money () start_solarium_work(); } } + else + { + sprintf(text_parameters[service_line]," Внесите оплату"); + } } // ============================== процедура прорисовки меню и изменения значения параметров ======================================= From b062f2969f8a525390afbf73d3e2d6333b389ed0 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Wed, 25 Dec 2024 01:22:17 +0300 Subject: [PATCH 27/28] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8?= =?UTF-8?q?=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=B2=D1=81=D0=B5?= =?UTF-8?q?=20=D1=87=D1=82=D0=BE=20=D0=BC=D0=BE=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 53 ++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index 675fe56..c29bcba 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -93,6 +93,14 @@ const PROGMEM char sprintf_format[][SIZE_SCREEN_LINE*2] = { "%s%04ld", "не требуется", //11 "требуется", //12 + " 0000", //13 + "%s %s ", //14 + "%s %ld %s", //15 + "%s %s %s", //16 + "%s %d %s", //17 + "CEAHC %02d:%02d MИH", //18 + " HAЖМИTE CTAPT", //19 + " ВНЕСИТЕ ОПЛАТУ", //20 }; // Переменные для работы с соляриями @@ -319,7 +327,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - "руб/мин" + "pyб/mин" } }, { @@ -331,7 +339,7 @@ const menu_screen menu_main[] PROGMEM = { 0, 0, }, - "руб" + "pyб" } }, { @@ -562,7 +570,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - "сек" + "ceк" } }, { @@ -589,7 +597,7 @@ const menu_screen menu_settings[] PROGMEM = { {0} }, { - "Руб/имп", + "Pyб/иmп", DIGIT_PARAM_LINE, { weight_impulse, @@ -775,7 +783,7 @@ const menu_screen menu_settings[] PROGMEM = { 0, 100, }, - "руб/мин" + "pyб/mин" } }, }, @@ -1438,14 +1446,17 @@ void show_line(byte index_line) } else { - sprintf(line," 0000"); + char format[11]; + memcpy_P( &format, &sprintf_format[13], 10); + sprintf(line,format); } lcd.print(convertCyr( utf8rus( line ))); } else if(current_menu_screen.menu_lines[index_line].type == LIST_PARAM_LINE) { char line[SIZE_SCREEN_LINE * 2]; - char format[8] = "%s %s "; + char format[8]; + memcpy_P( &format, &sprintf_format[14], 8); if(start_edit_parameter && index_line == current_line_index) { format[2] = '>'; @@ -1457,7 +1468,10 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == DIGIT_VIEW_LINE) { char line[SIZE_SCREEN_LINE * 2]; - sprintf(line,"%s %ld %s", current_menu_screen.menu_lines[index_line].string, + char format[10]; + memcpy_P( &format, &sprintf_format[15], 10); + + sprintf(line,format, current_menu_screen.menu_lines[index_line].string, all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], current_menu_screen.menu_lines[index_line].parameter.digit.unit); lcd.print(convertCyr( utf8rus( line ))); @@ -1465,7 +1479,10 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == TEXT_PARAM_LINE) { char line[SIZE_SCREEN_LINE * 2]; - sprintf(line,"%s %s %s", current_menu_screen.menu_lines[index_line].string, + char format[9]; + memcpy_P( &format, &sprintf_format[16], 9); + + sprintf(line,format, current_menu_screen.menu_lines[index_line].string, text_parameters[current_menu_screen.menu_lines[index_line].parameter.text.param_index], current_menu_screen.menu_lines[index_line].parameter.text.unit); lcd.print(convertCyr( utf8rus( line ))); @@ -1473,7 +1490,10 @@ void show_line(byte index_line) else if(current_menu_screen.menu_lines[index_line].type == DIGIT_INT_VIEW_LINE) { char line[SIZE_SCREEN_LINE * 2]; - sprintf(line,"%s %d %s", current_menu_screen.menu_lines[index_line].string, + char format[9]; + memcpy_P( &format, &sprintf_format[17], 9); + + sprintf(line,format, current_menu_screen.menu_lines[index_line].string, all_byte_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index], current_menu_screen.menu_lines[index_line].parameter.digit.unit); lcd.print(convertCyr( utf8rus( line ))); @@ -1649,9 +1669,14 @@ void get_money () if (all_long_parameters[money_counter] >= all_byte_parameters[price]) { + char format[30]; + memcpy_P( &format, &sprintf_format[18], 30); + // достаточно денег для оказания услуги - sprintf(text_parameters[time_seance],"СЕАНС %02d:%02d МИН", minute, second); - sprintf(text_parameters[service_line]," НАЖМИТЕ СТАРТ"); + sprintf(text_parameters[time_seance], format, minute, second); + + memcpy_P( &format, &sprintf_format[19], 30); + sprintf(text_parameters[service_line], format); digitalWrite(LEDPin, HIGH); // зажигаем светодиод @@ -1728,7 +1753,9 @@ void get_money () } else { - sprintf(text_parameters[service_line]," Внесите оплату"); + char format[30]; + memcpy_P( &format, &sprintf_format[20], 30); + sprintf(text_parameters[service_line], format); } } From 37bab3fdda879507d02f66e20bd24c58e7250c8d Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 31 Jan 2025 00:41:39 +0300 Subject: [PATCH 28/28] =?UTF-8?q?=D0=9E=D1=87=D0=B5=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solarium/solarium.ino | 73 +++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/solarium/solarium.ino b/solarium/solarium.ino index c29bcba..530b6d7 100644 --- a/solarium/solarium.ino +++ b/solarium/solarium.ino @@ -8,6 +8,9 @@ // активный уровень кнопок #define KEY_LEVEL 1 +// максимальное время работы солярия +#define MAX_TIME_SOLARIUM_WORK 20 + // ===============================задаем константы ========================================================================= const byte moneyPin = 2; // номер пина, к которому подключён купюроприемник, DB2 const byte inhibitPin = 4; // +Inhibit (зеленый) на купюроприемник, DB4 @@ -78,6 +81,7 @@ boolean need_reload_menu = true; // флаг перерисо boolean need_clear_menu = false; // флаг очистки экрана boolean need_hide_cursor = false; // флаг скытия курсора на экране boolean start_edit_parameter = false; // флаг старта редактирования параметра +boolean solarium_work = false; // флаг работы соляриев const PROGMEM char sprintf_format[][SIZE_SCREEN_LINE*2] = { "ver %s %s", @@ -89,11 +93,11 @@ const PROGMEM char sprintf_format[][SIZE_SCREEN_LINE*2] = { " Сброс прошел", "Неверный пароль", "%s %d %s ", - "%04ld", - "%s%04ld", + "%04ld", //9 + " %04ld", //10 "не требуется", //11 "требуется", //12 - " 0000", //13 + " 0000 ", //13 "%s %s ", //14 "%s %ld %s", //15 "%s %s %s", //16 @@ -121,20 +125,25 @@ const PROGMEM char sprintf_format[][SIZE_SCREEN_LINE*2] = { #define UV_COLLATEN_REGIME 2 #define work_regime 5 + +#define HIGH_RELAY 0 +#define LOW_RELAY 1 + #define signal_rele 6 + #define weight_impulse 7 #define COUNT_BYTE_PARAMETER 8 byte all_byte_parameters[COUNT_BYTE_PARAMETER]; const byte all_byte_parameters_default[COUNT_BYTE_PARAMETER] = { - 30, - 3, - 20, - 0, - 0, - 0, - 0, - 10, + 30, // pause_before + 3, // pause_after + 20, // price + 0, // remote_start + LUXURA_SOL, // solarium_type + COLLATEN_REGIME, // work_regime + LOW_RELAY, // signal_rele + 10, // weight_impulse }; #define long_starts_counter 0 @@ -373,7 +382,7 @@ const menu_screen menu_main[] PROGMEM = { { { { - " ДО СТАРТА", + " ДО СТАРТА", FIXED_LINE, {0} }, @@ -401,7 +410,7 @@ const menu_screen menu_main[] PROGMEM = { {0} }, { - " СЕАНС ЗАГАРА", + " СЕАНС ЗАГАРА", FIXED_LINE, {0} }, @@ -1112,6 +1121,12 @@ void isButtonHoldRepeate(byte x) */ void isButtonHold(byte x) { + if(solarium_work == true) + { + // если работают солярии вход в меню запрещен + return; + } + need_reload_menu = true; if(x == buttonPin_Start) @@ -1440,14 +1455,14 @@ void show_line(byte index_line) char line[SIZE_SCREEN_LINE * 2]; if(start_edit_parameter && index_line == current_line_index) { - char format[8]; - memcpy_P( &format, &sprintf_format[10], 8); - sprintf(line,format, " ", all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index]); + char format[11]; + memcpy_P( &format, &sprintf_format[10], 11); + sprintf(line, format, all_long_parameters[current_menu_screen.menu_lines[index_line].parameter.digit.param_index]); } else { char format[11]; - memcpy_P( &format, &sprintf_format[13], 10); + memcpy_P( &format, &sprintf_format[13], 11); sprintf(line,format); } lcd.print(convertCyr( utf8rus( line ))); @@ -1572,6 +1587,8 @@ bool read_money_impulse () */ void start_solarium_work() { + solarium_work = true; + switch(all_byte_parameters[solarium_type]) { case LUXURA_SOL: @@ -1634,6 +1651,8 @@ void stop_solarium_work() digitalWrite(lamp_start_pin, LOW); break; } + + solarium_work = false; } /* @@ -1680,6 +1699,13 @@ void get_money () digitalWrite(LEDPin, HIGH); // зажигаем светодиод + // Достигли максимального времени загара + if(minute >= MAX_TIME_SOLARIUM_WORK) + { + digitalWrite(inhibitPin, HIGH); // выставляем запрет приема монет + digitalWrite(LEDPin, LOW); // гасим светодиод + } + #if KEY_LEVEL == 1 if (digitalRead(buttonPin_Start) == LOW) #else @@ -1836,16 +1862,9 @@ void second_event() { stop_solarium_work(); - if(all_byte_parameters[solarium_type] == LUXURA_SOL) - { - restart_menu(); - } - else - { - memcpy_P( ¤t_menu_screen, &menu_main[WAIT_AFTER], sizeof(menu_screen)); - menu_index = WAIT_AFTER; - minute = all_byte_parameters[pause_after]; - } + memcpy_P( ¤t_menu_screen, &menu_main[WAIT_AFTER], sizeof(menu_screen)); + menu_index = WAIT_AFTER; + minute = all_byte_parameters[pause_after]; need_clear_menu = true; need_reload_menu = true;