////////////////////////////////////////////////////////////////////////////////
// Name: FloraPropagator2560-02 2018 WIFI version //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=17 //
// Robot that controls propagator //
// Platform: Arduino Mega 2560 //
// Created by: HARB rboek2@gmail.com september 2018 GPL copyrights //
// Thanks to: Library DHT 2011 by Limor Frie, modified 2012 by Tom Igoe //
// https://github.com/PaulStoffregen/OneWire //
// <DS1302.h> Copyright (c) 2009, Matt Sparks //
// As outputs the following modules are mounted: //
// - Standard Arduino Onboard LED (PWM) //
// - 3 color LED (PWM) //
// - Activ loudspeaker //
// - 220 Vac Relay //
// As inputs the following modules are mounted: //
// - DS1307 Real Time Clock //
// - DHT22 air temperature and air humidity sensor //
// - LED //
// - CJMCU soil huidity sensor (TWI) //
// For communications are mounted: //
// - Standard Serial Monitor output //
// - ESP-01 Wifi unit //
// //
// Connect ESP-01 to your Arduino: //
// Yellow = Arduino RX1 19 = ESP-01 TX //
// Blue = Arduino TX1 18 = ESP-01 RX //
// Connect your Arduino to your PC and open the serial monitor. //
// AT commands AT version:1.1.0.0(May 11 2016 18:09:56) //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//3456789112345678921234567893123456789412345678951234567896123456789712345678//
// EEPROM MEMORY MAP: //
// Start End Number Description //
// 0000 0000 1 Never use this memory location to be AVR compatible //
// 0001 0001 1 wateringProg Usr choice: 1=off 2=on 3=auto RELAY1 //
// 0002 0003 2 wateringON If CAPAC reaches this 2byte treshold RELAY1 //
// 0004 0005 2 wateringSecs How many seconds to keep ON RELAY1 //
// 0006 0006 1 Temperature/10 airheater Switch ON RELAY2 (0-25,5) //
// 0007 0007 1 Temperature/10 airheater Switch OFF RELAY2 (0-25,5) //
// 0008 0008 1 Usr choice: airheater 1=off 2=on 3=auto RELAY2 //
// 0009 0009 1 Temperature/10 heat coil Switch ON RELAY3 (0-25,5) //
// 0010 0010 1 Temperature/10 heat coil Switch OFF RELAY3 (0-25,5) //
// 0011 0011 1 Usr choice: heatcoil 1=off 2=on 3=auto RELAY3 //
// 0012 0012 1 Number of hours around noon GROWLED RELAY4 //
// 0013 0013 1 /Usr choice: growled 1=off 2=on 3=auto RELAY4 //
////////////////////////////////////////////////////////////////////////////////
// SET PRECOMPILER OPTIONS *****************************************************
// Initialse conditional compiling, uncomment to include, comment to exclude -
// Do comment the next line for runtime versions -----------------------------
#define RS232 //Uncomment to include Serial Monitor sections
//#ifdef RS232 //Only include these lines if the variable has been defined
// Define the needed header files for the precompiler, no charge if not used -
#include <DHT.h> //Needed for DHT22 and DHT11 Temperature and humidity sensors
#include <EEPROM.h> //Needed for read or write in EEPROM
#include <OneWire.h> //Library can be installed through Arduino IDE DS18B20
#include <RTClib.h> //connected via I2C and Wire lib
#include <WiFiEsp.h> //https://github.com/bportaluri/WiFiEsp
#include <Wire.h> //Two Wire Interface
// Define precompiler variables, runs faster & doesn`t use RAM ---------------
// Define PINS ---------------------------------------------------------------
OneWire term1(17); //Connects to pin 17, but may be any DIO pin DS1820
#define ledRedPin 44 //3 Colour LED, which PWM pin connects RED LED
#define ledBluPin 45 //3 Colour LED, which PWM pin connects BLUE LED
#define ledGrePin 46 //3 Colour LED, which PWM pin connects GREEN LED
#define DHTPIN 47 //Which DIO input pin connects DHT22
#define DHTTYPE DHT22 //What sensor is connected (AM2302) (AM2321) DHT22
#define Relay1Pin 48 //220Vac DIO output pin connects WATERING RELAY1
#define Relay2Pin 49 //220Vac DIO output pin connects AIR HEATER RELAY2
#define Relay3Pin 50 //220Vac DIO output pin connects COIL HEATER RELAY3
#define Relay4Pin 51 //220Vac DIO output pin ILLUMINATION LED RELAY4
#define buzAct 52 //Define DIO output pin connects ACTIV BUZZER
#define moistPin A8 //Analog input pin connects CAPACATIVE MOISTURE
#define moist2Pin A9 //Analog input pin connects CAPACATIVE 2 MOISTURE
#define moist3Pin A15 //Analog input pin connects CAPACATIVE 3 MOISTURE
//Define EEPROM variables ----------------------------------------------------
int wateringProg = 1; //Watering: 1=off 2=on 3=auto RELAY1
word propWaterON = 435; //If sensor CAPAC reaches this treshold RELAY1
word propWaterSecs = 300; //Number seconds watering will switch ON RELAY1
int airheatProg = 1; //Usr choice: airheater 1=off 2=on 3=auto RELAY2
int propAirheatON = 100; //Temperature/10 airheater Switch ON RELAY2
int propAirheatOFF = 130; //Temperature/10 airheater Switch OFF RELAY2
int heatCoilProg = 1; //Heatcoil 1=off 2=on 3=auto RELAY3
int propCoilON = 150; //Temperature/10 heatcoil ON RELAY3
int propCoilOFF = 160; //Temperature/10 airheater OFF RELAY2
int growLEDProg = 1; //GrowLED 1=off 2=on 3=auto RELAY4
int propLEDhours = 14; //Number of hours around noon RELAY4
//Define DATABASE VARIABLES --------------------------------------------------
bool propRelay1 = HIGH; //Status HIGH=off or LOW=on WATER RELAY1
bool propRelay2 = HIGH; //Status 1=off, 0=on AIRHEATER RELAY2
bool propRelay3 = HIGH; //Status HI=off, LW=on HEATCOIL RELAY3
bool propRelay4 = HIGH; //Status HI=off, LOW=on GROWLED RELAY4
word propCapac; //Moisture measured by CAPAC
word propCapacMin = 1023; //Minimum moisture measured in sequence by CAPAC
word propCapacMax = 0; //Maximum moisture measured in sequence by CAPAC
float propAirTemp; //Air temperature degree Celcius DHT22
float propAirHum; //Air humidity percentage DHT22
float propSoilTemp; //Soil temperature in Celsius DS18B20
String propKlok; //DateTime DS1307
word propCapac2; //Moisture measured by CAPAC
word propCapac2Min = 1023; //Minimum moisture measured in sequence by CAPAC
word propCapac2Max = 0; //Maximum moisture measured in sequence by CAPAC
word propCapac3; //Moisture measured by CAPAC
word propCapac3Min = 1023; //Minimum moisture measured in sequence by CAPAC
word propCapac3Max = 0; //Maximum moisture measured in sequence by CAPAC
//Define VARIABLES -----------------------------------------------------------
bool ledOnBoardVal = LOW; //You choose HIGH=on or LOW=off for LED_BUILTIN
byte msWait = 1; //Test your patience during the test LED
byte brillance = 0; //Brightness of any color, just to test PWM LED
char buf[100]; //Needed to display the date/time stamp DS1307
byte present = 0; //Used for oneWire, present = ds.reset() DS18B20
byte i; //Used for oneWire, loopcounter byte array DS18B20
byte data[12]; //Used for oneWire to store data read from DS18B20
byte type1_s = 0; //Type 0 = ok, except old DS1820=1, DS18B20
byte addr1[8]; //Array with first 8 bytes, inc/address DS18B20
String inStri = "No answer received"; //Default answer of ESP01
int starthours = 12 - (propLEDhours / 2); //Switch ON clock GROWLED
int finishhours = 12 + (propLEDhours / 2); //Switch OFF clock GROWLED
int currenthour; //Compare with starthours and finishhours for GROWLED
word readCounter = 0; //Read sensors if counted down to zero SENSORS
word readTimer = 9999; //Fill readCounter after reaching zero SENSORS
String html = ""; //HTML Response preapaired WIFI
int bodyLength; //HTML answer length WIFI
int status = WL_IDLE_STATUS; //Status of the ESP01 WIFI
char ssid[] = "Ranonkel9_EXT"; //Network SSID (name) WIFI
char pass[] = "Kat14_-5"; //Network password WIFI
String commandStr = ""; //Commands received by html INTERNET
int command = 0; //Which user command to perform WIFI
int value = 0; //Value that comes with the object WIFI
String tempo = ""; //Can be used anywhere
int tmp1; //Can be used anywhere
int tmp2; //Can be used anywhere
static unsigned long SwitchOFFtimer = millis()+ 300000; //WATERING
// Initialize OBJECTS --------------------------------------------------------
DHT dht(DHTPIN, DHTTYPE); //Initialize sensor object DHT22
DS1307 rtc; //Initialize Real Time Clock object DS1307
WiFiEspServer server(80); //Start the webserver WIFI
RingBuffer buf2(8); //Ringbuffer increases speed and reduces memory WIFI
//END OF PRECOMPILER OPTIONS ---------------------------------------------------
void setup() { // **************************************************************
ESP01setSpeed(); //Initializes the modem to 57600 WIFI ESP01
disable_jtag(); //Disable jtag to free port C, enabled by default JTAG
//EEPROMfirstTime(); //First time use, set values in EEPROM
wateringProg = EEPROM.read(1); //Watering: 1=off 2=on 3=auto RELAY1
propWaterON = promReadWord(2); //If CAPAC reaches this treshold RELAY1
propWaterSecs = promReadWord(4); //How many seconds to keep ON RELAY1
airheatProg = EEPROM.read(6); //Usr choice: 1=off 2=on 3=auto RELAY2
propAirheatON = EEPROM.read(7); //Temperature/10 airheater ON RELAY2
propAirheatOFF = EEPROM.read(8); //Temperature/10 airheater OFF RELAY2
heatCoilProg = EEPROM.read(9); //Heatcoil 1=off 2=on 3=auto RELAY3
propCoilON = EEPROM.read(10); //Temperature/10 heatcoil ON RELAY3
propCoilOFF = EEPROM.read(11); //Temperature/10 heatcoil OFF RELAY3
growLEDProg = EEPROM.read(12); //GrowLED 1=off 2=on 3=auto RELAY4
propLEDhours = EEPROM.read(13); //Number of hours around noon RELAY4
starthours = 12 - (propLEDhours / 2); //Switch ON clock GROWLED
finishhours = 12 + (propLEDhours / 2); //Switch OFF clock GROWLED
pinMode(LED_BUILTIN, OUTPUT); //Arduino boards contain an onboard LED_BUILTIN
pinMode(buzAct, OUTPUT); //Set this pin as output to BUZZER
pinMode(ledRedPin, OUTPUT); //Set this pin as output to redLED
pinMode(ledBluPin, OUTPUT); //Set this pin as output to blueLED
pinMode(ledGrePin, OUTPUT); //Set this pin as output to greenLED
analogReference(INTERNAL2V56); //Reduced to measure moisture CAPAC
pinMode(Relay1Pin, OUTPUT); //Set this pin as output to RELAY1
digitalWrite(Relay1Pin, propRelay1); //Switches OFF the RELAY1
pinMode(Relay2Pin, OUTPUT); //Set this pin as output to RELAY2
digitalWrite(Relay2Pin, propRelay2); //Switches OFF the RELAY2
pinMode(Relay3Pin, OUTPUT); //Set this pin as output to RELAY3
digitalWrite(Relay3Pin, propRelay3); //Switches OFF the RELAY3
pinMode(Relay4Pin, OUTPUT); //Set this pin as output to RELAY4
digitalWrite(Relay4Pin, propRelay4); //Switches OFF the RELAY4
Wire.begin(); //Start the Two Wire Interface object I2C
dht.begin(); //Start sensor object running DHT22
writeI2CRegister8bit(0x20, 6); //Reset sensor to tell it is a slave DHT22
Serial.begin(9600); //Nothing more needed for the Serial Monitor RSR232
Serial1.begin(57600); //RS232 Speed is preset to 57600 or 115200 at ESP01
//Start objects --------------------------------------------------------------
rtc.begin(); //Initialize Wire.begin first. Start the object running DS1307
//rtc.adjust(DateTime(__DATE__, __TIME__)); //Set to time compiled DS1307
//Test hardware and software -------------------------------------------------
beep(10); //Create a test beep with KY-012 active BUZZER
initializeWiFI(); //Initializes and connects to network WIFI
DS1820_init(); //Determins the type of DS1820 and reads properties DS1820
test_LEDs(); //PWM fade in and fade out for all 4 LEDs on board LED
//test_RELAY(); //Switches ON for 2 seconds the RELAY
Serial.println("Setup completed"); //Show the user the setup is done RS232
beep(10); //Create a test beep with KY-012 active BUZZER
} //End of setup ---------------------------------------------------------------
void loop() { //KEEP ON RUNNING THIS LOOP FOREVER *****************************
DateTime now = rtc.now(); //Read the current time into the object from DS1307
strncpy(buf,"YYYY-MM-DD hh:mm:ss\0",100); //Format string for the time DS1307
checkWifi(); //Check if any request available and if so then respond WIFI
propKlok = now.format(buf); //Format the timestap into a variable DS1307
strncpy(buf,"hh\0",100); //Format string for the time GROWLED
tempo = now.format(buf); //Format the timestap into a variable GROWLED
currenthour = tempo.toInt(); //Convert to value for switching GROWLED
checkWifi(); //Check if any request available and if so then respond WIFI
readSensors(); //Read several sensors at timed intervals only SENSORS
checkWifi(); //Check if any request available and if so then respond WIFI
} //End of void loop() ----------------------- KEEP ON RUNNING THIS LOOP FOREVER
void readSensors() { //Read several sensors at timed intervals only ************
if (readCounter == 0){ //Only perform measurements if counted down TIMER
digitalWrite(ledGrePin, HIGH); //Blue HIGH=on, LOW=off activityLED
DS1820_read(); //Reads the temperature in Celsius from DS18B20
propAirTemp = dht.readTemperature(); //Read temperature as Celsius DHT22
propAirHum = dht.readHumidity(); //Reading takes 250 milliseconds DHT22
propCapac = analogRead(moistPin); //Moisture measured by CAPACATIVE1
if (propCapac < propCapacMin){ //Do some statistics MOISTURE MINIMUM
propCapacMin = propCapac; //Set MOISTURE MINIMUM
} //Do some statistics MOISTURE MINIMUM
if (propCapac > propCapacMax){ //Compare statistics MOISTURE MAXIMUM
propCapacMax = propCapac; //Set MOISTURE MAXIMUM
} //End of if (propCapac > propCapacMax) Some statistics MOISTURE MAXIMUM
propCapac2 = analogRead(moist2Pin); //Moisture measured by CAPACATIVE2
if (propCapac2 < propCapac2Min){ //Do some statistics MOISTURE MINIMUM
propCapac2Min = propCapac2; //Set MOISTURE MINIMUM
} //Do some statistics MOISTURE MINIMUM
if (propCapac2 > propCapac2Max){ //Compare statistics MOISTURE MAXIMUM
propCapac2Max = propCapac2; //Set MOISTURE MAXIMUM
} //End of if (propCapac2 > propCapac2Max) Some statistics MOISTURE MAXIMUM
propCapac3 = analogRead(moist3Pin); //Moisture measured by CAPACATIVE3
if (propCapac3 < propCapac3Min){ //Do some statistics MOISTURE MINIMUM
propCapac3Min = propCapac3; //Set MOISTURE MINIMUM
} //Do some statistics MOISTURE MINIMUM
if (propCapac3 > propCapac3Max){ //Compare statistics MOISTURE MAXIMUM
propCapac3Max = propCapac3; //Set MOISTURE MAXIMUM
} //End of if (propCapac2 > propCapac2Max) Some statistics MOISTURE MAXIMUM
readCounter = readTimer; //RESET the counter TIMER
refreshAnswer(); //Replace the old answer by a new one DATA
setActuators(); //Calculate and set all OUTPUTS
toggle_ledOnBoard(); //Toggles the LED_BUILTIN ON or OFF onboardLED
if (propRelay1 == LOW){ //Plant needs watering, WATERING IS ON
beep(1); //Create a test beep with KY-012 active BUZZER
} //End of if (propRelay1 == LOW) Plant needs watering, WATERING IS ON
//Serial.println(html); //Show activity to the user RS232
digitalWrite(ledGrePin, LOW); //Blue HIGH=on, LOW=off activityLED
}else{ //Meaning counter was not yet zero TIMER
readCounter--; //Decrement of the timer counter TIMER
} //End of if (moistureCnt1 == 0)Perform measurements if counted down TIMER
} //Exit readSensors -----------------------------------------------------------
void setActuators(){ //Calculate and set all OUTPUTS ***************************
setRelay1(); //WATERING switch, calculate and set RELAY1
setRelay2(); //AIR HEATER switch, calculate and set RELAY2
setRelay3(); //COIL HEATER switch, calculate and set RELAY3
setRelay4(); //GROWLED switch, calculate and set RELAY4
} //Exit setActuators ----------------------------------------------------------
void checkWifi(){ //Check if any request available and if so then respond WIFI
WiFiEspClient client = server.available(); //Listen for incoming clients WIFI
if (client) { //If you get a client then do WIFI
digitalWrite(ledBluPin, HIGH); //Blue HIGH=on, LOW=off activityLED
handleClient(client); //Answers a client request made by WIFI
propCapacMin = 1023; //RESET Statistics minimum moisture content MOISTURE
propCapacMax = 0; //RESET Statistics maximum moisture content MOISTURE
propCapac2Min = 1023; //RESET Statistics minimum moisture content CAPAC2
propCapac2Max = 0; //RESET Statistics maximum moisture content CAPAC2
propCapac3Min = 1023; //RESET Statistics minimum moisture content CAPAC3
propCapac3Max = 0; //RESET Statistics maximum moisture content CAPAC3
digitalWrite(ledBluPin, LOW); //Blue HIGH=on, LOW=off activityLED
} //End of if (client) //If you get a client then do WIFI
} //Exit checkWifi -------------------------------------------------------------
void sendHttpResponse(WiFiEspClient client) { //Sends measurements WIFI ********
refreshAnswer(); //Replace the old answer by a new one DATA
client.println("HTTP/1.1 200 OK"); //Start answer to the request WIFI
client.println("Connection: close"); //Close after html is finished WIFI
client.print("Content-Length: "); //Finish html after amount of chars WIFI
client.println (bodyLength); //Name the amount of calculated characters WIFI
client.println("Content-Type: text/html"); //Needed to be compatible WIFI
client.println(" /n \n"); //Needed to end the headers WIFI
client.println(html); //Broadcast the message to be shown in browser WIFI
} //Exit sendHttpResponse ------------------------------------------------------
void handleClient(WiFiEspClient client){ //Proces a client request made by WIFI
commandStr = ""; //Reset the commands line WIFI
//Serial.println("New client"); //Show activity to the user RS232
buf2.init(); //Initialize the circular buffer
while (client.connected()) { //Loop while the client is connected
if (client.available()) { //If there are bytes to read from client
char c = client.read(); //Read a byte
buf2.push(c); //Push the byte into the ring buffer
commandStr += c; //Add received character to command
if (buf2.endsWith("\r\n\r\n")) { //Check for 2 newline characters in row
if (isDigit(commandStr[5])){ //Check if we received any command
tempo = commandStr.substring(5, 7); //Extract command 01-99
command = tempo.toInt(); //Translate the function to a executable
switch (command) { //Go to the according procedure
case 1: //Command = 1 = Set program WATERINGPROG *******************
tempo = commandStr[8]; //Extract parameter 1=off 2=on 3=auto
wateringProg = tempo.toInt(); //Set actual program for WATERING
setRelay1(); //WATERING switch, calculate and set RELAY1
eepromWriteByte(1, wateringProg); //Set 1 byte EEPROM
break; //End of command == 1 translates to command is 1=Set program
case 2: //If CAPAC reaches treshold CAPAC switch WATERING ON *******
tempo = commandStr.substring(8, 12); //Extract parameter 0000-9999
propWaterON = tempo.toInt(); //Convert to decimal PARAMETER
setRelay1(); //WATERING switch, calculate and set RELAY1
eepromWriteWord (2, propWaterON); //Set 2 bytes EEPROM
break; ///End of if (command == 2) Set switch ON WATERING ----------
case 3: //How many seconds to keep ON RELAY1 b4 switch WATERING OFF
tempo = commandStr.substring(8, 12); //Extract parameter 0000-9999
propWaterSecs = tempo.toInt(); //Convert to decimal PARAMETER
setRelay1(); //WATERING switch, calculate and set RELAY1
eepromWriteWord(4, propWaterSecs); //Set 2 bytes EEPROM
break; //End of if (command == 3) Set switch OFF WATERING ----------
case 11: //Command = 11 = Set program AIR HEATER *******************
tempo = commandStr[8]; //Extract parameter 1=off 2=on 3=auto
airheatProg = tempo.toInt(); //Convert to decimal PARAMETER
setRelay2(); //AIR HEATER switch, calculate and set RELAY2
eepromWriteByte(6, airheatProg); //Set 1 byte EEPROM
break; //End of command == 1 translates to command is 1=Set program
case 12: //If Temperature reaches treshold switch AIR HEATER ON ****
tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
propAirheatON = tempo.toInt(); //Convert to decimal PARAMETER
setRelay2(); //AIR HEATER switch, calculate and set RELAY2
eepromWriteByte(7, propAirheatON); //Set 1 byte EEPROM
break; //End of if (command == 2) Set switch ON AIR HEATER ---------
case 13: //If Temperature reaches treshold switch AIR HEATER OFF ***
tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
propAirheatOFF = tempo.toInt(); //Convert to decimal PARAMETER
setRelay2(); //AIR HEATER switch, calculate and set RELAY2
eepromWriteByte(8, propAirheatOFF); //Set 1 byte EEPROM
break; //End of if (command == 3) Set switch OFF AIR HEATER --------
case 21: //Command = 21 = Set program COIL HEATER ******************
tempo = commandStr[8]; //Extract parameter 1=off 2=on 3=auto
heatCoilProg = tempo.toInt(); //Convert to decimal PARAMETER
setRelay3(); //COIL HEATER switch, calculate and set RELAY3
eepromWriteByte(9, heatCoilProg); //Set 1 byte EEPROM
break; //Case 21 Command = 21 = Set program COIL HEATER
case 22: //If Temperature reaches treshold switch COIL HEATER ON ***
tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
propCoilON = tempo.toInt(); //Convert to decimal PARAMETER
setRelay3(); //COIL HEATER switch, calculate and set RELAY3
eepromWriteByte(10, propCoilON); //Set 1 byte EEPROM
break; //Case 22 Temperature treshold switch COIL HEATER ON
case 23: //If Temperature reaches treshold switch COIL HEATER OFF **
tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
propCoilOFF = tempo.toInt(); //Convert to decimal PARAMETER
setRelay3(); //COIL HEATER switch, calculate and set RELAY3
eepromWriteByte(11, propCoilOFF); //Set 1 byte EEPROM
break; //Case 23 Temperature treshold switch COIL HEATER OFF
case 31: //Command = 31 = Set program GROWLED **********************
tempo = commandStr[8]; //Extract parameter 1=off 2=on 3=auto
growLEDProg = tempo.toInt(); //Convert to decimal PARAMETER
setRelay4(); //GROWLED switch, calculate and set RELAY4
eepromWriteByte(12, growLEDProg); //Set 1 byte EEPROM
break; //Case 31 Command = 31 = Set program GROWLED
case 32: //Number of hours around noon RELAY4 GROWLED ON ***********
tempo = commandStr.substring(8, 12); //Extract parameter 0000-0023
propLEDhours = tempo.toInt(); //Convert to decimal PARAMETER
starthours = 12 - (propLEDhours / 2); //Switch ON clock GROWLED
finishhours = 12 + (propLEDhours / 2); //Switch OFF clock GROWLED
setRelay4(); //GROWLED switch, calculate and set RELAY4
eepromWriteByte(13, propLEDhours); //Set 1 byte EEPROM
break; //Case 32 Number of hours around noon RELAY4 GROWLED ON
} //End of the list with possible precedures -------------------------
} //End of if (isDigit(commandStr[5])) Check if we received any command
sendHttpResponse(client); //Meaning the end of the HTTP request
break; //After the response is sent we are done here
} //End of if (buf2.endsWith("\r\n\r\n")) { //Check for 2 newline chars
} //End of if (client.available()) { If there are bytes to read from client
} //End of while (client.connected()) { Loop while the client is connected
client.stop(); //Close the Wifi connection WIFI
Serial.println("Client disconnected"); //Showing we handeld a request RS232
Serial.println(" "); //Just to start a new paragraph RS232
} //End of handleClient Proces a client request made by WIFI -------------------
void refreshAnswer(void) { //Replace the old answer by a new one WIFI **********
if (String(propAirTemp) == " NAN"){ //Correct answer if not connected DHT22
propAirTemp = 99.1; //Both temperature and humidity will affected DHT22
propAirHum = -1; //Humidity value gives status not connected DHT22
}//End of String(propAirTemp) = " NAN" Answer corrected if not connected DHT22
html = String(wateringProg) + " "; //Watering: 1=off 2=on 3=auto RELAY1
html += String(propRelay1) + " "; //Status HIGH=off, LOW=on WATER RELAY1
html += String(propCapac) + " "; //Moisture measured by CAPAC
html += String(propCapacMin) + " "; //Minimum moisture in sequence by CAPAC
html += String(propCapacMax) + " "; //Maximum moisture in sequence by CAPAC
html += String(propWaterON) + " "; //If CAPAC reaches this treshold RELAY1
html += String(propWaterSecs)+ " "; //How many seconds to keep ON RELAY1
html += String(airheatProg) + " "; //Air heater 1=off 2=on 3=auto RELAY2
html += String(propRelay2) + " "; //Status 1=off, 0=on AIRHEATER RELAY2
html += String(propAirTemp) + " "; //Air temperature degree Celcius DHT22
html += String(propAirHum) + " "; //Air humidity percentage DHT22
html += String(propAirheatON) + " "; //Temperature/10 airheater ON RELAY2
html += String(propAirheatOFF) + " "; //Temperature/10 airheater OFF RELAY2
html += String(heatCoilProg)+ " "; //Heatcoil 1=off 2=on 3=auto RELAY3
html += String(propRelay3)+ " "; //Status HI=off, LW=on HEATCOIL RELAY3
html += String(propSoilTemp)+ " "; //Soil temperature in Celsius DS18B20
html += String(propCoilON)+ " "; //TTemperature/10 heatcoil ON RELAY3
html += String(propCoilOFF)+ " "; //Temperature/10 heatcoil OFF RELAY3
html += String(growLEDProg)+ " "; //GrowLED 1=off 2=on 3=auto RELAY4
html += String(propRelay4)+ " "; //Status HI=off, LOW=on GROWLED RELAY4
html += (propKlok)+ " "; //DateTime DS1307
html += String(propLEDhours) + " "; //Number of hours around noon RELAY4
html += String(propCapac2) + " "; //Moisture measured by CAPAC2
html += String(propCapac2Min) + " "; //Minimum moisture in sequence by CAPAC2
html += String(propCapac2Max) + " "; //Maximum moisture in sequence by CAPAC2
html += String(propCapac3) + " "; //Moisture measured by CAPAC3
html += String(propCapac3Min) + " "; //Minimum moisture in sequence by CAPAC3
html += String(propCapac3Max); //Maximum moisture in sequence by CAPAC3
bodyLength = html.length(); //Calculate the number of characters to sent WIFI
} //Exit refreshAnswer ---------------------------------------------------------
void showMonitor(){ //Shows all values at the serial monitor RS232 *************
Serial.println(html); //Print the answer to RS232
} //ExitshowMonitor(){ Shows all values at the serial monitor RS232 ------------
void printWifiStatus() { //Show relevant network settings to the user RS232 ****
Serial.println("You're connected to the network"); //Used at initialisation
Serial.print("SSID: "); //Print the SSID of the network you're attached to
Serial.println(WiFi.SSID()); //Print Router name
IPAddress ip = WiFi.localIP(); //Print your IP address
Serial.print("IP Address: "); //Print text for understanding
Serial.println(ip); //IP address
} //Exit printWifiStatus -------------------------------------------------------
void setRelay1(){ //WATERING switch, calculate and set RELAY1 ******************
if (SwitchOFFtimer < millis()) { //If propWaterSecs SWITCH WATER OFF RELAY1
propRelay1 = HIGH; //HIGH=off or LOW=on WATER RELAY1 SWITCH OFF
} //End of if (SwitchOFFtimer < millis propWaterSecs SWITCH WATER OFF RELAY1
switch (wateringProg) { //Watering program: 1=off 2=on 3=auto RELAY1
case 1: //Program = 1 = Set program WATERINGPROG OFF
propRelay1 = HIGH; //Status HIGH=off or LOW=on WATER RELAY1
break; //End of Program = 1 = Set program WATERINGPROG OFF
case 2: //Program = 2 = Set program WATERINGPROG ON
propRelay1 = LOW; //Status HIGH=off or LOW=on WATER RELAY1
break; //End of Program = 2 = Set program WATERINGPROG ON
case 3: //Program = 3 = Set program WATERINGPROG AUTO
if (propCapac > propWaterON and propRelay1 == HIGH) { //Treshold then ON
propRelay1 = LOW; //Status HIGH=off or LOW=on WATER ON RELAY1
SwitchOFFtimer = millis() + propWaterSecs*1000L; //Set SWTICH OFF TIME
Serial.print("Switch ON "); //Show activity to the user RS232
Serial.println(propKlok); //Show activity to the user RS232
} //End of If measurement reaches treshold then ON
break; //End of Program = 3 = Set program WATERINGPROG AUTO
} //End of switch wateringProg
digitalWrite(ledRedPin, !propRelay1); //RELAY1=ON --> LED RED=ON
digitalWrite(Relay1Pin, propRelay1); //Switches RELAY1
} //Exit setRelay1 -------------------------------------------------------------
void setRelay2(){ //AIR HEATER switch, calculate and set RELAY2 ****************
switch (airheatProg) { //AIR HEATER program: 1=off 2=on 3=auto RELAY2
case 1: //Program = 1 = Set program AIR HEATER OFF
propRelay2 = HIGH; //Status HIGH=off or LOW=on AIR HEATER RELAY2
break; //End of Program = 1 = Set program AIR HEATER OFF
case 2: //Program = 2 = Set program AIR HEATER ON
propRelay2 = LOW; //Status HIGH=off or LOW=on AIR HEATER RELAY2
break; //End of Program = 2 = Set program AIR HEATER ON
case 3: //Program = 3 = Set program AIR HEATER AUTO
if (propAirTemp < propAirheatON/10){ //If treshold measurement TURN ON
propRelay2 = LOW; //Status HIGH=off or LOW=on AIR HEATER ON RELAY2
} //End of If treshold measurement TURN ON
if (propAirTemp > propAirheatOFF/10){ //If treshold measurement TURN OFF
propRelay2 = HIGH; //Status HIGH=off or LOW=on AIR HEATER ON RELAY2
} //End of If treshold measurement TURN OFF
break; //End of Program = 3 = Set program AIR HEATER AUTO
} //End of switch AIR HEATER
digitalWrite(Relay2Pin, propRelay2); //Switches RELAY2
} //Exit setRelay2 -------------------------------------------------------------
void setRelay3(){ //COIL HEATER switch, calculate and set RELAY3 ***************
switch (heatCoilProg) { //COIL HEATER program: 1=off 2=on 3=auto RELAY3
case 1: //Program = 1 = Set program COIL HEATER OFF
propRelay3 = HIGH; //Status HIGH=off or LOW=on COIL HEATER RELAY3
break; //End of Program = 1 = Set program COIL HEATER OFF
case 2: //Program = 2 = Set program COIL HEATER ON
propRelay3 = LOW; //Status HIGH=off or LOW=on COIL HEATER RELAY3
break; //End of Program = 2 = Set program COIL HEATER ON
case 3: //Program = 3 = Set program COIL HEATER AUTO
if (propSoilTemp < propCoilON/10){ //If treshold measurement TURN ON
propRelay3 = LOW; //Status HIGH=off or LOW=on COIL HEATER ON RELAY3
} //End of If treshold measurement TURN ON
if (propSoilTemp > propCoilOFF/10){ //If treshold measurement TURN OFF
propRelay3 = HIGH; //Status HIGH=off or LOW=on COIL HEATER ON RELAY3
} //End of If treshold measurement TURN OFF
break; //End of Program = 3 = Set program COIL HEATER AUTO
} //End of switch COIL HEATER
digitalWrite(Relay3Pin, propRelay3); //Switches RELAY3
} //Exit setRelay3 -------------------------------------------------------------
void setRelay4(){ //GROWLED switch, calculate and set RELAY4 *******************
switch (growLEDProg) { //GROWLED program: 1=off 2=on 3=auto RELAY4
case 1: //Program = 1 = Set program GROWLED OFF
propRelay4 = HIGH; //Status HIGH=off or LOW=on GROWLED RELAY4
break; //Case 1 End of Program = 1 = Set program GROWLED OFF
case 2: //Program = 2 = Set program GROWLED ON
propRelay4 = LOW; //Status HIGH=off or LOW=on GROWLED RELAY4
break; //Case 2 End of Program = 2 = Set program GROWLED ON
case 3: //Program = 3 = Set program GROWLED AUTO
if (currenthour < starthours){ //Too early, GROWLED OFF
propRelay4 = HIGH; //Switch OFF , HIGH=off LOW=on GROWLED OFF
} //End of if (currenthour < starthours){ //Too early, GROWLED OFF
if (currenthour > finishhours){ //Too late, GROWLED OFF
propRelay4 = HIGH; //Switch OFF , HIGH=off LOW=on GROWLED OFF
} //End of if (currenthour > finishhours) Too late, GROWLED OFF
if (currenthour > (starthours-1) && currenthour <(finishhours)){ //ON
propRelay4 = LOW; //Switch ON , HIGH=off LOW=on GROWLED ON
} //End of if (currenthour > (starthours-1) && currenthour <(finishhours)
break; //Case 3 End of Program = 3 = Set program GROWLED AUTO
} //End of switch GROWLED
digitalWrite(Relay4Pin, propRelay4); //Switches RELAY4
} //Exit setRelay4 -------------------------------------------------------------
void initializeWiFI(){ //Initializes and connects to network *******************
WiFi.init(&Serial1); //Initialize ESP01 module WIFI
if (WiFi.status() == WL_NO_SHIELD) { //Check the presence of the module WIFI
Serial.println("WiFi module not present"); //Show error to the user RS232
while (true); //Don't continue by looping here forever WIFI
} //End of if (WiFi.status() == WL_NO_SHIELD) { Check the presence WIFI
while (status != WL_CONNECTED) { //Attempt connecting to WiFi network WIFI
Serial.print("Attempting to connect to WPA SSID: "); //Show connecting RS232
Serial.println(ssid); //Show fixed network name to the user RS232
status = WiFi.begin(ssid, pass); //Connected to WPA/WPA2 network
} //End of while (status != WL_CONNECTED) Keep on trying until connected WIFI
printWifiStatus(); //Show relevant network settings to the user RS232
server.begin(); //Start the web server on port 80 WIFI
} //End of initializeWiFI(){ Initializes and connects to network ---------------
void ESP01setSpeed(){ //Initializes the modem to 57600 WIFI ESP01 **************
Serial1.begin(115200); //Can be 115200 or 57600 WIFI ESP01
Serial1.setTimeout(5000); //1000 = default for WIFI ESP01
readESP01(); //Empty serial buffers
Serial.println("Test if AT system works correctly: "); //General test ESP01
Serial1.println("AT"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Restart ESP01: "); //Reset to defaults ESP01
Serial1.println("AT+RST"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Print firmware version: "); //Firmware of the ESP01
Serial1.println("AT+GMR"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Lists all valid modes: "); //Modes of Wifi on the ESP01
Serial1.println("AT+CWMODE?"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Lists available Access Points: "); //Networks for ESP01
Serial1.println("AT+CWLAP"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Test if AT system works correctly: "); //General test ESP01
Serial1.println("AT"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Set to slower communication rate: "); //General set ESP01
Serial1.println("AT+UART_DEF=57600,8,1,0,0"); //Send command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
Serial.println("Test if AT system works correctly: "); //General test ESP01
Serial1.println("AT"); //Send the AT command to the ESP01
readESP01(); //Receive data from the ESP01
Serial.println(inStri); //Show answer at the SERIAL MONITOR
} //Exit ESP01setSpeed ---------------------------------------------------------
void readESP01(void){ //Receive and proces AT data from the ESP01 **************
delay(10); //Give some time to answer ESP01
inStri = ""; //Reset receive string WIFI
while (Serial1.available() > 0) { //Check if any request available WIFI
inStri = inStri + Serial1.readString(); //Read incoming characters ESP01
delay(500); //Give some time to retreive data from the net ESP01
} //End of while (Serial1.available() > 0) Entire block has been read ESP01
if (inStri == "") { //Check if any error is made WIFI
inStri = "No answer received"; //Default answer if nothing received WIFI
} //End of if (inStri <> "") Check if any error is made WIFI
} //Exit readESP01 -------------------------------------------------------------
void DS1820_read(void) { //Reads the temperature from DS1820 in Celsius ********
term1.reset(); //Reset whatever still was running
term1.select(addr1); //Set the parameters for the library
term1.write(0x44); //Start conversion, with parasite power on at the end
delay(800); //Maybe 750ms is enough, maybe not, takes a lot of time though
present = term1.reset(); //We assume that the conversion is ready
term1.select(addr1); //Set the parameters for the library
term1.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { //We need 9 bytes
data[i] = term1.read(); //Read byte by byte
} //End of reading bytes
int16_t raw = (data[1] << 8) | data[0]; //Rotate the data
propSoilTemp = (float)raw / 16.0; //Untill they are in the correct position
} //Exit DS1820_read -----------------------------------------------------------
void DS1820_init(void) { //Determins the type of DS1820 thermometer1 ***********
if (!term1.search(addr1)) { //Term1 is an objest created by ONEWIRE
term1.reset_search(); //So if the variables are still empty
delay(250); //The variables must be filled and that costs some time
return; //Are you sure any DS1820 is connected
} //End of if (!term1.search(addr1))
if (OneWire::crc8(addr1, 7) != addr1[7]) {
return;
}
switch (addr1[0]) { //The first ROM byte indicates which tupe of chip
case 0x10:
type1_s = 1;
break;
case 0x28:
type1_s = 0;
break;
case 0x22:
type1_s = 0;
break;
default:
return;
}
term1.reset();
term1.select(addr1);
term1.write(0x44, 1); //Start conversion, with parasite power on at the end
delay(800); //Maybe 750ms is enough, maybe not, takes a lot of time though
present = term1.reset();
term1.select(addr1);
term1.write(0xBE); //Read Scratchpad
for ( i = 0; i < 9; i++) { //We need 9 bytes
data[i] = term1.read();
}
int16_t raw = (data[1] << 8) | data[0];
if (type1_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else { //// default is 12 bit resolution, 750 ms conversion time
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
}
propSoilTemp = (float)raw / 16.0;
} //Exit DS1820_init -----------------------------------------------------------
unsigned int readI2CRegister16bit(int addr, int reg){ //Read any TWI register **
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission();
delay(20);
Wire.requestFrom(addr, 2);
unsigned int t = Wire.read() << 8;
t = t | Wire.read();
return t;
} //Exit readI2CRegister16bit --------------------------------------------------
void writeI2CRegister8bit(int addr, int value){ //Reset sensor DHT22 **********
Wire.beginTransmission(addr);
Wire.write(value);
Wire.endTransmission();
} //Exit writeI2CRegister8bit --------------------------------------------------
void eepromWriteByte(word place, int parameter){ //Set EEPROM 1 byte and REFRESH
EEPROM.write(place , parameter); //Setting must be an integer WRITE
} //Exit eepromWriteByte -------------------------------------------------------
void eepromWriteWord(word place, word parameter){ //EEPROM 2 bytes and REFRESH*
tmp1 = parameter/255; //Tmp1 contains the HIGH BYTE
EEPROM.write(place, tmp1); //Setting HIGH byte WRITE
tmp2 = parameter -(tmp1 * 255) ; //Calculate LOW BYTE
EEPROM.write(place + 1, tmp2); //Setting HIGH byte WRITE
} //Exit eepromWriteWord ------------------------------------------------------
word promReadWord(word address) { //EEPROM read a 2 byte word ******************
tmp1 = EEPROM.read(address); //Read the HIGH part of the word HIGH
tmp2 = EEPROM.read(address+1); //Read the LOW part of the word LOW
return tmp1*255 + tmp2; // Return the word value
} //Exit promReadWord ----------------------------------------------------------
void EEPROMfirstTime() { //First time use, set values in EEPROM ****************
EEPROM.write(1, 1); //Watering: 1=off 2=on 3=auto RELAY1
EEPROM.write(2, 1); //If CAPAC reaches this treshold HIGH RELAY1
EEPROM.write(3, 11); //If CAPAC reaches this treshold LOW RELAY1
EEPROM.write(4, 1) ; //How many seconds to keep ON HIGH RELAY1
EEPROM.write(5, 55); //How many seconds to keep ON LOW RELAY1
EEPROM.write(6, 1); //Air heater 1=off 2=on 3=auto RELAY2
EEPROM.write(7, 100); //Temperature/10 airheater ON RELAY2
EEPROM.write(8, 130); //Temperature/10 airheater OFF RELAY2
EEPROM.write(9, 1); //Heatcoil 1=off 2=on 3=auto RELAY3
EEPROM.write(10, 150); //Temperature/10 heatcoil ON RELAY3
EEPROM.write(11, 160); //Temperature/10 heatcoil OFF RELAY3
EEPROM.write(12, 1); //GrowLED 1=off 2=on 3=auto RELAY4
EEPROM.write(13, 14); //Number of hours around noon RELAY4
} //Exit EEPROMfirstTime -------------------------------------------------------
void test_RELAY(){ //Switches ON for 2 seconds all RELAY ***********************
digitalWrite(Relay1Pin, LOW); //Switches ON the RELAY1
delay (2000); //Wait for 2 seconds
digitalWrite(Relay1Pin, HIGH); //Switches OFF the RELAY1
digitalWrite(Relay2Pin, LOW); //Switches ON the RELAY2
delay (2000); //Wait for 2 seconds
digitalWrite(Relay2Pin, HIGH); //Switches OFF the RELAY2
digitalWrite(Relay3Pin, LOW); //Switches ON the RELAY3
delay (2000); //Wait for 2 seconds
digitalWrite(Relay3Pin, HIGH); //Switches OFF the RELAY3
digitalWrite(Relay4Pin, LOW); //Switches ON the RELAY4
delay (2000); //Wait for 2 seconds
digitalWrite(Relay4Pin, HIGH); //Switches OFF the RELAY4
} //End of test_Relay(){ Switches ON for 2 seconds the RELAY -------------------
void test_LEDs(void){ //PWM fade in and fade out for all 4 LEDs on board *******
while (brillance<255){
analogWrite(LED_BUILTIN, brillance); //Set to desired PWM value LED_BUILTIN
brillance++;
delay (msWait);
}
while (brillance>0){
analogWrite(LED_BUILTIN, brillance); //Set to desired PWM value LED_BUILTIN
brillance--;
delay (msWait);
}
analogWrite(LED_BUILTIN, 0); //Set LED to desired PWM value = off LED_BUILTIN
while (brillance<255){
analogWrite(ledRedPin, brillance); //Set LED to desired PWM value RED
brillance++;
delay (msWait);
}
while (brillance>0){
analogWrite(ledRedPin, brillance); //Set LED to desired PWM value RED
brillance--;
delay (msWait);
}
analogWrite(ledRedPin, 0); //Set LED to desired PWM value = off RED
while (brillance<255){
analogWrite(ledGrePin, brillance); //Set LED to desired PWM value GREEN
brillance++;
delay (msWait);
}
while (brillance>0){
analogWrite(ledGrePin, brillance); //Set LED to desired PWM value GREEN
brillance--;
delay (msWait);
}
analogWrite(ledGrePin, 0); //Set LED to desired PWM value = off GREEN
while (brillance<255){
analogWrite(ledBluPin, brillance); //Set LED to desired PWM value BLUE
brillance++;
delay (msWait);
}
while (brillance>0){
analogWrite(ledBluPin, brillance); //Set LED to desired PWM value BLUE
brillance--;
delay (msWait);
}
analogWrite(ledBluPin, 0); //Set LED to desired PWM value = off BLUE
} //Exit test_LEDs -------------------------------------------------------------
void beep(uint8_t ms) { //Create a beep with KY-012 active buzzer **************
digitalWrite(buzAct,HIGH); //Turn buzzer on
while (ms > 0){ //Timer of the duration of the beep
delay(5); //Wait milliseconds
ms--; //Countdown untill we reached zero
} //Timer of the duration of the beep has been counted down to zero
digitalWrite(buzAct,LOW); //Turn annoying buzzer off as fast as you can
} //Exit beep ------------------------------------------------------------------
void toggle_ledOnBoard(void){ //Toggles the LED_BUILTIN on-board LED on or off *
ledOnBoardVal = !ledOnBoardVal; //Toggle value
digitalWrite(LED_BUILTIN, ledOnBoardVal); //Set Arduino boards onboard LED
} //Exit toggle_ledBin ---------------------------------------------------------
void disable_jtag(void) { //Disable jtag to free port C, enabled by default ****
#if defined(JTD) //Not all AVR controller include jtag
MCUCR |= ( 1 << JTD ); //Write twice to disable
MCUCR |= ( 1 << JTD ); //So stutter once
#endif //End of conditional compiling
} //Exit jtag_disable ----------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO MEGA 2560 //
// Board -Atmel- PIN - IDE - Function - External Connection FUNC //
// //
// CONNECTIONS RAILS TOP LEFT: DIGITAL PWM<~> ******************************* //
// SCL - 28 - PC5 -19/A5- ADC5/SCL/PCINT13 - DS1307 SCL orange TWI //
// SDA - 27 - PC4 -18/A4- ADC4/SDA/PCINT12 - DS1307 SDA white TWI //
// AREF - 31 - REF - - AREF - REF //
// 13 PWM - 26 - PB7 - 13 - OC0A/OC1C/PCINT17 - LED Arduino LED_BUILTIN PWM //
// 12 PWM - 18 - PB6 - 12 - OC1B/PCINT16 - PWM //
// 11 PWM - 17 - PB3 - 11 - MOSI/OC2A/PCINT3 - PWM //
// 10 PWM - 16 - PB2 - 10 - SS/OC1B/PCINT2 - PWM //
// 9 PWM - 15 - PB1 - 9 - OC1A/PCINT1 - PWM //
// 8 PWM - 14 - PB0 - 8 - PCINT0/CLK0/ICP1 - DIO //
// //
// CONNECTIONS RAILS TOP MIDDLE: DIGITAL PWM<~> ***************************** //
// 7 PWM - 13 - PD7 - 7 - PCINT23/AIN1 - PWM //
// 6 PWM - 12 - PD6 - 6 - PCINT22/OCA0/AIN0 - PWM //
// 5 PWM - 11 - PD5 - 5 - PCINT21/OC0B/T1 - PWM //
// 4 PWM - 6 - PD4 - 4 - PCINT20/XCK/T0 - PWM //
// 3 PWM - 5 - PD3 - 3 - PCINT19/OC2B/INT1 - PWM //
// 2 PWM - 4 - PD2 - 2 - PCINT18/INT0 - INT //
// 1 TX0 - 3 - PD1 - 1 - PCINT17/TXD - Serial monitor TX0 //
// 0 RX0 - 2 - PD0 - 0 - PCINT16/RCD - Serial Monitor RC0 //
// //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 14 TX3 - 13 - PD7 - 7 - PCINT23/AIN1 - DIO //
// 15 RX3 - 12 - PD6 - 6 - PCINT22/OCA0/AIN0 - PWM //
// 16 TX2 - 11 - PD5 - 5 - PCINT21/OC0B/T1 - TX2 //
// 17 RX2 - 6 - PD4 - 4 - PCINT20/XCK/T0 - DS18B20 green RX2 //
// 18 TX1 - 5 - PD3 - 3 - PCINT19/OC2B/INT1 - Transmit to ESP01 blue INT //
// 19 RX1 - 4 - PD2 - 2 - PCINT18/INT0 - Rec from ESP01 yellow INT //
// 20 SDA - 3 - PD1 - 1 - PCINT17/TXD - DS1307 white TWI //
// 21 SCL - 2 - PD0 - 0 - PCINT16/RCD - DS1307 orange TWI //
// //
// CONNECTIONS RAILS BOTTOM LEFT: POWER ************************************* //
// 5V - 7 - VCC - - VCC - VCC //
// RES - 1 - RES - - PCINT14/RESET - RES //
// 3.3V - - - - - //
// 5V - - - - - //
// GND - - - - - //
// GND - - - - - //
// Vin - - - - - //
// //
// CONNECTIONS RAILS BOTTOM CENTER: ANALOG IN ******************************* //
// A0 - 23 - PC0 -A0/14- ADC0/PCINT8 - ADC //
// A1 - 24 - PC1 -A1/15- ADC1/PCINT9 - ADC //
// A2 - 25 - PC2 -A2/16- ADC2/PCINT10 - ADC //
// A3 - 26 - PC3 -A3/17- ADC3/PCINT12 - ADC //
// A4 - 27 - PC4 -A4/18- ADC4/SDA/PCINT12 - TWI //
// A5 - 28 - PC5 -A5/19- ADC5/SCL/PCINT13 - TWI //
// //
// CONNECTIONS RAILS BOTTOM RIGHT: ANALOG IN ******************************** //
// A08 - 89 - PK0 - - ADC1 4/PCINT? - Moisture Capac yellow ADC //
// A09 - 88 - PK1 - - ADC15/PCINT? - ADC //
// A10 - 87 - PK2 - - ADC14/PCINT? - ADC //
// A11 - 86 - PK3 - - ADC15/PCINT? - ADC //
// A12 - 85 - PK4 - - ADC14/PCINT? - ADC //
// A13 - 84 - PK5 - - ADC15/PCINT? - ADC //
// A14 - 83 - PK6 - - ADC14/PCINT22 - ADC //
// A15 - 82 - PK7 - - ADC15/PCINT23 - ADC //
// //
// CONNECTIONS RAILS QUER RIGHT ********************************************* //
// Board -Atmel- PIN - IDE - Function - External Connection FUNC //
// 32 - 58 - PC5 - - DIO - DIO //
// 44 - 40 - PL5 - - OC5C - 3 Color led Red PWM //
// 45 - 39 - PL4 - - OC5B - 3 Color led Blue PWM //
// 46 - 38 - PL3 - - OC5A - 3 Color led Green PWM //
// 47 - 37 - PL2 - - T5 - DHT22 one-wire white DIO //
// 48 - 36 - PL1 - - ICP5 - Relais 1 brown DIO //
// 49 - 35 - PL0 - - ICP4 - Relais 2 brown DIO //
// 50 - 22 - PB3 - - MISO/PCINT3 - Relais 3 brown SPI //
// 51 - 21 - PB2 - - MOSI/PCINT2 - Relais 4 brown SPI //
// 52 - 20 - PB1 - - SCK/PCINT1 - Activ buzzer blue SPI //
// 53 - 19 - PB1 - - SS/PCINT0 - SPI //
// 54 - - GND - - GND - GND //
// 55 - - GND - - GND - GND //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//3456789112345678921234567893123456789412345678951234567896123456789712345678//
// EEPROM MEMORY MAP: //
// Start End Number Description //
// 0000 0000 1 Never use this memory location to be AVR compatible //
// 0001 0001 1 wateringProg Usr choice: 1=off 2=on 3=auto RELAY1 //
// 0002 0003 2 wateringON If CAPAC reaches this 2byte treshold RELAY1 //
// 0004 0005 2 wateringSecs How many seconds to keep ON RELAY1 //
// 0006 0006 1 Temperature/10 airheater Switch ON RELAY2 (0-25,5) //
// 0007 0007 1 Temperature/10 airheater Switch OFF RELAY2 (0-25,5) //
// 0008 0008 1 Usr choice: airheater 1=off 2=on 3=auto RELAY2 //
// 0009 0009 1 Temperature/10 heat coil Switch ON RELAY3 (0-25,5) //
// 0010 0010 1 Temperature/10 heat coil Switch OFF RELAY3 (0-25,5) //
// 0011 0011 1 Usr choice: heatcoil 1=off 2=on 3=auto RELAY3 //
// 0012 0012 1 Number of hours around noon GROWLED RELAY4 //
// 0013 0013 1 /Usr choice: growled 1=off 2=on 3=auto RELAY4 //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898
////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered by using the STK500) //
// On-Chip Debug Enabled: off (OCDEN=0) //
// JTAG Interface Enabled: off (JTAGEN=0) //
// Preserve EEPROM mem through the Chip Erase cycle: On (EESAVE = 0) //
// Boot Flash section = 2048 words, Boot startaddr=$3800 (BOOTSZ=00) //
// Boot Reset vector Enabled, default address=$0000 (BOOTSTR=0) //
// CKOPT fuse (operation dependent of CKSEL fuses (CKOPT=0) //
// Brown-out detection level at VCC=2,7V; (BODLEVEL=0) //
// Ext. Cr/Res High Freq.; Start-up time: 16K CK + 64 ms (CKSEL=1111 SUT=11) //
// LOCKBITS (are dangerous to change, since they cannot be reset) //
// Mode 1: No memory lock features enabled //
// Application Protect Mode 1: No lock on SPM and LPM in Application Section //
// Boot Loader Protect Mode 1: No lock on SPM and LPM in Boot Loader Section //
////////////////////////////////////////////////////////////////////////////////