From 655be76f831323b5375e0532416791d746cea982 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 13 Sep 2024 01:48:20 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D0=B5=D0=BC=D0=B0=20=D0=B4=D0=B5=D0=BD=D0=B5=D0=B3?= =?UTF-8?q?=20=D0=B8=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=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) {