diff --git a/Arduino/CanGrow/CanGrow.ino b/Arduino/CanGrow/CanGrow.ino index f450047..1613dc1 100644 --- a/Arduino/CanGrow/CanGrow.ino +++ b/Arduino/CanGrow/CanGrow.ino @@ -1,19 +1,6 @@ /* * 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() byte valSoilmoisture; // valTemperature - contains the value of getTemperature() @@ -63,8 +45,14 @@ float valHumidity; bool configured; char WIFIssid[32]; 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) +// unsigned long is 4 byte unsigned long GrowStart; // DayOfGrow contains on which day the grow is byte DayOfGrow; @@ -76,8 +64,7 @@ byte DaysBloom; byte LighthoursVeg; // LighthoursBloom - contains how many hours the Growlight is on in Bloom 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 byte Sunrise; // PINled_PWM - contains the PWM value for dimming the grow light @@ -89,7 +76,7 @@ byte MoistureSensor_Type; // UsePump - is the pump used? bool bool UsePump; // UseFan - is the fan used? bool -bool UseFan +bool UseFan; // SoilmoistureLow - contains the value , when soil moisture is assumed to be low, byte SoilmoistureLow; @@ -107,11 +94,6 @@ byte SoilmoistureLow; const char *APssid = "CanGrow-unconfigured"; 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"; /* + * * 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 @@ -146,7 +140,8 @@ const uint8_t PINfan = D0; // If D3 is pulled to LOW, boot fails const uint8_t PINdht = D3; // 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 PINpump = D5; const uint8_t PINled = D6; // @@ -332,12 +327,12 @@ float getHumidity() { return humidity; } -int getSoilmoisture(bool moistureSensor) { +int getSoilmoisture(byte moistureSensor) { /* * moistureSensor * ============== - * 0/false : analog capacitive moisture sensor - * 1/true : chirp I2C moisture sensor + * 0 : analog capacitive moisture sensor + * 1 : chirp I2C moisture sensor */ // value to return @@ -347,7 +342,7 @@ int getSoilmoisture(bool moistureSensor) { // value for dry int dry; - if(moistureSensor == false ) { + if(moistureSensor == 0 ) { // read analog value from analog moisture sensor wet = 180; dry= 590; @@ -380,6 +375,19 @@ int getLightchirp() { 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 Serial.print("wiping EEPROM... "); 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 !!"); - byte i = 0; + i = 0; while( i <= 10 ) { if( i % 2 ) { digitalWrite(PIN_WIPE, LOW); @@ -411,29 +419,6 @@ void wipeEEPROM() { bool loadEEPROM() { - /* - * WIFI data - */ - - // read var WIFIssid from address 0, 32 byte long - EEPROM.get(0, WIFIssid); - // read var WIFIpassword from address 32, 64 byte long - EEPROM.get(32, WIFIpassword); - - // read var WIFIip from address 96, 16 byte long - EEPROM.get(96, WIFIip); - - // read var WIFInetmask from address 112, 16 byte long - EEPROM.get(112, WIFInetmask); - // read var WIFIgateway from address 128, 16 byte long - EEPROM.get(128, WIFIgateway); - - /* - * Grow data - */ - - //TBD - /* * configured * @@ -443,18 +428,46 @@ bool loadEEPROM() { */ EEPROM.get(511, configured); - // print values to Serial output - Serial.println(":: EEPROM loaded ::"); - Serial.print("WIFIssid: "); - Serial.println(WIFIssid); - Serial.print("WIFIpassword: "); - Serial.println(WIFIpassword); + // when configured is > 1 (it should == 1) then read EEPROM furher data + if(configured > 0) { + /* + * WIFI data + */ + + // read var WIFIssid from address 0, 32 byte long + EEPROM.get(0, WIFIssid); + // read var WIFIpassword from address 32, 64 byte long + EEPROM.get(32, WIFIpassword); + + // read var WIFIip from address 96, 16 byte long + EEPROM.get(96, WIFIip); + + // read var WIFInetmask from address 112, 16 byte long + EEPROM.get(112, WIFInetmask); + // read var WIFIgateway from address 128, 16 byte long + EEPROM.get(128, WIFIgateway); + + /* + * Grow data + */ + + //TBD + + + + // print values to Serial output + Serial.println(":: EEPROM loaded ::"); + Serial.print("WIFIssid: "); + Serial.println(WIFIssid); + Serial.print("WIFIpassword: "); + Serial.println(WIFIpassword); + } + Serial.print("configured: "); Serial.println(configured); return(configured); - } @@ -512,59 +525,85 @@ void setup() { // initialise DHT11 dht.begin(); //TODO: Do only, when configured - WiFi.softAPConfig(WIFIip, WIFIgateway, WIFInetmask); - WiFi.softAP(APssid); - Serial.print("AP IP address: "); - Serial.println(WiFi.softAPIP()); - - - + Serial.println("To wipe the EEPROM saved data, set D4 (PIN_WIPE) to LOW - NOW! (2 seconds left)"); // wait a few seconds to let the user pull D4 down to wipe EEPROM // and we can enjoy the boot screen meanwhile :p delay(2000); // read status from PIN_WIPE to WIPE - WIPE = digitalRead(PIN_WIPE); + // 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.."); - // wipe EEPROM 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 webserver.on("/wifiConfig/save", HTTP_POST, POSTwifiConfig); // 404 handling - //webserver.onNotFound(handleNotFound); + webserver.onNotFound(WEB404); - /* - webserver.on("/", HTTP_GET, WEBroot); - - webserver.on("/control", HTTP_GET, handleControl); - */ - - + // start webserver webserver.begin(); } @@ -581,6 +620,14 @@ void loop() { //Serial.println("yolo"); webserver.handleClient(); } + +void WebHandler_unconfigured() { + webserver.on("/", HTTP_GET, WEBrootAP); +} + +void WebHandler_configured() { + webserver.on("/", HTTP_GET, WEBroot); +} /* * @@ -615,6 +662,12 @@ void WEBrootAP() { webserver.send(200, "text/html", body); } + +void WEB404() { + String body = FPSTR(HTMLheader); + body += "404 - not found"; + body += FPSTR(HTMLfooter); +} /* *