Last active
November 22, 2022 14:06
-
-
Save cyrus007/a87739ef16ae43beae310746587fb704 to your computer and use it in GitHub Desktop.
BME280 + OTA with esp8266 and Blynk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* from https://community.blynk.cc/t/just-my-battery-operated-esp8266-enviro-sensor-node-with-ota-update/9375 | |
V11 -> Temp | |
V9 -> Hum | |
V2 -> Pressure | |
V4 -> Lux | |
V8 -> Dew Point | |
V5 -> Temp Min | |
V6 -> Temp Max | |
V7 -> Reset Temp | |
V19 -> Vcc | |
V18 -> RSSI | |
V3 -> Barometer | |
V12 -> LED | |
V10 -> Slider | |
*/ | |
//#define BLYNK_PRINT Serial //this is the debugging for Blynk | |
//#define BLYNK_DEBUG // Optional, this enables 'full' debugging detailed prints | |
#define debug 0 // this is the debugging tag - change to 0 to turn off debugging serial prints | |
#include <ESP8266WiFi.h> | |
#include <ESP8266mDNS.h> | |
#include <WiFiUdp.h> | |
#include <ArduinoOTA.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <ESP8266HTTPUpdateServer.h> | |
#include <BlynkSimpleEsp8266.h> | |
#include <SimpleTimer.h> | |
#include <Wire.h> | |
#include <SPI.h> | |
#include <Adafruit_Sensor.h> | |
#include <Adafruit_BME280.h> | |
#include <BH1750FVI.h> | |
#define SEALEVELPRESSURE_HPA (1013.25) | |
Adafruit_BME280 bme; // I2C | |
WiFiClient client; | |
BH1750FVI LightSensor; | |
const char* host = "esp8266"; // will be "esp8266.local/update" in web browser | |
ESP8266WebServer httpServer(80); | |
ESP8266HTTPUpdateServer httpUpdater; | |
SimpleTimer timer; | |
ADC_MODE(ADC_VCC); | |
IPAddress ip(192, 168, 0, 14); //check this! | |
IPAddress gateway(192, 168, 0, 1); //check this! | |
IPAddress subnet(255, 255, 255, 0); // check this! | |
int vcc = ESP.getVcc(); //readvdd33(); | |
float humMin, humMax; | |
float temp, hum, pres, altitude; | |
float newTemp, oldTemp, tempChange; | |
float tempChangeSlider; | |
float tempChangeCoeff = 1; | |
float tempMin, tempMax, PreviousTempMin, PreviousTempMax; | |
double node3DewPoint; | |
int setProgramming, setProgrammingMode, resetMinMax; | |
int resetTemps; | |
long rssi = WiFi.RSSI(); | |
// Time to sleep (in seconds): | |
const int sleepTimeS = 720; //this is 12 minutes (i.e. readings done 5 times per hour, 120 times per day) | |
const char* SSID = "xxx"; | |
const char* pass = "yyy"; | |
const char* serverThingspeak = "api.thingspeak.com"; //this is the Thingspeak address | |
String apiKeyThingspeak "abc"; // Channel 123 | |
char authBlynk[] ="qwerty"; //insert token generated by Blynk | |
BLYNK_WRITE(V5) | |
{ | |
tempMin = param.asFloat(); | |
Blynk.virtualWrite(V5, tempMin); | |
} | |
BLYNK_WRITE(V6) | |
{ | |
tempMax = param.asFloat(); | |
Blynk.virtualWrite(V6, tempMax); | |
} | |
BLYNK_WRITE(V7) // reset min/max temps | |
{ | |
resetMinMax = param.asInt(); | |
if (resetMinMax == 1) { | |
resetTemps = 1; | |
Blynk.virtualWrite(V7, 0); | |
} | |
} | |
BLYNK_WRITE(V99) | |
{ | |
oldTemp = param.asFloat(); | |
Blynk.virtualWrite(V99, oldTemp); | |
} | |
BLYNK_WRITE(V13) // sets temperature warning coefficent for Blynk Notify | |
{ | |
tempChangeSlider = param.asFloat(); | |
if (tempChangeSlider > 0) | |
{ | |
tempChangeCoeff = tempChangeSlider / 5; | |
Blynk.virtualWrite(V15, tempChangeCoeff); | |
} | |
} | |
BLYNK_WRITE(V10) // progamming mode - set this to prevent sleep | |
{ | |
setProgrammingMode = param.asInt(); | |
if (setProgrammingMode == 1) { | |
setProgramming = 1; // this stops esp.sleep so it can accept the OTA reprogramming | |
Serial.println(F("set programing ACTIVATED")); | |
} | |
else if (setProgrammingMode == 0) { | |
setProgramming = 0; // this stops esp.sleep so it can accept the OTA reprogramming | |
Serial.println(F("set programing INACTIVE")); | |
} | |
} | |
void getSensorData() | |
{ | |
uint16_t lux = LightSensor.GetLightIntensity();// Get Lux value | |
temp = bme.readTemperature(); | |
pres = bme.readPressure() / 100.0F; | |
altitude = bme.readAltitude(SEALEVELPRESSURE_HPA); | |
hum = bme.readHumidity(); | |
node3DewPoint = dewPointAccurate(temp, hum); | |
if (debug == 1) | |
{ | |
Serial.print("Temp: "); | |
Serial.print(temp); | |
Serial.println("'C"); | |
Serial.print("Humidity: "); | |
Serial.print(hum); | |
Serial.println("% RH"); | |
Serial.print("Pressure: "); | |
Serial.print(pres); | |
Serial.println(" hPa"); | |
Serial.print("Dew point: "); | |
Serial.print(node3DewPoint); | |
Serial.println("'C"); | |
Serial.print("Light: "); | |
Serial.print(lux); | |
Serial.println(" lux"); | |
Serial.println("-------------------------------------------"); | |
} | |
Blynk.virtualWrite(V11, temp); // this sends the reading to the Blynk virtual pin | |
Blynk.virtualWrite(V9, hum); // this sends the reading to the Blynk virtual pin | |
Blynk.virtualWrite(V2, pres); // this sends the reading to the Blynk virtual pin | |
Blynk.virtualWrite(V8, node3DewPoint); // this sends the reading to the Blynk virtual pin | |
Blynk.virtualWrite(V19, vcc); // this sends the reading to the Blynk virtual pin | |
Blynk.virtualWrite(V18, rssi); // this sends the reading to the Blynk virtual pin | |
Blynk.virtualWrite(V4, lux); // this sends the reading to the Blynk virtual pin | |
newTemp = temp; | |
if (debug == 1) | |
{ | |
Serial.println("newTemp:"); | |
Serial.println(temp); | |
Serial.println("current tempMin:"); | |
Serial.println(tempMin); | |
Serial.println("current tempMax:"); | |
Serial.println(tempMax); | |
} | |
if (resetTemps == 1) | |
{ | |
if (debug == 1) | |
{ | |
Serial.println("resetting temps!"); | |
} | |
tempMin = 50; | |
tempMax = 0; | |
} | |
if (tempMin <= newTemp) | |
{ | |
tempMin = tempMin; | |
if (debug == 1) | |
{ | |
Serial.println("no change to tempMin "); | |
} | |
} | |
else if (tempMin > newTemp) | |
{ | |
tempMin = newTemp; | |
Blynk.virtualWrite(V5, tempMin); | |
if (debug == 1) | |
{ | |
Serial.println("tempMin updated"); | |
} | |
} | |
if (tempMax >= newTemp) | |
{ | |
tempMax = tempMax; | |
if (debug == 1) | |
{ | |
Serial.println("no change to tempMax "); | |
} | |
} | |
else if (tempMax < newTemp) | |
{ | |
tempMax = newTemp; | |
Blynk.virtualWrite(V6, tempMax); | |
if (debug == 1) | |
{ | |
Serial.println("tempMax updated"); | |
} | |
} | |
tempChange = newTemp - oldTemp; | |
if (debug == 1) | |
{ | |
Serial.print("newTemp:"); | |
Serial.println(newTemp); | |
Serial.print("oldTemp:"); | |
Serial.println(oldTemp); | |
Serial.print("tempChange:"); | |
Serial.println(tempChange); | |
Serial.print("tempChangeCoeff:"); | |
Serial.println(tempChangeCoeff); | |
} | |
Blynk.virtualWrite(V14, tempChange); | |
if ((tempChange > tempChangeCoeff) || (tempChange < -tempChangeCoeff)) | |
{ | |
Blynk.notify(String("BME280 Node06 - temp change of ") + (tempChange) + ("detected in 12mins.")); | |
} | |
oldTemp = temp; | |
Blynk.virtualWrite(V99, oldTemp); | |
if ((vcc < 3260) && (vcc > 3245)) | |
{ | |
Blynk.notify(String("NODE06 - Outside BME280 Sensor battery low: ") + vcc + ("mV")); | |
} | |
else if (vcc <= 3235) | |
{ | |
Blynk.notify(String("NODE06 - Outside BME280 Sensor BATTERY CRITICAL:") + vcc + ("mV")); | |
} | |
if (client.connect(serverThingspeak, 80)) | |
{ | |
String postStr = apiKeyThingspeak; | |
postStr += "&field1="; | |
postStr += String(temp); | |
postStr += "&field2="; | |
postStr += String(hum); | |
postStr += "&field3="; | |
postStr += String(pres); | |
postStr += "&field4="; | |
postStr += String(rssi); | |
postStr += "&field5="; | |
postStr += String(vcc); | |
//postStr += "&field6="; | |
//postStr += String(lux); | |
postStr += "&field7="; | |
postStr += String(node3DewPoint); | |
postStr += "\r\n\r\n"; | |
client.print("POST /update HTTP/1.1\n"); | |
client.print("Host: api.thingspeak.com\n"); | |
client.print("Connection: close\n"); | |
client.print("X-THINGSPEAKAPIKEY: " + apiKeyThingspeak + "\n"); | |
client.print("Content-Type: application/x-www-form-urlencoded\n"); | |
client.print("Content-Length: "); | |
client.print(postStr.length()); | |
client.print("\n\n"); | |
client.print(postStr); | |
} | |
if (debug == 1) | |
{ | |
Serial.println(F("just thingspoke")); | |
} | |
delay(10); | |
if (setProgramming == 0) | |
{ | |
Blynk.virtualWrite(12, 0); // programming LED off | |
delay(10); | |
ESP.deepSleep(sleepTimeS * 1000000); | |
delay(10); | |
} | |
else if (setProgramming == 1) | |
{ | |
Blynk.virtualWrite(12, 1023); //programming LED on - device is NOT going to deepSleep | |
} | |
} | |
void setup() | |
{ | |
{ | |
Serial.begin(115200); | |
if (debug == 1) | |
{ Serial.print(F("File name: ")); | |
Serial.println(F("")); | |
Serial.println(F("NODE06 - TPL Bug prototype BATTERY POWER - with Thingspeak & Blynk & Deep Sleep")); | |
Serial.print(F("File name: ")); | |
Serial.println(__FILE__); | |
Serial.println(F("")); | |
Serial.print(F("ESP voltage: ")); | |
Serial.print(vcc); | |
Serial.println(F("mV")); | |
Serial.println(F("")); | |
Serial.println(F("Where's Blynk??")); | |
} | |
WiFi.mode(WIFI_STA); | |
WiFi.config(ip, gateway, subnet); // this sets the ESP IP configuration - AVOIDS using router DHCP to save battery | |
WiFi.setOutputPower(0); // this is from conkerkh sets wifi to lowest power | |
Blynk.begin(authBlynk, SSID, pass, IPAddress(192, 168, 0, 7)); //LOCAL server details | |
// Blynk.begin(authBlynk, SSID, pass); use for CLOUD SERVER | |
ArduinoOTA.setHostname("BME280_Node06"); | |
ArduinoOTA.onStart([]() | |
{ | |
Serial.println("Start"); | |
}); | |
ArduinoOTA.onEnd([]() | |
{ | |
Serial.println("\nEnd"); | |
}); | |
ArduinoOTA.onError([](ota_error_t error) | |
{ | |
Serial.printf("Error[%u]: ", error); | |
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); | |
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); | |
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); | |
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); | |
else if (error == OTA_END_ERROR) Serial.println("End Failed"); | |
}); | |
ArduinoOTA.begin(); | |
Serial.println("Ready - OTA Success!!!"); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
MDNS.begin(host); | |
httpUpdater.setup(&httpServer); | |
httpServer.begin(); | |
MDNS.addService("http", "tcp", 80); | |
String ipaddress = WiFi.localIP().toString(); | |
String chipID = String(ESP.getChipId(), HEX); | |
char charChipID[10]; | |
chipID.toCharArray(charChipID, sizeof(charChipID)); | |
char charipaddress[16]; | |
ipaddress.toCharArray(charipaddress, sizeof(charipaddress)); | |
Serial.printf("Now open http://%s.local/update in your browser or \n", host); | |
Serial.printf("http://%s/update or http://%s.lan/update if you prefer.\n", charipaddress, charChipID); | |
while (!Blynk.connect()) | |
{ | |
delay(500); | |
Serial.print(F(".")); | |
} | |
long rssi = WiFi.RSSI(); | |
if (debug == 1) | |
{ | |
Serial.println(F("")); | |
Serial.println(F("Found some WiFi!")); | |
Serial.print(F("WiFi signal strength (RSSI): ")); | |
Serial.print(rssi); | |
Serial.println(F(" dBm")); | |
Serial.println(""); | |
Serial.println(F("Blynk started! ")); | |
Serial.println(F("------------")); | |
} | |
if (debug == 0) | |
{ | |
Serial.println(F("***************************serial print debug is OFF***************************")); | |
} | |
Blynk.syncAll(); | |
LightSensor.begin(); | |
Wire.begin(); | |
LightSensor.SetAddress(Device_Address_L);//'L' = Address 0x5C ??? | |
LightSensor.SetMode(Continuous_H_resolution_Mode); | |
timer.setInterval(60L * 1000L, getSensorData); | |
while (!Serial) | |
{ | |
} // Wait | |
bme.begin(); | |
// while (!bme.begin()) | |
// { | |
// Serial.println("Could not find BME280 sensor!"); | |
// delay(1000); | |
// } | |
} | |
} | |
void loop() | |
{ | |
Blynk.run(); // Initiates Blynk | |
timer.run(); // Initiates SimpleTimer | |
ArduinoOTA.handle(); | |
httpServer.handleClient(); | |
} | |
/*-----( Declare User-written Functions )-----*/ | |
// dewPoint function NOAA | |
// reference (1) : http://wahiduddin.net/calc/density_algorithms.htm | |
// reference (2) : http://www.colorado.edu/geography/weather_station/Geog_site/about.htm | |
// | |
double dewPointAccurate (double celsius, double humidity) | |
{ | |
// (1) Saturation Vapor Pressure = ESGG(T) | |
double RATIO = 373.15 / (273.15 + celsius); | |
double RHS = -7.90298 * (RATIO - 1); | |
RHS += 5.02808 * log10(RATIO); | |
RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO ))) - 1) ; | |
RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ; | |
RHS += log10(1013.124); // NB = 1013 = absolute air pressure from BME280 sensor!!!!??????????????? | |
// factor -3 is to adjust units - Vapor Pressure SVP * humidity | |
double VP = pow(10, RHS - 3) * humidity; | |
// (2) DEWPOINT = F(Vapor Pressure) | |
double T = log(VP / 0.61078); // temp var | |
return (241.88 * T) / (17.558 - T); | |
} | |
/* ==== END Functions ==== */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment