#include #include #include #include #include "config.h" #include "LittleFS.h" #include // Display #define LCD_COLUMNS 16 #define LCD_ROWS 2 #define LCD_ADDRESS 0x27 #define RELAY_PIN D3 #define TEMP_SENSOR_PIN D5 // network // After how much time without connection we will // reboot (in millis) #define NON_CONNECTED_REBOOT_TIMEOUT 60000 #define RECONNECT_TIMEOUT 10000 IPAddress my_ip(MY_IP); IPAddress gateway(MY_GW); IPAddress subnet(MY_NET); // modbus consts and works #define TCP_PORT 15000 #define T_UPDATE_INTERVAL 1000 #define REGISTER_TARGET_T 0 #define REGISTER_HYSTERESIS 1 #define REGISTER_CUR_TEMP 2 #define REGISTER_CUR_STATE 3 ModbusIP mb; OneWire oneWire(TEMP_SENSOR_PIN); DallasTemperature sensor(&oneWire); LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS); long last_poll; long last_update; int t_target = 7000; int hyst = 200; int cur_t = 0; int cur_state = 0; bool TryLoad(char *filename) { File f = LittleFS.open(filename, "r"); if (!f) return false; String s = f.readStringUntil('\n'); t_target = atoi(s.c_str()); s = f.readStringUntil('\n'); hyst = atoi(s.c_str()); f.close(); if (t_target == 0) return false; return true; } void LoadState() { if (TryLoad("/settings.txt")) return; TryLoad("/settings.txt.bak"); } void SaveTo(char *filename) { File f = LittleFS.open(filename, "w"); if (!f) return; f.println(t_target); f.println(hyst); f.close(); } void SaveState() { SaveTo("/settings.txt"); SaveTo("/settings.txt.bak"); } void setup() { lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); if (!LittleFS.begin()) { Serial.println("Unable to mount the filesystem"); lcd.print("ERR: FS"); ESP.restart(); } LoadState(); pinMode(RELAY_PIN, OUTPUT); pinMode(TEMP_SENSOR_PIN, INPUT); Serial.begin(115200); Serial.println("Initialised..."); WiFi.mode(WIFI_STA); WiFi.config(my_ip, gateway, subnet); WiFi.setAutoReconnect(true); WiFi.begin(WIFI_NAME, WIFI_PASS); Serial.print("Connecting"); lcd.print("Connecting..."); delay(500); Serial.println(); last_poll = millis(); mb.server(15000); mb.addHreg(REGISTER_TARGET_T, t_target); mb.addHreg(REGISTER_HYSTERESIS, hyst); mb.addHreg(REGISTER_CUR_TEMP, cur_t); mb.addHreg(REGISTER_CUR_STATE, cur_state); // sensor.begin(); sensor.setResolution(12); } void UpdateCurrent() { sensor.requestTemperatures(); cur_t = int(sensor.getTempCByIndex(0) * 100); last_update = millis(); } unsigned long last_connected = 0; unsigned long last_connecting = 0; void loop() { unsigned long current = millis(); int u = 0; if (current < last_update || current - last_update >= T_UPDATE_INTERVAL) { UpdateCurrent(); u = 1; } mb.task(); t_target = mb.Hreg(REGISTER_TARGET_T); hyst = mb.Hreg(REGISTER_HYSTERESIS); if (cur_t < t_target - hyst) cur_state = 1; else if (cur_t > t_target + hyst) cur_state = 0; mb.Hreg(REGISTER_CUR_STATE, cur_state); digitalWrite(RELAY_PIN, cur_state); if (u) { SaveState(); Serial.println("Cur state"); Serial.println(cur_state); Serial.println(cur_t); lcd.clear(); lcd.setCursor(0, 0); lcd.print("T: "); lcd.print((cur_t) / 100.0, 2); lcd.print(" ("); lcd.print(t_target / 100); lcd.print(")"); lcd.setCursor(0, 1); lcd.print("S: "); lcd.print(cur_state); lcd.print("WiFi: "); lcd.print(WiFi.status()); } mb.Hreg(REGISTER_TARGET_T, t_target); mb.Hreg(REGISTER_HYSTERESIS, hyst); mb.Hreg(REGISTER_CUR_TEMP, cur_t); mb.Hreg(REGISTER_CUR_STATE, cur_state); if (WiFi.status() != WL_CONNECTED) { if (current < last_connecting || current - last_connecting > RECONNECT_TIMEOUT) { WiFi.reconnect(); last_connecting = current; } } else { last_connected = current; } if (current < last_connected || current - last_connected > NON_CONNECTED_REBOOT_TIMEOUT) { SaveState(); ESP.restart(); } }