////////////////////////////////////////////////////////////////////////////////
// Name: FloraMoisture2560-2018 //
// Platform: Arduino Mega 2560 //
// Created by: HARB rboek2@gmail.com July 2018 GPL copyrights //
// http://robotigs.nl/robotigs/includes/bots_header.php?idbot=7 //
// This robot is built to replace the 2017 Uno robot in the greenhouse //
// 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) //
////////////////////////////////////////////////////////////////////////////////
// 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 COMPILER
//#ifdef RS232 //Only include these lines if RS232 has been defined COMPILER
//#endif //End of conditional compiling COMPILER
// Uncomment to use WIFI -----------------------------------------------------
#define WIFIrun //Uncomment to include WIFI COMPILER
//#ifdef WIFIrun //Only include these lines if WIFIrun is defined COMPILER
// Include the needed header files for the precompiler, no charge if not used-
#include <DHT.h> //Needed for DHT22 and DHT11 sensors HEADER
#include <Wire.h> //Two Wire Interface HEADER
#include <RTClib.h> //connected via I2C and Wire lib HEADER
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
#include <WiFiEsp.h> //https://github.com/bportaluri/WiFiEsp HEADER
#endif //End of conditional compiling COMPILER
// Define precompiler variables, runs faster & doesn`t use RAM ---------------
// Define PINS ---------------------------------------------------------------
#define buzAct 14 //Define which I/O pin connects the activ BUZZER
#define ledRedPin 44 //3 Colour LED, which PWM pin connects redLED
#define ledBluPin 45 //3 Colour LED, to which PWM pin connects blueLED
#define ledGrePin 46 //3 Colour LED, to which PWM pin connects greenLED
#define DHTPIN 47 //What DIO pin connects DHT22
#define Relay1Pin 48 //220Vac switch DIO pin connects RELAY
#define sonde2Power 50 //Pin for Soil moisture +5Vdc Power VOLTAGE DIVIDER
#define soilPower 52 //Pin for Soil moisture Power MOISTURE
#define soilPin A0 //Declare a pin for the soil moisture sensor MOISTURE
#define soilSonde2 A1 //Sensorpin ADC soil moisture sensor VOLTAGE DIVIDER
#define ldrPin A15 //Define to which DA converter pin connects LDR
#define DHTTYPE DHT22 //What sensor is connected (AM2302) (AM2321) DHT22
//Define VARIABLES -----------------------------------------------------------
bool ledOnBoardVal = LOW; //You choose HIGH-on or LOW-off for LED_BUILTIN
bool Relay1val = LOW; //You can chose HIGH-on or LOW-off for RELAY1
int Relay1usr = 2; //Usr setting off 1=unknown 2=off 3=on 4=auto RELAY1
int tmp1minimum = 2; //Temperature 1=unknown 2=off 3=>0degC 4=>3degC RELAY1
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
String timestamp; //String with stamp of current measurment DS1307
float grenairtmp1; //Temperature as measured by DHT22
float grenairhum1; //Humidity as measured by DHT22
word ldrVal = 0; //Contains last measurement (0-1023) LDR
int moistureTimer = 20; //Cycles after which measurement is made MOISTURE
int moistureCnt1 = 1; //Used to count down the moistureTimer MOISTURE
word moi1val = 0; //Value current moisture reading MOISTURE
word moi1min = 1023; //Statistics minimum moisture content MOISTURE
word moi1max = 0; //Statistics maximum moisture content MOISTURE
word moi2val = 0; //Value current moisture reading VOLTAGE DIVIDER
word moi2min = 1023; //Statistics minimum moisture VOLTAGE DIVIDER
word moi2max = 0; //Statistics maximum moisture VOLTAGE DIVIDER
String html = ""; //HTML Response preapaired WIFI
unsigned int bodyLength; //HTML answer length WIFI
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
char ssid[] = "Ranonkel9_EXT"; // Network SSID (name) WIFI
char pass[] = "123456789"; //Network password WIFI
int status = WL_IDLE_STATUS; //Status of the ESP01 WIFI
#endif //End of conditional compiling COMPILER
// Initialize OBJECTS --------------------------------------------------------
DHT dht(DHTPIN, DHTTYPE); //Initialize sensor object DHT22
DS1307 rtc; //Initialize Real Time Clock object DS1307
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
WiFiEspServer server(80); //Open port for requests
RingBuffer buf2(8); //Ringbuffer increases speed and reduces memory WIFI
#endif //End of conditional compiling COMPILER
//END OF PRECOMPILER OPTIONS ---------------------------------------------------
void setup() { // **************************************************************
disable_jtag(); //Disable jtag to free port C, enabled by default JTAG
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
pinMode(Relay1Pin, OUTPUT); //Set this pin as output to RELAY
pinMode(Relay1Pin, OUTPUT); //Set this pin as output to RELAY
digitalWrite(Relay1Pin, LOW); //Switches OFF the RELAY
pinMode(soilPower, OUTPUT); //Set 52 as an OUTPUT MOISTURE
digitalWrite(soilPower, LOW); //Set to LOW so no power is flowing MOISTURE
pinMode(sonde2Power, OUTPUT); //Set 50 as an OUTPUT VOLTAGE DIVIDER
digitalWrite(sonde2Power, LOW); //Set LOW so no power flows VOLTAGE DIVIDER
Serial.begin(9600); //Nothing more needed for the Serial Monitor RSR232
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
Serial1.begin(57600); //RS232 Speed is preset at ESP01
#endif //End of conditional compiling COMPILER
//Start objects --------------------------------------------------------------
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
rtc.begin(); //Start the object running DS1307
//rtc.adjust(DateTime(__DATE__, __TIME__)); //Set to time compiled DS1307
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
initializeWiFI(); //Initializes and connects to network WIFI
#endif //End of conditional compiling COMPILER
//Test hardware and software -------------------------------------------------
//test_RELAY(); //Switches ON for 2 seconds the RELAY
test_LEDs(); //PWM fade in and fade out for all 4 LEDs on board LED
beep(10); //Create a test beep with KY-012 active BUZZER
Serial.println("Setup completed"); //Show the user the setup is done RS232
Serial.println(""); //Just give out an empty line RS232
} //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); //Formatstring for the time DS1307
timestamp = now.format(buf); //Format the timestap into a variable DS1307
grenairtmp1 = dht.readTemperature(); //Read temperature as Celsius DHT22
grenairhum1 = dht.readHumidity();//Reading sensor takes 250 milliseconds DHT22
ldrVal = analogRead(ldrPin); //Read voltage on pin A15 LDR
readMoisture(); //Read moisture sensors at time intervals only MOISTURE
refreshAnswer(); //Replace the old answer by a new one WIFI
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
checkWifi(); //Check if any request available and if so then respond WIFI
#endif //End of conditional compiling COMPILER
//showMonitor(); //Shows all values at the serial monitor RS232
//showMoisture(); //Shows all values at the monitor, not with wifi, RS232
//beep(1); //Tell the world we are awake BUZZER
toggle_ledOnBoard(); //Toggles the LED_BUILTIN ON or OFF onboardLED
} //End of void loop() ----------------------- KEEP ON RUNNING THIS LOOP FOREVER
void checkWifi(){ //Check if any request available and if so then respond WIFI
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
digitalWrite(ledBluPin, HIGH); //Blue HIGH=on, LOW=off activityLED
WiFiEspClient client = server.available(); //Listen for incoming clients WIFI
if (client) { //If you get a client then do WIFI
handleClient(client); //Answers a client request made by WIFI
moi1min = 1023; //RESET Statistics minimum moisture content MOISTURE
moi1max = 0; //RESET Statistics maximum moisture content MOISTURE
moi2min = 1023; //RESET Statistics minimum moisture VOLTAGE DIVIDER
moi2max = 0; //RESET Statistics maximum moisture VOLTAGE DIVIDER
Serial.println(""); //Just give out an empty line RS232
} //End of if (client) { //If you get a client then do WIFI
digitalWrite(ledBluPin, LOW); //Blue HIGH=on, LOW=off activityLED
#endif //End of conditional compiling COMPILER
} //End of checkWifi Check if any request available and if so then respond WIFI
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
void handleClient(WiFiEspClient client){ //Answers a client request made by 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
if (buf2.endsWith("\r\n\r\n")) { //Check for 2 newline characters in row
Serial.println("Starting to send response"); //Showing we handeld
sendHttpResponse(client); //Meaning the end of the HTTP request
Serial.println("End of sending response");//Showing we handeld a req
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
} //End of handleClient(){ Answers a client request made by WiFi ---------------
#endif //End of conditional compiling COMPILER
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
void sendHttpResponse(WiFiEspClient client) { //Sends measurements WIFI ********
//HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
//and a content-type so the client knows what's coming, then a blank line:
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
//client.println(); //Any HTTP response ends with another blank line WIFI
//client.println(); //Any HTTP response ends with another blank line WIFI
//delay(500); //Give the web browser time to receive the data WIFI
} //Exit sendHttpResponse ------------------------------------------------------
#endif //End of conditional compiling COMPILER
void refreshAnswer(void) { //Replace the old answer by a new one WIFI **********
if (String(grenairtmp1) == " NAN"){ //Correct answer if not connected DHT22
grenairtmp1 = -3; //Both temperature and humidity will affected DHT22
grenairhum1 = -3; //Humidity value gives status not connected DHT22
}//End of String(grenairtmp1) = " NAN" Answer corrected if not connected DHT22
moi1val = (moi1min + moi1max) / 2; //Stabilizes measurements MOISTURE
html = (timestamp); //Start with a fresh string and enter a value DS1307
html += " "; //All response values are separated by a blank space WIFI
html += String(grenairtmp1); //Add another value to the response DHT22
html += " "; //All response values are separated by a blank space WIFI
html += String(grenairhum1); //Add another value to the response DHT22
html += " "; //All response values are separated by a blank space WIFI
html += String(ldrVal); //Add another value to the response LDR
html += " "; //All response values are separated by a blank space WIFI
html += String(Relay1val); //Add another value to the response RELAY
html += " "; //All response values are separated by a blank space WIFI
html += String(Relay1usr); //Add another value to the response RELAY
html += " "; //All response values are separated by a blank space WIFI
html += String(tmp1minimum); //Add another value to the response RELAY
html += " "; //All response values are separated by a blank space WIFI
html += String(moi1val); //Add another value to the response MOISTURE
html += " "; //All response values are separated by a blank space WIFI
html += String(moi1min); //Add another value to the response MOISTURE
html += " "; //All response values are separated by a blank space WIFI
html += String(moi1max); //Add another value to the response MOISTURE
html += " "; //All response values are separated by a blank space WIFI
html += String(moi2val); //Add another value to the response VOLTAGE DIVIDER
html += " "; //All response values are separated by a blank space WIFI
html += String(moi2min); //Add another value to the response VOLTAGE DIVIDER
html += " "; //All response values are separated by a blank space WIFI
html += String(moi2max); //Add another value to the response VOLTAGE DIVIDER
bodyLength = html.length(); //Calculate the number of characters to sent WIFI
} //Exit refreshAnswer ---------------------------------------------------------
int readMoisture() { //Read moisture sensors at time intervals only ************
if (moistureCnt1 == 0){ //Only perform measurements if counted down MOISTURE
readSoil(); //Some way of reading the moistureSpark MOISTURE
readSoilMoi2(); //Another way of reading the moisture VOLTAGE DIVIDER
moistureCnt1 = moistureTimer; //RESET the counter MOISTURE
}else{ //Meaning counter was not yet zero MOISTURE
moistureCnt1--; //Decrement of the timer counter MOISTURE
} //End of if (moistureCnt1 == 0)Perform measurements if counted down MOISTURE
} //Exit readMoisture ----------------------------------------------------------
int readSoil() { //Some way of reading the MOISTURE ****************************
digitalWrite(soilPower, HIGH); //Turn pin52 "On" MOISTURE
delay(10); //Wait 10 milliseconds MOISTURE
moi1val = analogRead(soilPin); //Read the SIG value form sensor MOISTURE
digitalWrite(soilPower, LOW); //Turn pin52 "Off" MOISTURE
if (moi1val < moi1min){ //Do some statistics MOISTURE
moi1min = moi1val; //Do some statistics MOISTURE
} //Do some statistics MOISTURE
if (moi1val > moi1max){ //Do some statistics MOISTURE
moi1max = moi1val; //Do some statistics MOISTURE
} //Do some statistics MOISTURE
} //Exit readSoil --------------------------------------------------------------
int readSoilMoi2() { //Another way of reading the moisture VOLTAGE DIVIDER *****
digitalWrite(sonde2Power, HIGH); //Turn pin50 "On" VOLTAGE DIVIDER
delay(10); //Wait 10 milliseconds MOISTURE
moi2val = analogRead(soilSonde2); //Read the value from probe VOLTAGE DIVIDER
digitalWrite(sonde2Power, LOW); //Turn pin50 "Off" VOLTAGE DIVIDER
if (moi2val < moi2min){ //Do some statistics VOLTAGE DIVIDER
moi2min = moi2val; //Do some statistics VOLTAGE DIVIDER
} //Do some statistics VOLTAGE DIVIDER
if (moi2val > moi2max){ //Do some statistics VOLTAGE DIVIDER
moi2max = moi2val; //Do some statistics VOLTAGE DIVIDER
} //Do some statistics VOLTAGE DIVIDER
} //Exit readSoilMoi2 ----------------------------------------------------------
void showMoisture(){ //Shows all values at the serial monitor RS232 ************
Serial.print("Meting1:"); //Print the answer to RS232
Serial.print(moi1val); //Print the answer to RS232
Serial.print(" Meting2:"); //Print the answer to RS232
Serial.print(moi2val); //Print the answer to RS232
Serial.println(); //Print the answer to RS232
} //End of showMonitor(){ Shows all values at the serial monitor RS232 ---------
void initializeWiFI(){ //Initializes and connects to network *******************
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
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
//status = WiFi.beginAP(ssid, 10, pass, ENC_TYPE_WPA2_PSK); //We are router
} //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
#endif //End of conditional compiling COMPILER
} //End of initializeWiFI(){ Initializes and connects to network ---------------
#ifdef WIFIrun //Only include these lines if WIFIrun has been defined COMPILER
void printWifiStatus() { //Show relevant network settings to the user RS232 ****
Serial.println("You're connected to the network");
// print the SSID of the network you're attached to
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print where to go in the browser
Serial.println();
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
Serial.println();
// print the received signal strength
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI): ");
Serial.println(rssi);
}
#endif //End of conditional compiling COMPILER
void test_RELAY(){ //Switches ON for 2 seconds the RELAY ***********************
digitalWrite(Relay1Pin, HIGH); //Switches ON the RELAY
delay (2000); //Wait for 2 seconds
digitalWrite(Relay1Pin, LOW); //Switches OFF the RELAY
} //End of test_Relay(){ Switches ON for 2 seconds the RELAY -------------------
void showMonitor(){ //Shows all values at the serial monitor RS232 *************
Serial.println(html); //Print the answer to RS232
delay(5000);
} //End of showMonitor(){ Shows all values at the serial monitor RS232 ---------
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 DHT22 sensor **********
Wire.beginTransmission(addr);
Wire.write(value);
Wire.endTransmission();
} //Exit writeI2CRegister8bit --------------------------------------------------
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 - Activ buzzer orange 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 - 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 - TWI //
// 21 SCL - 2 - PD0 - 0 - PCINT16/RCD - 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? - 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 - LDR purple 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 purple DIO //
// 49 - 35 - PL0 - - ICP4 - DIO //
// 50 - 22 - PB3 - - MISO/PCINT3 - SPI //
// 51 - 21 - PB2 - - MOSI/PCINT2 - SPI //
// 52 - 20 - PB1 - - SCK/PCINT1 - SPI //
// 53 - 19 - PB1 - - SS/PCINT0 - SPI //
// 54 - - GND - - GND - GND //
// 55 - - GND - - GND - GND //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898
// EEPROM MEMORY MAP: //
// Start End Number Description //
// 0000 0000 1 Never use this memory location to be AVR compatible //
////////////////////////////////////////////////////////////////////////////////
//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 //
////////////////////////////////////////////////////////////////////////////////