#include //*** Enables OTA programming. 1 of 3 lines
WiFiServer server(80); //Used for WiFi Server
#include
#include
#include //Real Time Clock library on I2C for DS3231. pin D1 is SCL, pin D2 is SDA
#include //Used for DS18B20 temp sensors https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
#include //Used for DS18B20 temp sensors. Run Simple DS18B20 from DallasTemperature first to find sensor addresses.
//Run Example Simple.pde from DallasTemperature first to find sensor addresses.
#include //I2C library Used for Real Time Clock and MCP23017 I/O expander. Same two wires.
#include //RTC library
#define ONE_WIRE_BUS D5 //Define pin the one wire bus is on
RtcDS3231 Rtc(Wire); // Real Time clock
int yvalue, rvalue, input4, analoginput, counter, wkday, offtimewh;
// int automode; // auto mode
//****ESP Now Receive Variables***************************
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
memcpy(&myData, incomingData, sizeof(myData));
}
//****End of ESP Now Receive Variables********************
int lastSecond = -1; // set last second to impossible number so it prints right away then every second
int lastSecond1 = -1; // used to reset alert only once per second
int currentmillis = 0;
int previousmillis = 0;
String request, timedate, Month, Day, Hour, Minute, Second, dow, distancestring;
String insidetemp, humidity, furnaceLED, basementtemp, outsidetemp, tempdata;
float temp1, t2, temp2, h1, prevh1, prevt1, amps;
// Furnace Variables
int Light = 0;
int Fan = 0;
float degreesC, temp1raw, temp2raw;
int light_level, furnaceONvalue;
int seconds, timeNOW, timeLAst;
// Ultrasonic variables
// int trig = D4;// common trigger output
int ultrasonics_read;
int distance_echo = D0;
int distance_duration; int Barreldistance; int distance=100; int Barrel_full; // initialize level to 100% so pumps don't start after upload - only reads level every minute
int Tankduration; int Tankdistance; int Tank_level=100; // initialize level to 100% so pumps don't start after upload - only reads level every minute
// End of Ultrasonic Variables
OneWire oneWire(ONE_WIRE_BUS); //Used for DS18B20 temp sensors
DallasTemperature sensors(&oneWire); //Used for DS18B20 temp sensors
DeviceAddress Sens1, Sens2; //Used for DS18B20 temp sensors
void setup() {
ArduinoOTA.begin(); //*** Enables OTA programming. 2 of 3 lines
server.begin();
pinMode(D0, INPUT); // Initialize D1 pin as an input Barrel Ultrasonic echo on Nodemcu 12E board
// pinMode(D3, OUTPUT); // Initialize D3 pin as an output Ultrasonic trigger on Nodemcu 12E board
pinMode(D4, OUTPUT); // Initialize D4 pin as an output Ultrasonic trigger on Nodemcu 12E board
pinMode(D6, OUTPUT); // Initialize D6 pin as an output for LIGHT on relay 1 on Nodemcu 12E board
pinMode(D7, OUTPUT); // Initialize D7 pin as an output for FAN on relay 2 on Nodemcu 12E board
// Initialize relay outputs to HIGH since LOW activates the relay
digitalWrite(D6, HIGH); // Relay 1 for Light
digitalWrite(D7, HIGH); // Relay 2 for Fan
Rtc.Begin(); //Starts I2C
// Start up the DS18B20 library and set temp resolution 11 bits equals .125C
sensors.begin();
sensors.getAddress(Sens1, 0);
sensors.setResolution(Sens1, 11);
sensors.getAddress(Sens2, 1);
sensors.setResolution(Sens2, 11);
// Uncomment next two lines to set Real Time Clock if required - after setting clock make sure and upload commented version again or time will be reset on reboot
// RtcDateTime t = RtcDateTime(19, 9, 12, 14, 8, 0); //set date and time NO leading zeroes (yr mo day Hour min sec)
// Rtc.SetDateTime(t); //configure the RTC with object // send about 25 secs before actual time.gov time to allow for compile
//******ESP NOW Setup****************************************************
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
// Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
esp_now_register_recv_cb(OnDataRecv);
//******End of ESP NOW Setup*********************************************
}
int automode = 0; // default mode is AUTO OFF mode
void loop() {
ArduinoOTA.handle(); //*** Enables OTA programming. 3 of 3 lines
if (myData.b > 300) digitalWrite(D4, LOW); // Turn the LED on (Note that LOW is the voltage level
if (myData.b < 300) digitalWrite(D4, HIGH); // mData.b is coming from the sending NodeMCU
//*************Analog Input read******************************************************
analoginput = analogRead(0); //Check!! Nodemcu 12E is digital 0 to 1024 for input 0 to 3.3V NOT 0 to 1.0V on pin A0.
furnaceONvalue = analoginput; // furnace program uses this variable for analog input of furnace LED ON
//*************End Analog Input read******************************************************
//*******Get Date and Time*************************************************
RtcDateTime t = Rtc.GetDateTime(); //get the time from the RTC
char str[15]; //declare a string as an array of chars
sprintf(str, "%d/%d/%d %d:%d:%d", //%d allows to print an integer to the string
t.Year(), //get year method
t.Month(), //get month method
t.Day(), //get day method
t.Hour(), //get Hour method
t.Minute(), //get Minute method
t.Second() //get Second method
);
//********End Get Date and Time***********************************************
//*********Light ON/OFF Logic*************************************************
if (Light == 1) digitalWrite(D6, LOW);// Light is on NC contacts so Default is OFF. LOW activates relay to turn Fan ON
if (Light == 0) digitalWrite(D6, HIGH);// LOW deactivates relay to turn Light OFF
//********End Light ON/OFF Logic*********************************************
//********* Fan ON/OFF Logic*************************************************
if (Fan == 1) { digitalWrite(D7, LOW); // Turn ON Fan
}
if (Fan == 0) { digitalWrite(D7, HIGH); // Turn OFF Fan
}
//*********Fan ON/OFF Logic*************************************************
//********Read temp from DS18B20s*****************************
sensors.requestTemperatures(); // Send the command to get temperatures from DS18B20s
// Reading temperatures from sensors
temp1raw = sensors.getTempCByIndex(0); //DSB1820 temp1
if ((temp1raw > -50.0) && (temp1raw < 50.0)) temp1 = temp1raw; // error checking
temp2raw = sensors.getTempCByIndex(1); //DSB1820 temp2
if ((temp2raw > -50.0) && (temp2raw < 50.0)) temp2 = temp2raw; // error checking
if ((automode == 1) && (temp1 > 24.0)) digitalWrite(D7, LOW); //LOW activates relay
if ((automode == 1) && (temp1 < 23.0)) digitalWrite(D7, HIGH); // HIGH deactivates relay
if ((automode == 1) && (temp1 > 24.0)) Fan = 1; // for web page display
if ((automode == 1) && (temp1 < 23.0)) Fan = 0; // for web page display
//********End read temperature ****************************************
//*****Read Ultrasonics*********************************************************
if ((t.Second() == 0) || (t.Second() == 5) || (t.Second() == 10) || (t.Second() == 15) || (t.Second() == 30) || (t.Second() == 35) || (t.Second() == 40) || (t.Second() == 45) || (t.Second() == 50) || (t.Second() == 55)) ultrasonics_read = 0; // reset ultrasonics_read bit after 0
if (ultrasonics_read == 0){ // only read ultrasonics once every 5 secs
ultrasonics_read = 1; // only read once every five seconds
// Ultrasonic Distance Sensor
delay(10);
// Clears the trig
// digitalWrite(trig, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
// digitalWrite(trig, HIGH);
delayMicroseconds(10);
// digitalWrite(trig, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
distance_duration = pulseIn(distance_echo, HIGH);
// Calculating the distance
distance = distance_duration*0.17; // BML demo for distance in mm
delay(100);
}
//*****End Read Ultrasonic*****************************************************
//***read photoresistor light_level *****
light_level = 1024 - analogRead(0);
if ((automode == 1) && (light_level < 500)) Light = 1;
if ((automode == 1) && (light_level > 600)) Light = 0;
//********end read photoresistor light_level *******************
//*******WiFi detect client and record input********************************
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Read the first line of the request
request = client.readStringUntil('\r');
client.flush();
//*******End of WiFi detect client and record input********************************
//*************Actions on web page button click. Buttons defined below.************************
if (request.indexOf("/FAN=ON") != -1) {// Input from screen. No spaces in name.
if (automode == 0) Fan = 1;
}
if (request.indexOf("/FAN=OFF") != -1) {// Input from screen. No spaces in name.
if (automode == 0) Fan = 0;
}
// Match the request
if (request.indexOf("/LIGHT=ON") != -1) {// yvalue = Sys ON. Input from screen. No spaces in name.
if (automode == 0) Light = 1;
}
if (request.indexOf("/LIGHT=OFF") != -1) {// Input from screen. No spaces in name.
if (automode == 0) Light = 0;
}
if (request.indexOf("/AUTO_ON") != -1) {// Input from screen. No spaces in name. Water heater auto mode
automode = 1;
}
if (request.indexOf("/AUTO_OFF") != -1) {// Input from screen. No spaces in name. Water heater auto mode
automode = 0;
}
request.indexOf("/HOME"); // Go to Home page after LEDs set.
//*******End of web page button actions******************************************************
//****** Return the response in HTML on web page************************************
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("");
client.println( // start code html with this. Have to add quotes before and after. Delete most html quotes in line.
""
""
"ESP NOW Web Page Demo"
// "" // Auto refresh every 60 secs. Issues?
""
""
""
"" //Use monospace font to make columns of text and numbers line up
"
"); // large font applies between
and
below
//*********End HTML page start of defintion*****************************************
//*********Print Date and Time add leading zeroes to Web Page***********************************
Hour = String(t.Hour()); // integers like t.Hour() are used for comparisons and control. Change to string for display and add leading zeroes
if (t.Hour() <= 9) Hour = "0" + Hour; // adjust for 0-9
Minute = String(t.Minute());
if (t.Minute() <= 9) Minute = "0" + Minute; // adjust for 0-9
Second = String(t.Second());
if (t.Second() <= 9) Second = "0" + Second; // adjust for 0-9
if (t.DayOfWeek() == 0) dow = " Sun"; // t.DayOfWeek() calculated from rest of date not from DS3231
if (t.DayOfWeek() == 1) dow = " Mon";
if (t.DayOfWeek() == 2) dow = " Tue";
if (t.DayOfWeek() == 3) dow = " Wed";
if (t.DayOfWeek() == 4) dow = " Thu";
if (t.DayOfWeek() == 5) dow = " Fri";
if (t.DayOfWeek() == 6) dow = " Sat";
Month = String(t.Month());
Day = String(t.Day());
if (t.Month() <= 9) Month = "0" + Month; // adjust for 0-9 in month
if (t.Day() <= 9) Day = "0" + Day; // adjust for 0-9 in day
timedate = String(t.Year())+ "/" + Month + "/" + Day + " " + Hour + ":" + Minute + ":" + Second ; // create string for display with one client.println
client.println(timedate);
client.println(" "); // add spaces
client.println(dow); // print day of week
client.println(" "); // add spaces
//*********End Print Date and Time to Web Page ********************************************
//*********Web Page Button Style defintion CSS******************************************************************
client.println( //html output. Put quotes around html code. Don't have to client.println every line
""
//*****End Web Page Button Style Definition************************************************************************************************
//******Web Page Buttons Definitions************************************************************************************************
" "
"" // LIGHT ON button definition. No spaces
" " // horizontal space between buttons
"" //LIGHT OFF button definition. No spaces
" "
"" // FAN ON button definition. No spaces
" " // horizontal space between buttons
"" //FAN OFF button definition. No spaces
" " // horizontal space between buttons
""); //Home button definition. No spaces
// client.print(" "); // add spaces
//client.println(
// " "); // add spaces
//*****End Button Definition************************************************************************************************
//***** Display data to web page
client.println("" //Use monospace font to make columns of text and numbers line up
"
"); // large font applies between
and
below
tempdata = "Temp "+String(temp1,1)+"C";
client.println(tempdata);
client.println(" ");
client.println(" Light_Level ");
client.println(myData.b);
client.println(" ");
distancestring = "Distance "+String(distance)+"mm";
// client.println(distancestring);
client.println(" Counter ");
client.println(myData.c);
client.println(" ");
client.println(" ");
client.println(" ");
client.println(" ");
// client.println(" ");
//client.println(" ");
client.println(
//***Furnace and water heater buttons***************
" " //Clear Flag button definition. No spaces
" "
" ");
//***End furnace and water heater buttons***********
// " ");
//****Print data to web page
client.println("" //Use monospace font to make columns of text and numbers line up
"
"); // large font applies between
and
below
client.println(" ");
client.println(" ");
if (automode == 1) client.println("Auto:ON_");
if (automode == 0) client.println("Auto:OFF");
client.println(" ");
client.println(" ");
if (Light == 0) client.println("Light:OFF");
if (Light == 1) client.println("Light:ON_");
client.println(" ");
if (Fan == 0) client.println("Fan:OFF");
if (Fan == 1) client.println("Fan:ON_");
client.println(" ");
client.println("ESP NOW");
client.println(" ");
client.println(" ");
client.println(" ");
client.println(" ");
client.println(" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
"."); // add period below the background you want to display or it won't scroll past last text
client.println("