diff --git a/Blynk.ino b/Blynk.ino index 7718c7fe..fbd24c1e 100644 --- a/Blynk.ino +++ b/Blynk.ino @@ -150,6 +150,8 @@ BLYNK_WRITE(V4) { sam_command_sync = SAMOVAR_BEER; } else if (Samovar_Mode == SAMOVAR_BK_MODE && !PowerOn) { sam_command_sync = SAMOVAR_BK; + } else if (Samovar_Mode == SAMOVAR_NBK_MODE && !PowerOn) { + sam_command_sync = SAMOVAR_NBK; } else if (Samovar_Mode == SAMOVAR_DISTILLATION_MODE && !PowerOn) { sam_command_sync = SAMOVAR_DISTILLATION; } else diff --git a/FS.ino b/FS.ino index f821e2ef..a6361352 100644 --- a/FS.ino +++ b/FS.ino @@ -344,6 +344,8 @@ String get_prf_name() { fl = "/dist.prf"; } else if (Samovar_CR_Mode == SAMOVAR_BK_MODE) { fl = "/bk.prf"; + } else if (Samovar_CR_Mode == SAMOVAR_NBK_MODE) { + fl = "/nbk.prf"; } else { fl = "/rectificat.prf"; } diff --git a/Menu.ino b/Menu.ino index cb58a895..3f23b528 100644 --- a/Menu.ino +++ b/Menu.ino @@ -427,6 +427,14 @@ void menu_get_power() { set_menu_screen(3); samovar_reset(); } + } else if (Samovar_Mode == SAMOVAR_NBK_MODE) { + if (!PowerOn) { + set_menu_screen(2); + sam_command_sync = SAMOVAR_NBK; + } else { + set_menu_screen(3); + samovar_reset(); + } } else { if (!PowerOn) { set_menu_screen(2); diff --git a/Samovar.h b/Samovar.h index 5d07da50..f0ec3e8b 100644 --- a/Samovar.h +++ b/Samovar.h @@ -5,7 +5,7 @@ #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif -#define SAMOVAR_VERSION F("6.18") +#define SAMOVAR_VERSION F("6.19") //#define __SAMOVAR_DEBUG @@ -157,6 +157,10 @@ StaticSemaphore_t xSemaphoreBufferAVR; #define LUA_BK "" #endif +#ifndef LUA_NBK +#define LUA_NBK "" +#endif + #ifndef LUA_RECT #define LUA_RECT "" #endif @@ -300,10 +304,10 @@ LiquidMenu main_menu1(lcd); DNSServer dns; -enum SamovarCommands {SAMOVAR_NONE, SAMOVAR_START, SAMOVAR_POWER, SAMOVAR_RESET, CALIBRATE_START, CALIBRATE_STOP, SAMOVAR_PAUSE, SAMOVAR_CONTINUE, SAMOVAR_SETBODYTEMP, SAMOVAR_DISTILLATION, SAMOVAR_BEER, SAMOVAR_BEER_NEXT, SAMOVAR_BK, SAMOVAR_SELF_TEST, SAMOVAR_DIST_NEXT}; +enum SamovarCommands {SAMOVAR_NONE, SAMOVAR_START, SAMOVAR_POWER, SAMOVAR_RESET, CALIBRATE_START, CALIBRATE_STOP, SAMOVAR_PAUSE, SAMOVAR_CONTINUE, SAMOVAR_SETBODYTEMP, SAMOVAR_DISTILLATION, SAMOVAR_BEER, SAMOVAR_BEER_NEXT, SAMOVAR_BK, SAMOVAR_NBK, SAMOVAR_SELF_TEST, SAMOVAR_DIST_NEXT}; volatile SamovarCommands sam_command_sync; // переменная для передачи команд между процессами -enum SAMOVAR_MODE {SAMOVAR_RECTIFICATION_MODE, SAMOVAR_DISTILLATION_MODE, SAMOVAR_BEER_MODE, SAMOVAR_BK_MODE, SAMOVAR_SUVID_MODE, SAMOVAR_LUA_MODE}; +enum SAMOVAR_MODE {SAMOVAR_RECTIFICATION_MODE, SAMOVAR_DISTILLATION_MODE, SAMOVAR_BEER_MODE, SAMOVAR_BK_MODE, SAMOVAR_NBK_MODE, SAMOVAR_SUVID_MODE, SAMOVAR_LUA_MODE}; volatile SAMOVAR_MODE Samovar_Mode; volatile SAMOVAR_MODE Samovar_CR_Mode; diff --git a/Samovar.ino b/Samovar.ino index 752c9d35..c7becc36 100644 --- a/Samovar.ino +++ b/Samovar.ino @@ -139,6 +139,7 @@ cppQueue msg_q(100, 5, FIFO); #include "distiller.h" #include "beer.h" #include "BK.h" +#include "nbk.h" #include "SPIFFSEditor.h" #include "I2CStepper.h" @@ -457,6 +458,8 @@ void triggerSysTicker(void *parameter) { check_alarm_distiller(); } else if (Samovar_Mode == SAMOVAR_BK_MODE) { check_alarm_bk(); + } else if (Samovar_Mode == SAMOVAR_NBK_MODE) { + check_alarm_nbk(); } else if (Samovar_Mode == SAMOVAR_BEER_MODE) { check_alarm_beer(); WFpulseCount = 100; @@ -508,6 +511,8 @@ void triggerSysTicker(void *parameter) { } else if (Samovar_Mode == SAMOVAR_BK_MODE) { + } else if (Samovar_Mode == SAMOVAR_NBK_MODE) { + } //Считаем прогресс отбора для текущей строки программы и время до конца завершения строки и всего отбора (режим ректификации) else if (Samovar_Mode == SAMOVAR_RECTIFICATION_MODE && (TargetStepps > 0 || program[ProgramNum].WType == "P")) { @@ -1093,6 +1098,12 @@ void loop() { sam_command_sync = SAMOVAR_BK; } else bk_finish(); + } else if (Samovar_Mode == SAMOVAR_NBK_MODE) { + //если дистилляция включаем или выключаем + if (!PowerOn) { + sam_command_sync = SAMOVAR_NBK; + } else + nbk_finish(); } else if (Samovar_Mode == SAMOVAR_BEER_MODE) { //если пиво включаем или двигаем программу if (!PowerOn) { @@ -1162,6 +1173,11 @@ void loop() { SamovarStatusInt = 3000; startval = 3000; break; + case SAMOVAR_NBK: + Samovar_Mode = SAMOVAR_NBK_MODE; + SamovarStatusInt = 4000; + startval = 4000; + break; case SAMOVAR_SELF_TEST: start_self_test(); break; diff --git a/WebServer.ino b/WebServer.ino index efcb91a1..befef5b4 100644 --- a/WebServer.ino +++ b/WebServer.ino @@ -46,6 +46,13 @@ void change_samovar_mode() { server.on("/index.htm", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(SPIFFS, "/bk.htm", String(), false, indexKeyProcessor); }); + } else if (Samovar_Mode == SAMOVAR_NBK_MODE) { + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(SPIFFS, "/nbk.htm", String(), false, indexKeyProcessor); + }); + server.on("/index.htm", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(SPIFFS, "/nbk.htm", String(), false, indexKeyProcessor); + }); } else { Samovar_Mode = SAMOVAR_RECTIFICATION_MODE; server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { @@ -427,6 +434,8 @@ String setupKeyProcessor(const String &var) { return "selected"; else if (var == "BK" && (SAMOVAR_MODE)SamSetup.Mode == SAMOVAR_BK_MODE) return "selected"; + else if (var == "NBK" && (SAMOVAR_MODE)SamSetup.Mode == SAMOVAR_NBK_MODE) + return "selected"; else if (var == "SUVID" && (SAMOVAR_MODE)SamSetup.Mode == SAMOVAR_SUVID_MODE) return "selected"; else if (var == "RAL" && !SamSetup.rele1) @@ -750,6 +759,10 @@ void web_command(AsyncWebServerRequest *request) { if (!PowerOn) sam_command_sync = SAMOVAR_BK; else sam_command_sync = SAMOVAR_POWER; + } else if (Samovar_Mode == SAMOVAR_NBK_MODE) { + if (!PowerOn) sam_command_sync = SAMOVAR_NBK; + else + sam_command_sync = SAMOVAR_POWER; } else sam_command_sync = SAMOVAR_POWER; } else if (request->hasArg("setbodytemp")) { @@ -909,6 +922,7 @@ void get_web_interface() { s += get_web_file("beer.htm", SAVE_FILE_OVERRIDE); s += get_web_file("bk.htm", SAVE_FILE_OVERRIDE); + s += get_web_file("nbk.htm", SAVE_FILE_OVERRIDE); s += get_web_file("brewxml.htm", SAVE_FILE_OVERRIDE); s += get_web_file("calibrate.htm", SAVE_FILE_OVERRIDE); s += get_web_file("chart.htm", SAVE_FILE_OVERRIDE); @@ -920,6 +934,7 @@ void get_web_interface() { s += get_web_file("beer.lua", SAVE_FILE_IF_NOT_EXIST); s += get_web_file("bk.lua", SAVE_FILE_IF_NOT_EXIST); + s += get_web_file("nbk.lua", SAVE_FILE_IF_NOT_EXIST); s += get_web_file("btn_button1.lua", SAVE_FILE_IF_NOT_EXIST); s += get_web_file("btn_button2.lua", SAVE_FILE_IF_NOT_EXIST); s += get_web_file("dist.lua", SAVE_FILE_IF_NOT_EXIST); diff --git a/data/nbk.htm b/data/nbk.htm new file mode 100644 index 00000000..7e4e365c --- /dev/null +++ b/data/nbk.htm @@ -0,0 +1,685 @@ + + + + + + + + Самовар + + + + + + + + + +
+ +
+ + +
+ +
+ +
+
+
+
Samovar
+
+
v.
+
+
+
+ +
+
+ +
+
+ + +
+
+ Работа: +
+
+ +
+ +
+
+ Т в царге:    + + °C +
+
+ Т пара:    + + °C +
+
+ Δ температур:   + + °C +
+
+ +
+
+ Т воды:    + + °C +
+
+ Т в кубе:    + + °C +
+
+ Т в ТСА:    + + °C +
+
+ +
+ +
+ + Статус: + +
+ +
+
+
+
+ Скорость насоса: + + + +
+ +
+
+ +
+ +
+
+
+ + +
+
+ +
+
+
+
+ + + +
+
+ + + +
+
+ Режим регулятора: +
+
+
+ + Мощность: Вт + +
+
+ +
+
+ Давление:   + + мм рт.ст. +
+
+ В начале:   + + мм рт.ст. +
+
+ +
+
+ + + +
+
+ +
+ +
+
Программа отбора:
+ +
+ +
+ +
+ +
+
+ +
+ Пример программы отбора: +
+
+
+
+ +
+ + +
+ +
+ +
+ Системные параметры: Heap=; BME temp=; RSSI = ; Свободно: +
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/data/nbk.lua b/data/nbk.lua new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/data/nbk.lua @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/data/setup.htm b/data/setup.htm index ae268101..5aa7dae2 100644 --- a/data/setup.htm +++ b/data/setup.htm @@ -146,6 +146,7 @@

+

diff --git a/data/version.txt b/data/version.txt index ecb32f86..09b1fbc3 100644 --- a/data/version.txt +++ b/data/version.txt @@ -1 +1 @@ -6.18 \ No newline at end of file +6.19 \ No newline at end of file diff --git a/lua.h b/lua.h index 89f81b1b..f44516de 100644 --- a/lua.h +++ b/lua.h @@ -13,6 +13,8 @@ LuaWrapper lua; #include #include "I2CStepper.h" +#include + #define EXPANDER_UPDATE_TIMEOUT 500 #ifdef USE_MQTT @@ -193,6 +195,8 @@ static int lua_wrapper_set_power(lua_State *lua_state) { sam_command_sync = SAMOVAR_BEER; } else if (Samovar_Mode == SAMOVAR_BK_MODE && !PowerOn) { sam_command_sync = SAMOVAR_BK; + } else if (Samovar_Mode == SAMOVAR_NBK_MODE && !PowerOn) { + sam_command_sync = SAMOVAR_NBK; } else if (Samovar_Mode == SAMOVAR_DISTILLATION_MODE && !PowerOn) { sam_command_sync = SAMOVAR_DISTILLATION; } else @@ -429,6 +433,18 @@ static int lua_wrapper_get_num_variable(lua_State *lua_state) { a = PauseOn; } else if (Var == "program_Wait") { a = program_Wait; + } else if (Var == "YY") { + a = year(time(NULL)); + } else if (Var == "MM") { + a = month(time(NULL)); + } else if (Var == "DD") { + a = day(time(NULL)); + } else if (Var == "HH") { + a = hour(time(NULL)) + SamSetup.TimeZone; + } else if (Var == "MI") { + a = minute(time(NULL)); + } else if (Var == "SS") { + a = second(time(NULL)); } else if (Var == "test_num_val") { a = test_num_val; } else if (Var != "") { @@ -1073,6 +1089,8 @@ String get_lua_mode_name() { fl = "/dist" + String(LUA_DIST) + ".lua"; } else if (Samovar_CR_Mode == SAMOVAR_BK_MODE) { fl = "/bk" + String(LUA_BK) + ".lua"; + } else if (Samovar_CR_Mode == SAMOVAR_NBK_MODE) { + fl = "/nbk" + String(LUA_NBK) + ".lua"; } else { fl = "/rectificat" + String(LUA_RECT) + ".lua"; } diff --git a/nbk.h b/nbk.h new file mode 100644 index 00000000..af659180 --- /dev/null +++ b/nbk.h @@ -0,0 +1,117 @@ +#include +#include "Samovar.h" + +void nbk_finish(); +void set_power_mode(String Mode); +void set_power(bool On); +void create_data(); +void open_valve(bool Val, bool msg); +void set_pump_pwm(float duty); +void set_pump_speed_pid(float temp); +void SendMsg(String m, MESSAGE_TYPE msg_type); +bool check_boiling(); +void set_water_temp(float duty); + + +void nbk_proc() { + + if (!PowerOn) { +#ifdef USE_MQTT + SessionDescription.replace(",", ";"); + MqttSendMsg((String)chipId + "," + SamSetup.TimeZone + "," + SAMOVAR_VERSION + ",NBK," + SessionDescription, "st"); +#endif + set_power(true); +#ifdef SAMOVAR_USE_POWER + delay(1000); + set_power_mode(POWER_SPEED_MODE); +#else + current_power_mode = POWER_SPEED_MODE; + digitalWrite(RELE_CHANNEL4, SamSetup.rele4); +#endif + create_data(); //создаем файл с данными + SteamSensor.Start_Pressure = bme_pressure; + SendMsg(("Включен нагрев непрерывной бражной колонны"), NOTIFY_MSG); + } + + if (TankSensor.avgTemp >= SamSetup.DistTemp) { + nbk_finish(); + } + vTaskDelay(10 / portTICK_PERIOD_MS); +} + +void nbk_finish() { + SendMsg(("Работа непрерывной бражной колонны завершена"), NOTIFY_MSG); + set_power(false); + reset_sensor_counter(); +} + + +void check_alarm_nbk() { + //сбросим паузу события безопасности + if (alarm_t_min > 0 && alarm_t_min <= millis()) alarm_t_min = 0; + + if (PowerOn && !valve_status && TankSensor.avgTemp >= OPEN_VALVE_TANK_TEMP) { + open_valve(true, true); +#ifdef USE_WATER_PUMP + set_pump_pwm(bk_pwm); +#endif + } + + //Определяем, что началось кипение - вода охлаждения начала нагреваться + if (current_power_mode == POWER_SPEED_MODE && (check_boiling() || SteamSensor.avgTemp > CHANGE_POWER_MODE_STEAM_TEMP || PipeSensor.avgTemp > CHANGE_POWER_MODE_STEAM_TEMP)) { +#ifdef SAMOVAR_USE_POWER +#ifndef SAMOVAR_USE_SEM_AVR + set_current_power(45); +#else + set_current_power(200); +#endif +#else + current_power_mode = POWER_WORK_MODE; + digitalWrite(RELE_CHANNEL4, !SamSetup.rele4); +#endif + } + + if (!PowerOn && !is_self_test && valve_status && WaterSensor.avgTemp <= TARGET_WATER_TEMP - 20) { + open_valve(false, true); +#ifdef USE_WATER_PUMP + if (pump_started) set_pump_pwm(0); +#endif + } + + //Проверяем, что температурные параметры не вышли за предельные значения + if ((WaterSensor.avgTemp >= MAX_WATER_TEMP) && PowerOn) { + set_buzzer(true); + //Если с температурой проблемы - выключаем нагрев, пусть оператор разбирается + set_power(false); + SendMsg(("Аварийное отключение! Превышена максимальная температура воды охлаждения!"), ALARM_MSG); + } + +#ifdef USE_WATERSENSOR + //Проверим, что вода подается + if (WFAlarmCount > WF_ALARM_COUNT && PowerOn) { + set_buzzer(true); + //Если с водой проблемы - выключаем нагрев, пусть оператор разбирается + sam_command_sync = SAMOVAR_POWER; + SendMsg(("Аварийное отключение! Прекращена подача воды."), ALARM_MSG); + } +#endif + + if ((WaterSensor.avgTemp >= ALARM_WATER_TEMP - 5) && PowerOn && alarm_t_min == 0) { + set_buzzer(true); + //Если уже реагировали - надо подождать 30 секунд, так как процесс инерционный + SendMsg(("Критическая температура воды!"), WARNING_MSG); + +#ifdef SAMOVAR_USE_POWER + + check_power_error(); + if (WaterSensor.avgTemp >= ALARM_WATER_TEMP) { + set_buzzer(true); + SendMsg("Критическая температура воды! Напряжение снижено с " + (String)target_power_volt, ALARM_MSG); + //Попробуем снизить напряжение регулятора на 5 вольт, чтобы исключить перегрев колонны. + set_current_power(target_power_volt - 5); + } +#endif + alarm_t_min = millis() + 30000; + } + vTaskDelay(10 / portTICK_PERIOD_MS); +} diff --git a/sensorinit.h b/sensorinit.h index 0e118a83..ca4776cd 100644 --- a/sensorinit.h +++ b/sensorinit.h @@ -147,12 +147,13 @@ void DS_getvalue(void) { // // return; - float ss, ps, ws, ts, acp, correctT; + float ss, ps, ws, ts, acp; + float correctT = 0; //Считаем корректировку температуры от атмосферного давления if (bme_pressure > 0 && PowerOn) { correctT = (760 - bme_pressure) * 0.037; - } else correctT = 0; + } ss = correctT + sensors.getTempC(SteamSensor.Sensor); // считываем температуру с датчика 0 ps = correctT + sensors.getTempC(PipeSensor.Sensor); // считываем температуру с датчика 1