Added heating. Added "dry work" prevention. More fixes
This commit is contained in:
+134
-24
@@ -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,11 +181,23 @@ 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);
|
||||||
|
if (error_pump)
|
||||||
|
{
|
||||||
|
lcd.print(" PUMP ERR");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
lcd.print(" WiFi: ");
|
lcd.print(" WiFi: ");
|
||||||
lcd.print(WiFi.status());
|
lcd.print(WiFi.status());
|
||||||
// print current error
|
}
|
||||||
//
|
//
|
||||||
if (cur_state)
|
if (error_pump)
|
||||||
|
{
|
||||||
|
lcd.setRGB(255, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cur_pump_state)
|
||||||
{
|
{
|
||||||
lcd.setRGB(0, 0, 255);
|
lcd.setRGB(0, 0, 255);
|
||||||
}
|
}
|
||||||
@@ -157,22 +205,26 @@ void UpdateDisplay()
|
|||||||
{
|
{
|
||||||
lcd.setRGB(0, 255, 0);
|
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);
|
||||||
@@ -180,16 +232,63 @@ void UpdatePump()
|
|||||||
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
@@ -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
@@ -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"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user