Added heating. Added "dry work" prevention. More fixes

This commit is contained in:
ftc
2022-09-06 23:25:44 +03:00
parent 9a538ba014
commit 09d416774a
3 changed files with 160 additions and 42 deletions
+145 -35
View File
@@ -9,7 +9,14 @@
#define SENSOR_UPDATE_INTERVAL 500 #define SENSOR_UPDATE_INTERVAL 500
#define SCREEN_UPDATE_INTERVAL 200 #define SCREEN_UPDATE_INTERVAL 200
// Interval between allowed switch-states of the pump // Interval between allowed switch-states of the pump
#define PUMP_SWITCH_INTERVAL 1000 #define PUMP_SWITCH_INTERVAL 5000
// Interval considering "rather long" to work for pump without pressure increase
#define PUMP_UNPRODUCTIVE_TIMEOUT 60000
// amount of pressure what we consider "productive increase" (in 0.01 of bar)
#define PRESSURE_PRODUCTIVE_INCREASE 50
// In fact, pump needs to be able to increase pressure by PRESSURE_PRODUCTIVE_INCREASE
// in PUMP_UNPRODUCTIVE_TIMEOUT time of working
#define MODE_AUTO 0 #define MODE_AUTO 0
#define MODE_MANUAL 1 #define MODE_MANUAL 1
@@ -17,14 +24,22 @@
#define REGISTER_CURRENT_TEMP 0 #define REGISTER_CURRENT_TEMP 0
#define REGISTER_CURRENT_HUM 1 #define REGISTER_CURRENT_HUM 1
#define REGISTER_CURRENT_PRESS 2 #define REGISTER_CURRENT_PRESS 2
#define REGISTER_CUR_STATE 3 #define REGISTER_PUMP_STATE 3
#define REGISTER_MODE 4 #define REGISTER_PUMP_MODE 4
#define REGISTER_P_ON 5 #define REGISTER_P_ON 5
#define REGISTER_P_OFF 6 #define REGISTER_P_OFF 6
#define REGISTER_T_ON 7
#define REGISTER_T_OFF 8
#define REGISTER_HEAT_MODE 9
#define REGISTER_HEAT_STATE 10
#define REGISTER_PUMP_ERROR 11
#define DHTPIN D3 #define DHTPIN D3
#define DHTTYPE AM2301 #define DHTTYPE AM2301
#define PUMP_PIN D4
#define HEATER_PIN D0
ModbusIP mb; ModbusIP mb;
DHT dht(DHTPIN, DHTTYPE); DHT dht(DHTPIN, DHTTYPE);
rgb_lcd lcd; rgb_lcd lcd;
@@ -35,15 +50,23 @@ unsigned long last_update;
int p_on = 150; int p_on = 150;
int p_off = 250; int p_off = 250;
int cur_mode = MODE_AUTO; int cur_pump_mode = MODE_AUTO;
int cur_state = 0; int cur_pump_state = 0;
int cur_p = 0; int cur_p = 0;
int cur_t = 0; int cur_t = 0;
int cur_hum = 0; int cur_hum = 0;
int t_on = 200; // 2 degrees
int t_off = 1500; // 15 degrees
int cur_heat_mode = MODE_AUTO;
int cur_heat_state = 0;
bool error_pump = false;
bool error_heat = false;
void setup() void setup()
{ {
pinMode(D4, OUTPUT); pinMode(PUMP_PIN, OUTPUT);
pinMode(HEATER_PIN, OUTPUT);
pinMode(DHTPIN, INPUT); pinMode(DHTPIN, INPUT);
pinMode(A0, INPUT); pinMode(A0, INPUT);
@@ -75,10 +98,20 @@ void setup()
mb.addHreg(REGISTER_CURRENT_TEMP, cur_t); mb.addHreg(REGISTER_CURRENT_TEMP, cur_t);
mb.addHreg(REGISTER_CURRENT_HUM, cur_hum); mb.addHreg(REGISTER_CURRENT_HUM, cur_hum);
mb.addHreg(REGISTER_CURRENT_PRESS, cur_p); mb.addHreg(REGISTER_CURRENT_PRESS, cur_p);
mb.addHreg(REGISTER_CUR_STATE, cur_state); mb.addHreg(REGISTER_PUMP_STATE, cur_pump_state);
mb.addHreg(REGISTER_MODE, cur_mode); mb.addHreg(REGISTER_PUMP_MODE, cur_pump_mode);
mb.addHreg(REGISTER_P_ON, p_on); mb.addHreg(REGISTER_P_ON, p_on);
mb.addHreg(REGISTER_P_OFF, p_off); mb.addHreg(REGISTER_P_OFF, p_off);
mb.addHreg(REGISTER_T_ON, t_on);
mb.addHreg(REGISTER_T_OFF, t_off);
mb.addHreg(REGISTER_HEAT_STATE, cur_heat_state);
mb.addHreg(REGISTER_HEAT_MODE, cur_heat_mode);
mb.addHreg(REGISTER_PUMP_ERROR, error_pump);
//
Serial.print("Heater pin ");
Serial.println(HEATER_PIN);
Serial.print("Pump pin ");
Serial.println(PUMP_PIN);
} }
@@ -94,9 +127,11 @@ void UpdateDHTData()
// Workings with pressure sensor // Workings with pressure sensor
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
const int MEASURES_AMOUNT = 100; const int MEASURES_AMOUNT = 1000;
int measures[MEASURES_AMOUNT]; int measures[MEASURES_AMOUNT];
int measure_pos = 0; int measure_pos = 0;
// добавка к измеренному значению (поправка на особенности датчика)
float PRESSURE_CALIBRATION = -2;
void UpdatePressure() void UpdatePressure()
{ {
@@ -106,8 +141,9 @@ void UpdatePressure()
float p_volt = (p_int / 1024.0f) * 3.3f; float p_volt = (p_int / 1024.0f) * 3.3f;
// divide by maximal input voltage from sensor (it is 2.5) // divide by maximal input voltage from sensor (it is 2.5)
// and then multiply by sensor max value (10 bar) - we will get pressure in bar // and then multiply by sensor max value (10 bar) - we will get pressure in bar
// also add one atmosphere (1.01325 bar), because sensor reads excess pressure (not absolute)
// finally multiply by 100 as we have int registers // finally multiply by 100 as we have int registers
measures[measure_pos] = (int)(((p_volt / 2.5f) * 10) * 100); measures[measure_pos] = (int)(((p_volt / 2.5f) * 10 + 1.01325) * 100);
measure_pos++; measure_pos++;
// We will use average of MEASURES_AMOUNT last sensor readings // We will use average of MEASURES_AMOUNT last sensor readings
// excluding minimal and maximal value (to get rid of peaks) // excluding minimal and maximal value (to get rid of peaks)
@@ -125,7 +161,7 @@ void UpdatePressure()
if (i == min_pos || i == max_pos) continue; if (i == min_pos || i == max_pos) continue;
sum += measures[i]; sum += measures[i];
} }
cur_p = sum / (MEASURES_AMOUNT - 2); cur_p = sum / (MEASURES_AMOUNT - 2) + PRESSURE_CALIBRATION * 100;
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -145,51 +181,114 @@ void UpdateDisplay()
lcd.setCursor(0, 1); lcd.setCursor(0, 1);
lcd.print("H: "); lcd.print("H: ");
lcd.print(cur_hum / 100); lcd.print(cur_hum / 100);
lcd.print(" WiFi: "); if (error_pump)
lcd.print(WiFi.status());
// print current error
//
if (cur_state)
{ {
lcd.setRGB(0, 0, 255); lcd.print(" PUMP ERR");
} }
else else
{ {
lcd.setRGB(0, 255, 0); lcd.print(" WiFi: ");
lcd.print(WiFi.status());
}
//
if (error_pump)
{
lcd.setRGB(255, 0, 0);
}
else
{
if (cur_pump_state)
{
lcd.setRGB(0, 0, 255);
}
else
{
lcd.setRGB(0, 255, 0);
}
} }
last_screen_update = current; last_screen_update = current;
} }
} }
unsigned long last_pump_switch = 0; unsigned long last_pump_switch = 0;
unsigned long last_pump_on = 0;
int last_pump_p = 0;
void UpdatePump() void UpdatePump()
{ {
unsigned long current = millis(); unsigned long current = millis();
int new_state = cur_state; int new_state = cur_pump_state;
if (cur_mode == MODE_AUTO) if (cur_pump_mode == MODE_AUTO)
{ {
if (cur_p < p_on) new_state = 1; if (cur_p < p_on) new_state = 1;
else if (cur_p > p_off) new_state = 0; else if (cur_p > p_off) new_state = 0;
if ((current < last_pump_switch || current - last_pump_switch > PUMP_SWITCH_INTERVAL) if ((current < last_pump_switch || current - last_pump_switch > PUMP_SWITCH_INTERVAL)
&& new_state != cur_state) && new_state != cur_pump_state
&& cur_t > t_on) // turning on pump only if temperature is high enough
{ {
Serial.print("CHANGE STATE "); Serial.print("CHANGE STATE ");
Serial.print(cur_p); Serial.print(cur_p);
Serial.print(" "); Serial.print(" ");
Serial.print(p_on); Serial.print(p_on);
Serial.print(" "); Serial.print(" ");
Serial.print(p_off); Serial.print(p_off);
cur_state = new_state; cur_pump_state = new_state;
mb.Hreg(REGISTER_CUR_STATE, cur_state); mb.Hreg(REGISTER_PUMP_STATE, cur_pump_state);
last_pump_switch = current; last_pump_switch = current;
if (new_state == 1)
{
last_pump_on = current;
last_pump_p = cur_p;
}
} }
} }
else else
{ {
cur_state = mb.Hreg(REGISTER_CUR_STATE); cur_pump_state = mb.Hreg(REGISTER_PUMP_STATE);
} }
digitalWrite(D4, cur_state); if (error_pump)
{
cur_pump_state = 0;
}
digitalWrite(PUMP_PIN, cur_pump_state);
// check for unproductive
if (cur_pump_state == 1)
{
if (current < last_pump_on || current - last_pump_on >= PUMP_UNPRODUCTIVE_TIMEOUT)
{
if (cur_p - last_pump_p < PRESSURE_PRODUCTIVE_INCREASE)
{
error_pump = true;
cur_pump_state = 0;
}
else
{
// the pump is working, will perform new check in PUMP_UNPRODUCTIVE_TIMEOUT
last_pump_p = cur_p;
last_pump_on = current;
}
}
}
}
void UpdateHeater()
{
int new_state = cur_heat_state;
if (cur_heat_mode == MODE_AUTO)
{
if (cur_t < t_on) new_state = 1;
else if (cur_t > t_off) new_state = 0;
if (new_state != cur_heat_state)
{
cur_heat_state = new_state;
mb.Hreg(REGISTER_HEAT_STATE, cur_heat_state);
}
}
else
{
cur_heat_state = mb.Hreg(REGISTER_HEAT_STATE);
}
digitalWrite(HEATER_PIN, cur_heat_state);
} }
void loop() void loop()
@@ -206,8 +305,13 @@ void loop()
mb.task(); mb.task();
p_on = mb.Hreg(REGISTER_P_ON); p_on = mb.Hreg(REGISTER_P_ON);
p_off = mb.Hreg(REGISTER_P_OFF); p_off = mb.Hreg(REGISTER_P_OFF);
cur_mode = mb.Hreg(REGISTER_MODE); cur_pump_mode = mb.Hreg(REGISTER_PUMP_MODE);
t_on = mb.Hreg(REGISTER_T_ON);
t_off = mb.Hreg(REGISTER_T_OFF);
cur_heat_mode = mb.Hreg(REGISTER_HEAT_MODE);
error_pump= mb.Hreg(REGISTER_PUMP_ERROR);
UpdatePump(); UpdatePump();
UpdateHeater();
if (u) if (u)
{ {
Serial.print("Current pressure: "); Serial.print("Current pressure: ");
@@ -216,15 +320,21 @@ void loop()
Serial.print(cur_t); Serial.print(cur_t);
Serial.print(" h "); Serial.print(" h ");
Serial.print(cur_hum); Serial.print(cur_hum);
Serial.print(" state "); Serial.print(" pump ");
Serial.println(cur_state); Serial.print(cur_pump_state);
Serial.print(" heat ");
Serial.println(cur_heat_state);
} }
mb.Hreg(REGISTER_P_ON, p_on); mb.Hreg(REGISTER_P_ON, p_on);
mb.Hreg(REGISTER_P_OFF, p_off); mb.Hreg(REGISTER_P_OFF, p_off);
mb.Hreg(REGISTER_MODE, cur_mode); mb.Hreg(REGISTER_PUMP_MODE, cur_pump_mode);
mb.Hreg(REGISTER_T_ON, t_on);
mb.Hreg(REGISTER_T_OFF, t_off);
mb.Hreg(REGISTER_HEAT_MODE, cur_heat_mode);
mb.Hreg(REGISTER_CURRENT_TEMP, cur_t); mb.Hreg(REGISTER_CURRENT_TEMP, cur_t);
mb.Hreg(REGISTER_CURRENT_HUM, cur_hum); mb.Hreg(REGISTER_CURRENT_HUM, cur_hum);
mb.Hreg(REGISTER_CURRENT_PRESS, cur_p); mb.Hreg(REGISTER_CURRENT_PRESS, cur_p);
mb.Hreg(REGISTER_PUMP_ERROR, error_pump);
UpdateDisplay(); UpdateDisplay();
if (WiFi.status() != WL_CONNECTED) if (WiFi.status() != WL_CONNECTED)
{ {
+8 -4
View File
@@ -1,7 +1,11 @@
Number Well_P_on "Well turn on pressure [%.2f]" {channel="modbus:data:Well:W:Well_P_on:number"} Number Well_P_on "Well pump turn on pressure [%.2f]" {channel="modbus:data:Well:W:Well_P_on:number"}
Number Well_P_off "Well turn off temperature [%.2f]" {channel="modbus:data:Well:W:Well_P_off:number"} Number Well_P_off "Well pump turn off pressure [%.2f]" {channel="modbus:data:Well:W:Well_P_off:number"}
Number Well_P "Well current pressure [%.2f]" <temperature> {channel="modbus:data:Well:W:Well_P:number"} Number Well_P "Well current pressure [%.2f]" <temperature> {channel="modbus:data:Well:W:Well_P:number"}
Number Well_Temp "Well temperature [%.1f °C]" <temperature> {channel="modbus:data:Well:W:Well_Temp:number"} Number Well_Temp "Well temperature [%.1f °C]" <temperature> {channel="modbus:data:Well:W:Well_Temp:number"}
Number Well_Hum "Well humidity [%.1f%%]" <humidity> {channel="modbus:data:Well:W:Well_Hum:number"} Number Well_Hum "Well humidity [%.1f%%]" <humidity> {channel="modbus:data:Well:W:Well_Hum:number"}
Number Well_Mode "Well mode" <switch> {channel="modbus:data:Well:W:Well_Mode:number"} Number Well_Pump_Mode "Well pump mode" <switch> {channel="modbus:data:Well:W:Well_Pump_Mode:number"}
Switch Well_State "Well state" <switch> {channel="modbus:data:Well:W:Well_State:switch"} Switch Well_Pump_State "Well pump state" <switch> {channel="modbus:data:Well:W:Well_Pump_State:switch"}
Number Well_T_on "Well turn on heater [%.2f]" {channel="modbus:data:Well:W:Well_T_on:number"}
Number Well_T_off "Well turn off temperature [%.2f]" {channel="modbus:data:Well:W:Well_T_off:number"}
Number Well_Heat_Mode "Well heater mode" <switch> {channel="modbus:data:Well:W:Well_Heat_Mode:number"}
Switch Well_Heat_State "Well heater state" <switch> {channel="modbus:data:Well:W:Well_Heat_State:switch"}
+7 -3
View File
@@ -1,11 +1,15 @@
Bridge modbus:tcp:Well [ host="192.168.0.24", port=15000, id=1 ] { Bridge modbus:tcp:Well [ host="192.168.0.24", port=15000, id=1 ] {
Bridge poller W[start = 0, length = 7, type = "holding", refresh = 500] { Bridge poller W[start = 0, length = 11, type = "holding", refresh = 500] {
Thing data Well_Temp[readStart = "0", readValueType = "int16", readTransform="JS(divide100.js)"] Thing data Well_Temp[readStart = "0", readValueType = "int16", readTransform="JS(divide100.js)"]
Thing data Well_Hum[readStart = "1", readValueType = "int16", readTransform="JS(divide100.js)"] Thing data Well_Hum[readStart = "1", readValueType = "int16", readTransform="JS(divide100.js)"]
Thing data Well_P[readStart = "2", readValueType = "int16", readTransform="JS(divide100.js)"] Thing data Well_P[readStart = "2", readValueType = "int16", readTransform="JS(divide100.js)"]
Thing data Well_State[readStart = "3", readValueType = "int16", writeStart="3", writeValueType="int16", writeType="holding"] Thing data Well_Pump_State[readStart = "3", readValueType = "int16", writeStart="3", writeValueType="int16", writeType="holding"]
Thing data Well_Mode[readStart = "4", readValueType = "int16", writeStart="4", writeValueType="int16", writeType="holding"] Thing data Well_Pump_Mode[readStart = "4", readValueType = "int16", writeStart="4", writeValueType="int16", writeType="holding"]
Thing data Well_P_on[readStart = "5", readValueType = "int16", readTransform="JS(divide100.js)", writeStart="5", writeValueType="int16", writeTransform="JS(multiply100.js)", writeType="holding"] Thing data Well_P_on[readStart = "5", readValueType = "int16", readTransform="JS(divide100.js)", writeStart="5", writeValueType="int16", writeTransform="JS(multiply100.js)", writeType="holding"]
Thing data Well_P_off[readStart = "6", readValueType = "int16", readTransform="JS(divide100.js)", writeStart="6", writeValueType="int16", writeTransform="JS(multiply100.js)", writeType="holding"] Thing data Well_P_off[readStart = "6", readValueType = "int16", readTransform="JS(divide100.js)", writeStart="6", writeValueType="int16", writeTransform="JS(multiply100.js)", writeType="holding"]
Thing data Well_T_on[readStart = "7", readValueType = "int16", readTransform="JS(divide100.js)", writeStart="7", writeValueType="int16", writeTransform="JS(multiply100.js)", writeType="holding"]
Thing data Well_T_off[readStart = "8", readValueType = "int16", readTransform="JS(divide100.js)", writeStart="8", writeValueType="int16", writeTransform="JS(multiply100.js)", writeType="holding"]
Thing data Well_Heat_Mode[readStart = "9", readValueType = "int16", writeStart="9", writeValueType="int16", writeType="holding"]
Thing data Well_Heat_State[readStart = "10", readValueType = "int16", writeStart="10", writeValueType="int16", writeType="holding"]
} }
} }