diff --git a/Arduino/CanGrow/CanGrow.ino b/Arduino/CanGrow/CanGrow.ino
index f2c9233..edc682c 100644
--- a/Arduino/CanGrow/CanGrow.ino
+++ b/Arduino/CanGrow/CanGrow.ino
@@ -95,7 +95,7 @@ char WebUiPassword[32] = "cangrow";
// configured - if false, let the user configure system settings first
bool configured = false;
// NTP Offset
-short ntpOffset;
+short NtpOffset;
// MoistureSensor_Type - contains which moisture sensor to use
// 1: analog capacitive sensor
// 2: I2C chirp sensor from catnip electronics
@@ -138,10 +138,14 @@ byte LighthoursBloom = 12;
byte SunriseHour = 7;
// SunriseHour - contains to which minute of SunriseHour the growlight turns on
byte SunriseMinute = 0;
-// PINled_PWM - contains the PWM value for dimming the grow light
+// PINledPWM - contains the PWM value for dimming the grow light
// default is 255 to ensure it is just on for the case UseLEDrelais is true
-byte PINled_PWM = 255;
-byte PINfan_PWM = 255;
+byte PINledPWM = 255;
+byte PINfanPWM = 255;
+
+// fade in and out sunrise and sunset?
+bool SunFade;
+byte SunFadeDuration = 30;
/*
*
@@ -354,11 +358,11 @@ function convertDateToEpoch(src, dst) {
*
* Pin assignments
*
- * D0 - MOSFET Fan
+ * D0 - MOSFET Pump
* D1, D2 - I2C
* D3 - DHT11
* D4 - PIN_WIPE
- * D5 - MOSFET Pump
+ * D5 - MOSFET Fan
* D6 - MOSFET Grow LED, PWM
* D7 - waterlevel (set HIGH to read value)
* D8 - analog soil moisture (set HIGH to read value)
@@ -692,7 +696,7 @@ bool loadEEPROM() {
* 164 PumpOnTime
* 165 MoistureSensor_Type
* 166 SoilmoistureLow
- * 167 ntpOffset
+ * 167 NtpOffset
* 169 UseLEDrelais
*
* 170 GrowName
@@ -707,10 +711,12 @@ bool loadEEPROM() {
*
* -- afterwards added, need to sort --
*
- * 213 PINled_PWM
+ * 213 PINledPWM
* 214 TemperatureSensor_Type
* 215 UseFANrelais
- * 216 PINfan_PWM
+ * 216 PINfanPWM
+ * 217 SunFade
+ * 218 SunFadeDuration
*
*/
@@ -763,20 +769,13 @@ bool loadEEPROM() {
// size is 1 byte
EEPROM.get(166, SoilmoistureLow);
// size is 2 byte
- EEPROM.get(167, ntpOffset);
+ EEPROM.get(167, NtpOffset);
// size is 1 byte
EEPROM.get(169, UseLEDrelais);
// size is 1 byte
- // I forgot to add TemperatureSensor_Type to EEPROM and noticed it
- // quite late in the process of programming. So this value residents
- // in 214 and not directly after UseLEDrelais
- EEPROM.get(213, PINled_PWM);
- // size is 1 byte
EEPROM.get(214, TemperatureSensor_Type);
// size is 1 byte
EEPROM.get(215, UseFANrelais);
- // size is 1 byte
- EEPROM.get(216, PINfan_PWM);
}
// TODO auth does not work atm
// EEPROM.get(160, WebUiUsername);
@@ -805,6 +804,12 @@ bool loadEEPROM() {
EEPROM.get(211, SunriseMinute);
// size is 1 byte
EEPROM.get(212, DayOfGrow);
+ // size is 1 byte
+ EEPROM.get(213, PINledPWM);
+ // size is 1 byte
+ EEPROM.get(216, PINfanPWM);
+ EEPROM.get(217, SunFade);
+ EEPROM.get(218, SunFadeDuration);
}
@@ -833,8 +838,8 @@ bool loadEEPROM() {
Serial.println(MoistureSensor_Type);
Serial.print("SoilmoistureLow: ");
Serial.println(SoilmoistureLow);
- Serial.print("ntpOffset: ");
- Serial.println(ntpOffset);
+ Serial.print("NtpOffset: ");
+ Serial.println(NtpOffset);
Serial.print("UseLEDrelais: ");
Serial.println(UseLEDrelais);
Serial.print("UseFANrelais: ");
@@ -859,10 +864,14 @@ bool loadEEPROM() {
Serial.println(SunriseMinute);
Serial.print("DayOfGrow: ");
Serial.println(DayOfGrow);
- Serial.print("PINled_PWM: ");
- Serial.println(PINled_PWM);
- Serial.print("PINfan_PWM: ");
- Serial.println(PINfan_PWM);
+ Serial.print("PINledPWM: ");
+ Serial.println(PINledPWM);
+ Serial.print("PINfanPWM: ");
+ Serial.println(PINfanPWM);
+ Serial.print("SunFade: ");
+ Serial.println(SunFade);
+ Serial.print("SunFadeDuration: ");
+ Serial.println(SunFadeDuration);
} else {
@@ -911,7 +920,7 @@ void wifiConnect() {
display.display();
timeClient.begin();
- timeClient.setTimeOffset(ntpOffset * 60 * 60);
+ timeClient.setTimeOffset(NtpOffset * 60 * 60);
timeClient.update();
while ( ! timeClient.isTimeSet()) {
timeClient.update();
@@ -951,6 +960,51 @@ void wifiAp() {
//Serial.println("The login credentials for the WebUI are 'cangrow' for username and password");
}
+void setOutput(byte pin, byte pinState) {
+ /*
+ * Pin assignments
+ *
+ * 1 - LED
+ * 2 - FAN
+ * 3 - PUMP
+ *
+ */
+
+
+ switch(pin) {
+ case 1:
+ if(pinState > 0) {
+ if(UseLEDrelais == true) {
+ digitalWrite(PINled, HIGH);
+ } else {
+ analogWrite(PINled, PINledPWM);
+ }
+ } else {
+ digitalWrite(PINled, LOW);
+ }
+ break;
+ case 2:
+ if(pinState > 0) {
+ if(UseFANrelais == true) {
+ digitalWrite(PINfan, HIGH);
+ } else {
+ analogWrite(PINfan, PINledPWM);
+ }
+ } else {
+ digitalWrite(PINfan, LOW);
+ }
+ break;
+ // PUMP Pin (D0) does not support PWM, so we do not need to care about
+ case 3:
+ if(pinState > 0) {
+ digitalWrite(PINpump, HIGH);
+ } else {
+ digitalWrite(PINpump, LOW);
+ }
+ break;
+ }
+}
+
/*
* Setup
*
@@ -1068,8 +1122,9 @@ void setup() {
// set web handler
WebHandler();
// start webserver
- webserver.begin();
+ webserver.begin();
+ Serial.println(".:: CanGrow Ready ::.");
}
@@ -1086,18 +1141,16 @@ void loop() {
unsigned int secondsToday = (timeClient.getHours() * 60 * 60) + (timeClient.getMinutes() * 60) + timeClient.getSeconds();
unsigned long currentRuntime = millis();
byte lightHours;
+ byte PINledPWM_tmp;
// first we call webserver handle client
webserver.handleClient();
- // do every second when everything is configured
+ // do every second when everything is configured and grow is started
if( (configured == true) && (strlen(GrowName) > 0) && (currentRuntime - outputPrevTime >= 1000) ){
- // debug output
- Serial.print("secondsSunrise: ");
- Serial.println(secondsSunrise);
- Serial.print("secondsToday: ");
- Serial.println(secondsToday);
- //Serial.println("yolo");
+ /*
+ * LED controlling
+ */
// calculate acutal DayOfGrow
DayOfGrow = int(ceil(float((timeClient.getEpochTime() - GrowStart) / 60 / 60 / 24)));
@@ -1109,17 +1162,31 @@ void loop() {
lightHours = LighthoursVeg;
}
- // check if secondsToday is larger then secondsSunrise time AND if secondsToday is smaller then the sum of secondsSunrise + seconds of lightHours
- if( (secondsToday >= secondsSunrise) && (secondsToday <= ( secondsSunrise + (lightHours * 60 * 60) ) )){
- // turn on light
+ // check if secondsToday is larger then secondsSunrise time AND if
+ // secondsToday is smaller then the sum of secondsSunrise + seconds of lightHours
+ if( (SunFade == true) && ((secondsToday >= secondsSunrise) && (secondsToday <= ( secondsSunrise + (lightHours * 60 * 60))) ) ){
+
+ // in the first n minutes of lighting (SunFadeDuration), we want
+ //to raise the light slowly to prevent stress from the plant
+ if(secondsSunrise + SunFadeDuration * 60 >= secondsToday) {
+ // convert progress sunrise to PWM value
+ PINledPWM_tmp = (SunFadeDuration * 60 - ((secondsSunrise + SunFadeDuration * 60) - secondsToday)) * 255 / (SunFadeDuration * 60);
+
+ } else if( (SunFade == true) && (secondsToday >= ((secondsSunrise + lightHours * 60 * 60) - SunFadeDuration * 60) ) ) {
+ // calculate progress sunset to PWM value
+ PINledPWM_tmp = (secondsSunrise + (lightHours * 60 * 60) - secondsToday) * 255 / (SunFadeDuration * 60);
+
+ } else {
+ // no sunrise or sunset, just keep the LED turned on
+ setOutput(1, PINledPWM);
+ }
-
- // TODO write a LED control function which takes also takes care of UseLEDrelais
- analogWrite(PINled, PINled_PWM);
} else {
// turn off
- digitalWrite(PINled, LOW);
+ setOutput(1, 0);
}
+
+ // current time gets previous time for new interval
outputPrevTime = currentRuntime;
}
@@ -1176,7 +1243,7 @@ void WebHandler() {
webserver.onNotFound(WEB404);
// switching MOSFETs
- webserver.on("/switch", HTTP_POST, POSTswitchMOSFET);
+ webserver.on("/switch", HTTP_POST, POSTsetOutput);
// api stuff
webserver.on("/api/sensors", HTTP_GET, APIgetSensors);
@@ -1433,7 +1500,7 @@ void WEBroot() {
}
body += "
";
body += "Growlight brightnes: ";
- body += ((PINled_PWM * 100) / 255);
+ body += ((PINledPWM * 100) / 255);
body += " %
";
body += "