Hello friends,
My goal: I want to control the pH value of my pool automaticly. For this i have a probe in my pool, that measues every x - interval the pH. Two pumps can dose a solution either to get the pH up or get the ph down, to a given setpoint. Long story short, fot this i coded myself a three-point-controller which will run on my esp32 in the loop.
i would realy appreciate if someone can control my function if there are some flaws, errors or nonsense. My first real-life testings seems positive. But since i dont wanna ruin my whole pool, i would prefer nor error.
Hopefully my code can help anyone for their applications=).
void threePointController(float hysteresis, float setpoint, int deadTime, int controlTime) {
float measurement;
// Depending on what sensor was chosen, it will use it as the source
// Note: The switch-case block is commented out; consider removing it if not needed.
// switch(mySettings.sensorSelect) {
// case 0:
// return;
// case 1:
measurement = mySettings.sensor_3_int;
// break;
// }
if (mySettings.controllerOnOff == 0) {
// If the controller is turned off, set relays off and update display
digitalWrite(RELAY_DOWN, 0);
digitalWrite(RELAY_UP, 0);
myNex.writeStr("page1.q4.picc=0");
}
// Start the three-point controller
if (mySettings.controllerOnOff == 1) {
static bool relayStatus = 1; // Relay status: false = OFF, true = ON
static int controlDirection = 0; // 0 = neutral, 1 = downward, 2 = upward
float upperLimit = setpoint + hysteresis;
float lowerLimit = setpoint - hysteresis;
int pump_DOWN = RELAY_DOWN;
int pump_UP = RELAY_UP;
if (relayStatus == 1) { // If relay is ON (controller is active), check time
if (millis() - Loop_Timer_tpc > controlTime) {
// If time exceeds controlTime, turn off the controller
myNex.writeStr("page1.q4.picc=0");
relayStatus = 0; // Relay OFF
digitalWrite(pump_UP, 0);
digitalWrite(pump_DOWN, 0);
Loop_Timer_tpc = millis();
}
} else if (relayStatus == 0) { // If relay is OFF (controller is inactive), check for deadTime
if (millis() - Loop_Timer_tpc > deadTime) {
if (measurement >= upperLimit) {
// If "measurement" exceeds upper hysteresis, turn the relay ON (controller active)
relayStatus = 1;
digitalWrite(pump_UP, 0);
digitalWrite(pump_DOWN, 1);
controlDirection = 1;
myNex.writeStr("page1.q4.picc=27");
Loop_Timer_tpc = millis();
} else if (measurement > setpoint && controlDirection == 1) {
// If "measurement" is above setpoint and controlling downward, continue controlling downward
relayStatus = 1;
digitalWrite(pump_UP, 0);
digitalWrite(pump_DOWN, 1);
myNex.writeStr("page1.q4.picc=27");
Loop_Timer_tpc = millis();
} else if (measurement <= setpoint && controlDirection == 1) {
// If "measurement" reaches setpoint while controlling downward, stop the controller
relayStatus = 1;
digitalWrite(pump_UP, 0);
digitalWrite(pump_DOWN, 0);
controlDirection = 0;
myNex.writeStr("page1.q4.picc=0");
Loop_Timer_tpc = millis();
} else if (measurement <= lowerLimit) {
// If "measurement" violates lower hysteresis, turn the relay ON (controller active)
relayStatus = 1;
digitalWrite(pump_UP, 1);
digitalWrite(pump_DOWN, 0);
controlDirection = 2;
myNex.writeStr("page1.q4.picc=27");
Loop_Timer_tpc = millis();
} else if (measurement < setpoint && controlDirection == 2) {
// If "measurement" is below setpoint and controlling upward, continue controlling upward
relayStatus = 1;
digitalWrite(pump_UP, 1);
digitalWrite(pump_DOWN, 0);
myNex.writeStr("page1.q4.picc=27");
Loop_Timer_tpc = millis();
} else if (measurement >= setpoint && controlDirection == 2) {
// If "measurement" reaches setpoint while controlling upward, stop the controller
relayStatus = 1;
digitalWrite(pump_UP, 0);
digitalWrite(pump_DOWN, 0);
controlDirection = 0;
myNex.writeStr("page1.q4.picc=0");
Loop_Timer_tpc = millis();
}
}
}
}
}