Skip to content

Instantly share code, notes, and snippets.

@cyrus007
Last active November 22, 2022 14:06
Show Gist options
  • Save cyrus007/a87739ef16ae43beae310746587fb704 to your computer and use it in GitHub Desktop.
Save cyrus007/a87739ef16ae43beae310746587fb704 to your computer and use it in GitHub Desktop.
BME280 + OTA with esp8266 and Blynk
/* 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