firmware WIP

This commit is contained in:
Marcus 2024-04-13 19:02:12 +02:00
parent 349e9822d8
commit dc10435d81

View file

@ -1,19 +1,6 @@
/* /*
* CanGrow - simply DIY automatic plant grow system (for cannabis). * CanGrow - simply DIY automatic plant grow system (for cannabis).
* *
* Pin assignment
* ==============
*
* D0 - MOSFET Fan
* D1, D2 - I2C
* D3 - DHT11
* D5 - MOSFET Pump
* D6 - MOSFET Grow LED, PWM
* D7 - waterlevel (set HIGH to read value)
* D8 - analog soil moisture (set HIGH to read value)
* A0 - analog input for soil moisture and waterlevel readings
*
* D4 and D7 cannot be HIGH at the same time!
*/ */
/* /*
@ -39,11 +26,6 @@
* *
*/ */
// When D4 is LOW at start, WIPE is true and EEPROM get cleared
// D4 hast to be shorted to GND withing the 2 sec delay in setup();
// DO NOT PULL D4 DOWN AT START/POWER ON !!! BOOT WILL FAIL
bool WIPE;
// valSoilmoisture - contains the value of getSoilmoisture() // valSoilmoisture - contains the value of getSoilmoisture()
byte valSoilmoisture; byte valSoilmoisture;
// valTemperature - contains the value of getTemperature() // valTemperature - contains the value of getTemperature()
@ -63,8 +45,14 @@ float valHumidity;
bool configured; bool configured;
char WIFIssid[32]; char WIFIssid[32];
char WIFIpassword[64]; char WIFIpassword[64];
IPAddress WIFIip(192,168,4,20);
IPAddress WIFInetmask(255,255,255,0);
IPAddress WIFIgateway(192,168,4,254);
// GrowName - contains the name of the grow/plant. Up to 32 byte
char GrowName[32];
// GrowStart - contains unix timestamp from date where grow starts (00:00) // GrowStart - contains unix timestamp from date where grow starts (00:00)
// unsigned long is 4 byte
unsigned long GrowStart; unsigned long GrowStart;
// DayOfGrow contains on which day the grow is // DayOfGrow contains on which day the grow is
byte DayOfGrow; byte DayOfGrow;
@ -76,8 +64,7 @@ byte DaysBloom;
byte LighthoursVeg; byte LighthoursVeg;
// LighthoursBloom - contains how many hours the Growlight is on in Bloom // LighthoursBloom - contains how many hours the Growlight is on in Bloom
byte LighthoursBloom; byte LighthoursBloom;
// GrowName - contains the name of the grow/plant. Up to 32 byte
char GrowName[32];
// Sunrise - contains to which hour of day the growlight turns on // Sunrise - contains to which hour of day the growlight turns on
byte Sunrise; byte Sunrise;
// PINled_PWM - contains the PWM value for dimming the grow light // PINled_PWM - contains the PWM value for dimming the grow light
@ -89,7 +76,7 @@ byte MoistureSensor_Type;
// UsePump - is the pump used? bool // UsePump - is the pump used? bool
bool UsePump; bool UsePump;
// UseFan - is the fan used? bool // UseFan - is the fan used? bool
bool UseFan bool UseFan;
// SoilmoistureLow - contains the value , when soil moisture is assumed to be low, // SoilmoistureLow - contains the value , when soil moisture is assumed to be low,
byte SoilmoistureLow; byte SoilmoistureLow;
@ -107,11 +94,6 @@ byte SoilmoistureLow;
const char *APssid = "CanGrow-unconfigured"; const char *APssid = "CanGrow-unconfigured";
const char *APpass = "CanGrow"; const char *APpass = "CanGrow";
IPAddress WIFIip(192,168,4,20);
IPAddress WIFInetmask(255,255,255,0);
IPAddress WIFIgateway(192,168,4,254);
/* /*
* *
@ -137,8 +119,20 @@ const char HTMLfooter[] PROGMEM = R"EOF(
)EOF"; )EOF";
/* /*
*
* Pin assignments * Pin assignments
* *
* D0 - MOSFET Fan
* D1, D2 - I2C
* D3 - DHT11
* D4 - PIN_WIPE
* D5 - MOSFET Pump
* D6 - MOSFET Grow LED, PWM
* D7 - waterlevel (set HIGH to read value)
* D8 - analog soil moisture (set HIGH to read value)
* A0 - analog input for soil moisture and waterlevel readings
*
* D4 and D7 cannot be HIGH at the same time!
*/ */
// D0 is HIGH at boot, no PWM // D0 is HIGH at boot, no PWM
@ -146,7 +140,8 @@ const uint8_t PINfan = D0;
// If D3 is pulled to LOW, boot fails // If D3 is pulled to LOW, boot fails
const uint8_t PINdht = D3; const uint8_t PINdht = D3;
// D4 is HIGH at boot, boot fail if pulled to LOW // D4 is HIGH at boot, boot fail if pulled to LOW
// PIN_WIPE set to HIGH at start erases the EEPROM saved data // During Start Screen you can pull D4 to LOW to wipe saved data in EEPROM
// DO NOT PULL D4 DOWN AT WHEN POWERING ON !!! BOOT WILL FAIL
const uint8_t PIN_WIPE = D4; const uint8_t PIN_WIPE = D4;
const uint8_t PINpump = D5; const uint8_t PINpump = D5;
const uint8_t PINled = D6; // const uint8_t PINled = D6; //
@ -332,12 +327,12 @@ float getHumidity() {
return humidity; return humidity;
} }
int getSoilmoisture(bool moistureSensor) { int getSoilmoisture(byte moistureSensor) {
/* /*
* moistureSensor * moistureSensor
* ============== * ==============
* 0/false : analog capacitive moisture sensor * 0 : analog capacitive moisture sensor
* 1/true : chirp I2C moisture sensor * 1 : chirp I2C moisture sensor
*/ */
// value to return // value to return
@ -347,7 +342,7 @@ int getSoilmoisture(bool moistureSensor) {
// value for dry // value for dry
int dry; int dry;
if(moistureSensor == false ) { if(moistureSensor == 0 ) {
// read analog value from analog moisture sensor // read analog value from analog moisture sensor
wet = 180; wet = 180;
dry= 590; dry= 590;
@ -380,6 +375,19 @@ int getLightchirp() {
void wipeEEPROM() { void wipeEEPROM() {
// i is helper variable. We reuse it later here again.
byte i = 0;
while(digitalRead(PIN_WIPE) == LOW ) {
// only show the Serial message once
if(i == 0) {
Serial.println("Please release PIN_WIPE to erase all data saved in EEPROM");
Serial.println("LAST CHANCE TO KEEP THE DATA WHEN RESETTING NOW!!");
}
// increase i to show the serial message only once
i = 1;
}
// write a 0 to all 512 bytes of the EEPROM // write a 0 to all 512 bytes of the EEPROM
Serial.print("wiping EEPROM... "); Serial.print("wiping EEPROM... ");
for (int i = 0; i < 512; i++) { EEPROM.write(i, 0); } for (int i = 0; i < 512; i++) { EEPROM.write(i, 0); }
@ -395,7 +403,7 @@ void wipeEEPROM() {
Serial.println("!! Device will restart in 5 seconds !!"); Serial.println("!! Device will restart in 5 seconds !!");
byte i = 0; i = 0;
while( i <= 10 ) { while( i <= 10 ) {
if( i % 2 ) { if( i % 2 ) {
digitalWrite(PIN_WIPE, LOW); digitalWrite(PIN_WIPE, LOW);
@ -411,6 +419,17 @@ void wipeEEPROM() {
bool loadEEPROM() { bool loadEEPROM() {
/*
* configured
*
* read var configured from address 511 - I put this to the end to
* prevent confusion with the 1 byte offset in the address when it
* would be at the beginning - more a cosmetic thing
*/
EEPROM.get(511, configured);
// when configured is > 1 (it should == 1) then read EEPROM furher data
if(configured > 0) {
/* /*
* WIFI data * WIFI data
*/ */
@ -434,14 +453,7 @@ bool loadEEPROM() {
//TBD //TBD
/*
* configured
*
* read var configured from address 511 - I put this to the end to
* prevent confusion with the 1 byte offset in the address when it
* would be at the beginning - more a cosmetic thing
*/
EEPROM.get(511, configured);
// print values to Serial output // print values to Serial output
Serial.println(":: EEPROM loaded ::"); Serial.println(":: EEPROM loaded ::");
@ -449,12 +461,13 @@ bool loadEEPROM() {
Serial.println(WIFIssid); Serial.println(WIFIssid);
Serial.print("WIFIpassword: "); Serial.print("WIFIpassword: ");
Serial.println(WIFIpassword); Serial.println(WIFIpassword);
}
Serial.print("configured: "); Serial.print("configured: ");
Serial.println(configured); Serial.println(configured);
return(configured); return(configured);
} }
@ -512,59 +525,85 @@ void setup() {
// initialise DHT11 // initialise DHT11
dht.begin(); //TODO: Do only, when configured dht.begin(); //TODO: Do only, when configured
WiFi.softAPConfig(WIFIip, WIFIgateway, WIFInetmask); Serial.println("To wipe the EEPROM saved data, set D4 (PIN_WIPE) to LOW - NOW! (2 seconds left)");
WiFi.softAP(APssid);
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
// wait a few seconds to let the user pull D4 down to wipe EEPROM // wait a few seconds to let the user pull D4 down to wipe EEPROM
// and we can enjoy the boot screen meanwhile :p // and we can enjoy the boot screen meanwhile :p
delay(2000); delay(2000);
// read status from PIN_WIPE to WIPE // read status from PIN_WIPE to WIPE
WIPE = digitalRead(PIN_WIPE);
// when PIN_WIPE is set to LOW, wipe EEPROM // when PIN_WIPE is set to LOW, wipe EEPROM
if( WIPE == 0 ) { if(digitalRead(PIN_WIPE) == LOW) {
Serial.print("PIN_WIPE (D4) is set to LOW, wiping EEPROM now.."); Serial.print("PIN_WIPE (D4) is set to LOW, wiping EEPROM now..");
// wipe EEPROM // wipe EEPROM
wipeEEPROM(); wipeEEPROM();
} else {
// load stored values from EEPROM
loadEEPROM();
} }
/*
* load EEPROM and Setup WiFi
*
* call loadEEPROM() which returns a bool
* When true, CanGrow is already configured and EEPROM values are applied
* When false, CanGrow is unconfigured and we need to run the setup assistant
*/
// load stored values from EEPROM
if(loadEEPROM()) {
Serial.print("Configuration found in EEPROM, connect to Wifi ");
Serial.println(WIFIssid);
// Start WiFi connection
WiFi.begin(WIFIssid, WIFIpassword);
// wait until WiFi connection is established
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
// use webhandlers for configured state
WebHandler_configured();
// no data found in EEPROM, setup Access Point
} else {
Serial.println("Creating Accesspoint");
Serial.print("SSID: ");
Serial.println(APssid);
Serial.print("Password: ");
Serial.println(APpass);
// configure WiFi Access Point
WiFi.softAPConfig(WIFIip, WIFIgateway, WIFInetmask);
// start Access Point
WiFi.softAP(APssid, APpass);
Serial.print("CanGrow IP address: ");
Serial.println(WiFi.softAPIP());
// use webhandlers for unconfigured state
WebHandler_unconfigured();
}
/* /*
* Webserver handlers * Webserver handlers
* here are the generic webserver handlers like 404 not found
* wificonfig save, ...
*
* if you are looking for the single webpages handler, have a look to
*
* WebHandler_unconfigured() and WebHandler_configured()
*/ */
// when not configured, webroot is WEBrootAP
// nothing else configured
if(configured == 0) {
webserver.on("/", HTTP_GET, WEBrootAP);
} else {
webserver.on("/", HTTP_GET, WEBroot);
}
// generic handler // generic handler
webserver.on("/wifiConfig/save", HTTP_POST, POSTwifiConfig); webserver.on("/wifiConfig/save", HTTP_POST, POSTwifiConfig);
// 404 handling // 404 handling
//webserver.onNotFound(handleNotFound); webserver.onNotFound(WEB404);
/*
webserver.on("/", HTTP_GET, WEBroot);
webserver.on("/control", HTTP_GET, handleControl);
*/
// start webserver
webserver.begin(); webserver.begin();
} }
@ -582,6 +621,14 @@ void loop() {
webserver.handleClient(); webserver.handleClient();
} }
void WebHandler_unconfigured() {
webserver.on("/", HTTP_GET, WEBrootAP);
}
void WebHandler_configured() {
webserver.on("/", HTTP_GET, WEBroot);
}
/* /*
* *
* Web pages * Web pages
@ -616,6 +663,12 @@ void WEBrootAP() {
} }
void WEB404() {
String body = FPSTR(HTMLheader);
body += "404 - not found";
body += FPSTR(HTMLfooter);
}
/* /*
* *
* POSTs * POSTs