firmware wip - growher.ch post

add changes from https://www.grower.ch/forum/threads/diy-grow-controller-cangrow-projektvorstellung.163654/page-2#post-4153636
introduce invert output system config option
This commit is contained in:
DeltaLima 2024-12-05 02:05:39 +01:00
parent 461b816115
commit 26a0c6603d
5 changed files with 73 additions and 34 deletions

View file

@ -100,7 +100,8 @@ void setup() {
Serial.println(":: initialise I2C ::"); Serial.println(":: initialise I2C ::");
// initialise Wire for I2C // initialise Wire for I2C
Wire.begin(); Wire.begin();
Wire.setClockStretchLimit(2500); // ClockStretchLimit seems to have negative effects
//Wire.setClockStretchLimit(2500);
Serial.println(":: initialise display ::"); Serial.println(":: initialise display ::");
// initialise I2C display // initialise I2C display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x64 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x64
@ -241,6 +242,8 @@ void loop() {
controlPUMP(); controlPUMP();
controlFAN();
displayScreens(); displayScreens();
// current time gets previous time for new interval // current time gets previous time for new interval

View file

@ -109,6 +109,7 @@ unsigned short MaintenanceDuration = 300;
char Esp32CamIP[16]; char Esp32CamIP[16];
// PumpLastOn (long) timestamp // PumpLastOn (long) timestamp
unsigned long PumpLastOn; unsigned long PumpLastOn;
bool OutputInvert;

View file

@ -107,7 +107,8 @@ bool loadEEPROM() {
* 237 PumpLastOn (4 byte) * 237 PumpLastOn (4 byte)
* 241 PumpIntervalVeg (1 byte) * 241 PumpIntervalVeg (1 byte)
* 242 PumpIntervalBloom (1 byte) * 242 PumpIntervalBloom (1 byte)
* 243 ... * 243 OutputInvert (1 byte)
* 244 ...
* *
*/ */
@ -173,7 +174,9 @@ bool loadEEPROM() {
EEPROM.get(221, Esp32CamIP); EEPROM.get(221, Esp32CamIP);
// size is 4 byte // size is 4 byte
EEPROM.get(237, PumpLastOn); EEPROM.get(237, PumpLastOn);
// size is 1 byte
EEPROM.get(243, OutputInvert);
} }
// TODO auth does not work atm // TODO auth does not work atm
// EEPROM.get(160, WebUiUsername); // EEPROM.get(160, WebUiUsername);
@ -250,6 +253,10 @@ bool loadEEPROM() {
Serial.println(UseFANrelais); Serial.println(UseFANrelais);
Serial.print("MaintenanceDuration: "); Serial.print("MaintenanceDuration: ");
Serial.println(MaintenanceDuration); Serial.println(MaintenanceDuration);
Serial.print("PumpLastOn: ");
Serial.println(PumpLastOn);
Serial.print("OutputInvert: ");
Serial.println(OutputInvert);
Serial.println("---- Grow values ----"); Serial.println("---- Grow values ----");
Serial.print("GrowName: "); Serial.print("GrowName: ");
@ -396,7 +403,7 @@ unsigned short growState() {
void setOutput(byte Output, byte OutputState) { void setOutput(byte Output, byte OutputState) {
/* /*
* Pin assignments * Output assignments
* *
* 1 - LED * 1 - LED
* 2 - FAN * 2 - FAN
@ -405,6 +412,7 @@ void setOutput(byte Output, byte OutputState) {
*/ */
bool UseRelais = true; bool UseRelais = true;
byte OutputPin; byte OutputPin;
byte OutputState_tmp;
switch(Output) { switch(Output) {
case 1: case 1:
@ -438,10 +446,22 @@ void setOutput(byte Output, byte OutputState) {
//~ Serial.print("UseRelais: "); //~ Serial.print("UseRelais: ");
//~ Serial.println(UseRelais); //~ Serial.println(UseRelais);
// TODO read config for inverted outputs
if( (UseRelais == true) || (OutputPin == PinPUMP) ) { if( (UseRelais == true) || (OutputPin == PinPUMP) ) {
digitalWrite(OutputPin, 1 - OutputState); if(OutputInvert == true) {
OutputState_tmp = 1 - OutputState;
} else {
OutputState_tmp = OutputState;
}
digitalWrite(OutputPin, OutputState_tmp);
} else { } else {
analogWrite(OutputPin, 255 - OutputState); if(OutputInvert == true) {
OutputState_tmp = 255 - OutputState;
} else {
OutputState_tmp = OutputState;
}
analogWrite(OutputPin, OutputState_tmp);
} }
} }
@ -676,7 +696,7 @@ void controlPUMP() {
switch(UsePump) { switch(UsePump) {
case 1: case 1:
// when diff of time now and time pumpLastOn is greater then PumpInterval, do some watering (Or manual watering) // when diff of time now and time pumpLastOn is greater then PumpInterval, do some watering (Or manual watering)
if( (timeClient.getEpochTime() - PumpLastOn) >= (PumpInterval) ) { // TODO: * 24 * 60 * 60 PumpInterval if( (timeClient.getEpochTime() - PumpLastOn) >= (PumpInterval * 24 * 60 *60) ) { // PumpInterval to, Days * 24 * 60 * 60
// only water as long PumpOnTime // only water as long PumpOnTime
if(PumpOnTimePassed < PumpOnTime) { if(PumpOnTimePassed < PumpOnTime) {
setOutput(3, 1); setOutput(3, 1);
@ -688,6 +708,7 @@ void controlPUMP() {
PumpLastOn = timeClient.getEpochTime(); PumpLastOn = timeClient.getEpochTime();
// write the value to EEPROM for the case ESP gets restarted // write the value to EEPROM for the case ESP gets restarted
EEPROM.put(237, PumpLastOn); EEPROM.put(237, PumpLastOn);
EEPROM.commit(); //write to EEPROM
PumpOnTimePassed = 0; PumpOnTimePassed = 0;
} }
} else { } else {
@ -719,9 +740,9 @@ void controlPUMP() {
// //
case 3: case 3:
if( ( (timeClient.getEpochTime() - PumpLastOn) >= (PumpInterval) ) && //TODO calculate PumpInterval into days as well here if( ( (timeClient.getEpochTime() - PumpLastOn) >= (PumpInterval * 24 * 60 *60) ) && // PumpInterval to, Days * 24 * 60 * 60
( (valSoilmoistureAvg < SoilmoistureLow) || ( (valSoilmoistureAvg < SoilmoistureLow) ||
( (valSoilmoistureAvg >= SoilmoistureLow) && ( (PumpOnTimePassed > 0) && (PumpOnTimePassed <= PumpOnTime) ) ) ( (valSoilmoistureAvg >= SoilmoistureLow) && ( (PumpOnTimePassed > 0) && (PumpOnTimePassed <= PumpOnTime) ) )
) ) { ) ) {
// check if we alerady exceeded max PumpOnTime // check if we alerady exceeded max PumpOnTime
if(PumpOnTimePassed < PumpOnTime) { if(PumpOnTimePassed < PumpOnTime) {
@ -750,3 +771,9 @@ void controlPUMP() {
//digitalWrite(PinPUMP, LOW); //digitalWrite(PinPUMP, LOW);
} }
} }
void controlFAN() {
setOutput(2, PinFANPWM); //inverted pwm
}

View file

@ -1,5 +1,5 @@
/* CanGrow_Version.h gets generated from cangrow.sh */ /* CanGrow_Version.h gets generated from cangrow.sh */
const char* CanGrowVer = "0.1-dev"; const char* CanGrowVer = "0.1-dev";
const char* CanGrowBuild = "d2e264d-20240919022041"; const char* CanGrowBuild = "461b816-20241205020134";

View file

@ -498,15 +498,20 @@ void WEBgrowSettings() {
body+= "' required> Minutes<br>\n"; body+= "' required> Minutes<br>\n";
if(UseLEDrelais == false) { if(UseLEDrelais == false) {
body += "LED brightness: <input type='range' id='PinLEDPWM' name='PinLEDPWM' min='1' max='255' value='"; body += "LED brightness: <input type='range' id='PinLEDPWM' name='PinLEDPWM' min='0' max='255' value='";
body += PinLEDPWM; body += PinLEDPWM;
body += "'/> %<br>\n"; body += "'/> %<br>\n";
} }
if(UseFANrelais == false) { if(UseFANrelais == false) {
body += "FAN speed: <input type='range' id='PinFANPWM' name='PinFANPWM' min='1' max='255' value='"; body += "FAN speed: <input type='range' id='PinFANPWM' name='PinFANPWM' min='0' max='255' value='";
body += PinFANPWM; body += PinFANPWM;
body += "'/> %<br>\n"; body += "'/> %<br>\n";
} else {
body += "FAN on/off: <select id='PinFANPWM' name='PinFANPWM' required>\n";
body += "<option value='1'" + returnStrSelected(PinFANPWM, 1) + ">Yes</option>\n";
body += "<option value='0'" + returnStrSelected(PinFANPWM, 0) + ">No</option>\n";
body += "</select><br>\n";
} }
@ -559,12 +564,12 @@ void WEBsystemSettings() {
body += "<form method='post' action='/systemSettings/save'>\n"; body += "<form method='post' action='/systemSettings/save'>\n";
// UseFan bool // UseFan bool
body += "Fan mode: <select id='UseFan' name='UseFan' required>\n"; //~ body += "Fan mode: <select id='UseFan' name='UseFan' required>\n";
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";} //~ if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
body += "<option value='1'" + returnStrSelected(UseFan, 0) + ">Off</option>\n"; //~ body += "<option value='1'" + returnStrSelected(UseFan, 0) + ">Off</option>\n";
body += "<option value='1'" + returnStrSelected(UseFan, 1) + ">Use</option>\n"; //~ body += "<option value='1'" + returnStrSelected(UseFan, 1) + ">Use</option>\n";
body += "<option value='0'" + returnStrSelected(UseFan, 2) + ">Do not use</option>\n"; //~ body += "<option value='0'" + returnStrSelected(UseFan, 2) + ">Do not use</option>\n";
body += "</select><br>\n"; //~ body += "</select><br>\n";
/* /*
// UsePump bool // UsePump bool
@ -584,7 +589,16 @@ void WEBsystemSettings() {
body += "</select><br><p class='helpbox'><b>1:</b> Water every few days.<br> \ body += "</select><br><p class='helpbox'><b>1:</b> Water every few days.<br> \
<b>2:</b> Water if the soil moisture falls below <i>Soilmoisture low</i> value<br> \ <b>2:</b> Water if the soil moisture falls below <i>Soilmoisture low</i> value<br> \
<b>3:</b> Water every few days if the soil moisture falls below <i>Soilmoisture low</i> value.</p>\n"; <b>3:</b> Water every few days if the soil moisture falls below <i>Soilmoisture low</i> value.</p>\n";
// OutputInvert bool
body += "Invert Outputs: <select id='OutputInvert' name='OutputInvert' required>\n";
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
body += "<option value='1'" + returnStrSelected(OutputInvert, 1) + ">Yes</option>\n";
body += "<option value='0'" + returnStrSelected(OutputInvert, 0) + ">No</option>\n";
body += "</select><br>\n";
// UseLEDrelais bool // UseLEDrelais bool
body += "Use relais for LED: <select id='UseLEDrelais' name='UseLEDrelais' required>\n"; body += "Use relais for LED: <select id='UseLEDrelais' name='UseLEDrelais' required>\n";
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";} if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
@ -742,14 +756,7 @@ void POSTgrowSettings() {
PinLEDPWM = webserver.arg("PinLEDPWM").toInt(); PinLEDPWM = webserver.arg("PinLEDPWM").toInt();
} }
if(UseFANrelais == true) { PinFANPWM = webserver.arg("PinFANPWM").toInt();
// if a relais is used to turn on grow light, we force PWM to max val
PinFANPWM = 255;
} else {
// otherwise just do PWM
PinFANPWM = webserver.arg("PinFANPWM").toInt();
}
String GrowName_tmp = webserver.arg("GrowName"); String GrowName_tmp = webserver.arg("GrowName");
GrowName_tmp.toCharArray(GrowName, 32); GrowName_tmp.toCharArray(GrowName, 32);
@ -841,7 +848,7 @@ void POSTsystemSettings() {
MaintenanceDuration = webserver.arg("MaintenanceDuration").toInt(); MaintenanceDuration = webserver.arg("MaintenanceDuration").toInt();
String Esp32CamIP_tmp = webserver.arg("Esp32CamIP"); String Esp32CamIP_tmp = webserver.arg("Esp32CamIP");
Esp32CamIP_tmp.toCharArray(Esp32CamIP, 221); Esp32CamIP_tmp.toCharArray(Esp32CamIP, 221);
OutputInvert = webserver.arg("OutputInvert").toInt();
configured = true; configured = true;
@ -867,6 +874,7 @@ void POSTsystemSettings() {
EEPROM.put(215, UseFANrelais); EEPROM.put(215, UseFANrelais);
EEPROM.put(219, MaintenanceDuration); EEPROM.put(219, MaintenanceDuration);
EEPROM.put(221, Esp32CamIP); EEPROM.put(221, Esp32CamIP);
EEPROM.put(243, OutputInvert);
// write data to EEPROM // write data to EEPROM
EEPROM.commit(); EEPROM.commit();
@ -888,12 +896,12 @@ void POSTsystemSettings() {
Serial.println("UseLEDrelais is 1, forcing PinLEDPWM to max to prevent relais damage"); Serial.println("UseLEDrelais is 1, forcing PinLEDPWM to max to prevent relais damage");
} }
if(UseFANrelais == true) { //~ if(UseFANrelais == true) {
PinFANPWM = 255; //~ PinFANPWM = 255;
EEPROM.put(215, PinFANPWM); //~ EEPROM.put(215, PinFANPWM);
EEPROM.commit(); //~ EEPROM.commit();
Serial.println("UseFANrelais is 1, forcing PinFANPWM to max to prevent relais damage"); //~ Serial.println("UseFANrelais is 1, forcing PinFANPWM to max to prevent relais damage");
} //~ }
Serial.print("configured: "); Serial.print("configured: ");
Serial.println(configured); Serial.println(configured);