Temperature Monitoring (indoor and outdoor)
https://randomnerdtutorials.com/guide-for-ds18b20-temperature-sensor-with-arduino/
#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <DHT_U.h>
#include <EEPROM.h>
//////////////////////////////
// EDIT THIS SECTION
int activeConnection = 1;
// primary wifi
const String ssid1 = "xxx";
const String password1 = "xxxxx";
// secondary wifi
const String ssid2 = "xxxx";
const String password2 = "xxxxx";
const String heartbeatUrl = "https://xxx.xxx.ca/silopower/heartbeat.php";
const String temperatureUrl = "https://xxx.xxx.ca/silopower/set_temp_humidity.php?data=";
// end edit section
////////////////////
#define EEPROM_SIZE 4
int eepromPingsAddress = 0;
float totalServerPings = 0;
int eepromFailedPingsAddress = 1;
float totalServerPingFails = 0;
int eepromActiveConnection = 1;
String prevTemperatureText = "";
String prevHumidifyText = "";
String prevConnectivityText1 = "";
String prevConnectivityText2 = "";
const int indoorTemperaturePin = 16;
const int outdoorTemperaturePin = 17;
const int buttonPin = 15;
int buttonState = 0;
int displayMode = 1; // 1: watts, watts per hours, voltage 2: temp, humidiy 3: internet
const float potOffset = 895; // try 900 next ... 910 // higher value results in lower reading
const int pulseRate = 1000; // loop runs once per second
const int serverSendInterval = 10; // 10 minutes between sending a voltage update to the server
const int samplesPerReading = 60 * serverSendInterval; // every x minutes send a sample to the server
int temperatureLoopCount = 0;
int lcdBacklightOnCounter = 1;
long secondsOfHour = 0; // used to reset esp32 every 24 hours
float currentIndoorTemperature = 0;
float currentIndoorHumidity = 0;
float currentOutdoorTemperature = 0;
float currentOutdoorHumidity = 0;
String payload = "";
int httpCode = 0;
bool wifiConnected = false;
bool wifiPaused = false;
int wifiPausedTick = 0;
bool wifiSleeping = false;
bool debug = false; // when true server does not update
bool serverFailed = false;
int wifiConnectionAttempts = 0;
HTTPClient http;
DHT_Unified dhtIndoor(indoorTemperaturePin, DHT11);
DHT_Unified dhtOutdoor(outdoorTemperaturePin, DHT22);
Adafruit_ADS1115 ads;
LiquidCrystal_I2C lcd_i2c(0x27, 16, 2);
const float FACTOR = 20; //20A/1V from the CT
const float multiplier = 0.0000472; // increate so bring down read current
void setup() {
Serial.begin(115200); // this needs to match the value in the serial monitor
//Init EEPROM
EEPROM.begin(EEPROM_SIZE);
pinMode(buttonPin, INPUT);
delay(2000);
dhtIndoor.begin();
// Print temperature sensor details.
sensor_t indoorSensor;
dhtIndoor.temperature().getSensor( & indoorSensor);
// Print humidity sensor details.
dhtIndoor.humidity().getSensor( & indoorSensor);
dhtOutdoor.begin();
// Print temperature sensor details.
sensor_t dhtOutdoor;
dhtIndoor.temperature().getSensor( & dhtOutdoor);
// Print humidity sensor details.
dhtIndoor.humidity().getSensor( & dhtOutdoor);
EEPROM.begin(EEPROM_SIZE);
activeConnection = EEPROM.read(eepromActiveConnection);
Serial.print("eepromActiveConnection :");
Serial.println(activeConnection);
if (isnan(activeConnection)) {
activeConnection = 1;
}
if(activeConnection == 0){
activeConnection = 1;
}
Serial.print("activeConnection: ");
Serial.println(activeConnection);
float pingData = EEPROM.readFloat(eepromPingsAddress);
if (isnan(pingData)) {
pingData = 0;
}
totalServerPings = pingData;
EEPROM.end();
EEPROM.begin(EEPROM_SIZE);
float pingFailData = EEPROM.readFloat(eepromFailedPingsAddress);
if (isnan(pingFailData)) {
pingFailData = 0;
}
totalServerPingFails = pingFailData;
EEPROM.end();
if(!connectToWiFi()){
delay(2000);
WiFi.disconnect();
delay(1000);
if(activeConnection == 1){
activeConnection = 2;
}else {
activeConnection = 1;
}
connectToWiFi();
}
if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
while (1);
}
ads.setGain(GAIN_FOUR);
lcd_i2c.init();
lcd_i2c.backlight();
}
void loop() {
secondsOfHour ++;
// after 24 hours reset this integer
if(secondsOfHour > 86400){
secondsOfHour = 1;
// Serial.println("restarting :");
ESP.restart();
}
if(lcdBacklightOnCounter == 0){
lcd_i2c.noBacklight();
}else {
// if lcb backlight counter is over zero it is active so increment
lcdBacklightOnCounter ++;
// turn off backlight after 1800 - 5 mintes of inactivity
if(lcdBacklightOnCounter > 1800){
lcd_i2c.noBacklight();
lcdBacklightOnCounter = 0;
}
}
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
lcd_i2c.clear();
lcd_i2c.backlight();
if(lcdBacklightOnCounter == 0){
displayMode = 1;
}else {
displayMode++;
if (displayMode > 2) {
displayMode = 1;
}
}
lcdBacklightOnCounter = 1;
}
sensors_event_t indoorSensorEvent;
//////////////////////////////
// TEMPERATURE AND HUMIDITY
// no need to read the temperature every second
if (temperatureLoopCount % 10 == 0) {
dhtIndoor.temperature().getEvent( & indoorSensorEvent);
if (isnan(indoorSensorEvent.temperature)) {
Serial.println(F("Error reading indoor temperature!"));
} else {
currentIndoorTemperature = indoorSensorEvent.temperature;
}
dhtIndoor.humidity().getEvent( & indoorSensorEvent);
if (isnan(indoorSensorEvent.relative_humidity)) {
Serial.println(F("Error reading indoor humidity!"));
} else {
currentIndoorHumidity = indoorSensorEvent.relative_humidity;
}
}
sensors_event_t outdoorSensorEvent;
// no need to read the temperature every second
if (temperatureLoopCount % 10 == 0) {
dhtOutdoor.temperature().getEvent( & outdoorSensorEvent);
if (isnan(outdoorSensorEvent.temperature)) {
Serial.println(F("Error reading outdoor temperature!"));
} else {
currentOutdoorTemperature = outdoorSensorEvent.temperature;
}
dhtOutdoor.humidity().getEvent( & outdoorSensorEvent);
if (isnan(outdoorSensorEvent.relative_humidity)) {
Serial.println(F("Error reading outdoor humidity!"));
} else {
currentOutdoorHumidity = outdoorSensorEvent.relative_humidity;
}
}
String temperatureText = "IT:" + String(currentIndoorTemperature, 0) + "c OT:" + String(currentOutdoorTemperature, 0) + "c";
String humidifyText = "IH:" + String(currentIndoorHumidity, 0) + " OH:" + String(currentOutdoorHumidity, 0) + "";
if (wifiPaused) {
if (wifiPausedTick > 60 && wifiConnectionAttempts == 0) { // wait 1 minute before attempting to reconnect
wifiPaused = false;
wifiPausedTick = 0;
connectToWiFi();
} else {
wifiPausedTick++;
}
}
/////////////////////
// SERVER RELAY
Serial.println("temperatureLoopCount: ");
Serial.println(temperatureLoopCount);
if (!debug && (temperatureLoopCount >= samplesPerReading) || serverFailed) {
temperatureLoopCount = 0;
setWifiSleepMode(false);
delay(2000);
// do a heartbeat check to see if we are online...
http.begin(heartbeatUrl);
httpCode = http.GET();
if (!httpCode > 0) {
// wifi may not be alive yet so wait 3 seconds
delay(3000);
}
String recordedIndoorTemperature = String(currentIndoorTemperature, 1);
String recordedIndoorHumidity = String(currentIndoorHumidity, 1);
String recordedOutdoorTemperature = String(currentOutdoorTemperature, 1);
String recordedOutdoorHumidity = String(currentOutdoorHumidity, 1);
recordedIndoorTemperature.trim();
recordedIndoorHumidity.trim();
recordedOutdoorTemperature.trim();
recordedOutdoorHumidity.trim();
temperatureLoopCount = 0;
Serial.println("repaying temperature: ");
Serial.println(temperatureLoopCount);
http.begin(temperatureUrl + recordedIndoorTemperature + "," + recordedIndoorHumidity + "," + recordedOutdoorTemperature + "," + recordedOutdoorHumidity);
httpCode = http.GET();
if (httpCode > 0) {
payload = http.getString();
Serial.println("HTTP Response: " + payload);
recordPingSucces();
} else {
recordPingFailure();
}
http.end();
setWifiSleepMode(true);
}
temperatureLoopCount++;
////////////////////////////
// LCD DISPLAY
switch (displayMode) {
case 1:
temperatureText.trim();
humidifyText.trim();
if(prevTemperatureText != temperatureText || prevHumidifyText != humidifyText){
lcd_i2c.clear();
}
prevTemperatureText = temperatureText;
prevHumidifyText = humidifyText;
lcd_i2c.setCursor(0, 0);
lcd_i2c.print(temperatureText);
lcd_i2c.setCursor(0, 1);
lcd_i2c.print(humidifyText);
break;
case 2:
String connectivityText1 = "";
if(wifiConnected){
connectivityText1 += "WF ON";
}
if(wifiConnected && !serverFailed){
connectivityText1 += " SERVER ON";
}
String serverPings = String(totalServerPings, 0);
serverPings.trim();
String serverPingFails = String(totalServerPingFails, 0);
serverPingFails.trim();
String connectivityText2 = serverPings + "/" + serverPingFails + " PINGS";
connectivityText1.trim();
connectivityText2.trim();
if(prevConnectivityText1 != connectivityText1 || prevConnectivityText2 != connectivityText2){
lcd_i2c.clear();
}
prevConnectivityText1 = connectivityText1;
prevConnectivityText2 = connectivityText2;
lcd_i2c.setCursor(0, 0);
lcd_i2c.print(connectivityText1);
lcd_i2c.setCursor(0, 1);
lcd_i2c.print(connectivityText2);
break;
}
delay(pulseRate);
}
/**
* connect to wifi
*/
bool connectToWiFi() {
String activeSsid = "";
String activePassword = "";
if(activeConnection == 1){
activeSsid = ssid1;
activePassword= password1;
}else if(activeConnection == 2){
activeSsid = ssid2;
activePassword= password2;
}
Serial.print("Connecting to WiFi: ");
Serial.println(activeSsid);
WiFi.begin(activeSsid, activePassword);
while (WiFi.status() != WL_CONNECTED && wifiConnectionAttempts < 20) {
delay(500);
Serial.print(".");
wifiConnectionAttempts++;
}
wifiConnectionAttempts = 0;
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
wifiConnected = true;
EEPROM.begin(EEPROM_SIZE);
EEPROM.write(eepromActiveConnection, activeConnection);
EEPROM.commit();
EEPROM.end();
Serial.print("set activeConnection to : ");
Serial.println(activeConnection);
return true;
} else {
Serial.println("Connection failed. Trying alternative");
return false;
}
}
/**
* set wifi sleep mode between data relays to conserve energy
* @param sleepMode - if true set wifi card to sleep to conserve energy
*/
void setWifiSleepMode(bool sleepMode) {
wifiSleeping = sleepMode;
if (sleepMode) {
WiFi.disconnect();
WiFi.setSleep(true);
delay(1000);
Serial.print("sleep wifi status: ");
Serial.println(wl_status_to_string(WiFi.status()));
} else {
WiFi.setSleep(false);
WiFi.reconnect();
delay(1000);
Serial.print("awaken wifi status: ");
Serial.println(wl_status_to_string(WiFi.status()));
// Check if the connection is still active. if not trigger wait for it to come back online
if (WiFi.status() != WL_CONNECTED && !wifiPaused) {
Serial.println("Connection lost. Attempting to reconnect in 1 minute ...");
WiFi.disconnect();
wifiPaused = true;
wifiConnected = false;
connectToWiFi();
}
}
}
/**
* record server ping success in long term memory
*/
void recordPingSucces() {
totalServerPings++;
EEPROM.begin(EEPROM_SIZE);
EEPROM.writeFloat(eepromPingsAddress, totalServerPings);
EEPROM.commit();
EEPROM.end();
wifiConnected = true;
serverFailed = false;
}
/**
* record server ping fails in long term memory
*/
void recordPingFailure() {
totalServerPingFails++;
EEPROM.begin(EEPROM_SIZE);
EEPROM.writeFloat(eepromFailedPingsAddress, totalServerPingFails);
EEPROM.commit();
EEPROM.end();
wifiConnected = false;
serverFailed = true;
}
/**
* ESP32 wifi card statuses
* @param status
* @return string
*/
String wl_status_to_string(wl_status_t status) {
String response = "";
switch (status) {
case WL_NO_SHIELD:
response = "WL_NO_SHIELD";
break;
case WL_IDLE_STATUS:
response = "WL_IDLE_STATUS";
break;
case WL_NO_SSID_AVAIL:
response = "WL_NO_SSID_AVAIL";
break;
case WL_SCAN_COMPLETED:
response = "WL_SCAN_COMPLETED";
break;
case WL_CONNECTED:
response = "WL_CONNECTED";
break;
case WL_CONNECT_FAILED:
response = "WL_CONNECT_FAILED";
break;
case WL_CONNECTION_LOST:
response = "WL_CONNECTION_LOST";
break;
case WL_DISCONNECTED:
response = "WL_DISCONNECTED";
break;
}
return response;
}