205 lines
4.2 KiB
Arduino
205 lines
4.2 KiB
Arduino
#include <OneWire.h>
|
|
#include <DallasTemperature.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <ModbusIP_ESP8266.h>
|
|
#include "config.h"
|
|
#include "LittleFS.h"
|
|
#include <LiquidCrystal_I2C.h>
|
|
|
|
// Display
|
|
#define LCD_COLUMNS 16
|
|
#define LCD_ROWS 2
|
|
#define LCD_ADDRESS 0x27
|
|
|
|
#define RELAY_PIN D7
|
|
#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 MODE_OFF 0
|
|
#define MODE_ON 1
|
|
|
|
#define REGISTER_TARGET_T 0
|
|
#define REGISTER_HYSTERESIS 1
|
|
#define REGISTER_CUR_TEMP 2
|
|
#define REGISTER_CUR_STATE 3
|
|
#define REGISTER_MODE 4
|
|
|
|
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;
|
|
int mode = 1;
|
|
|
|
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());
|
|
s = f.readStringUntil('\n');
|
|
mode = 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.println(mode);
|
|
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);
|
|
mb.addHreg(REGISTER_MODE, mode);
|
|
//
|
|
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);
|
|
mode = mb.Hreg(REGISTER_MODE);
|
|
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);
|
|
if (mode == MODE_OFF)
|
|
{
|
|
cur_state = 0;
|
|
}
|
|
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(") ");
|
|
if (mode == MODE_ON) lcd.print("ON");
|
|
else lcd.print("OFF");
|
|
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();
|
|
}
|
|
}
|