thank you! It works now!
I have also added to the code Uptime to check random reset
I have to figure out how to manage decimal, I donât like too much! One is enough!
thank you! It works now!
I have also added to the code Uptime to check random reset
I have to figure out how to manage decimal, I donât like too much! One is enough!
my updated code to use use the Adafruit BME280 library.
so that if the temp goes up/down by more than a set amount over the device period (12 mins in my case) then Blynk Notify tells you.
for me - this helps me to know when to open the doors & windows when the southerly change is coming through, or to close up the house when the sun is starting to make its radiation knownâŚ
hopefully it is of use to you too
i think i will use it for Lux, humidity & air pressure changes too⌠i will see how it goes
//#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 ==== */
in the last script
String apiKeyThingspeak âabcâ; // Channel 123 change in
String apiKeyThingspeak = âabcâ; // Channel 123
or it wonât compile
BTW I have see a strange behavior with the code (the first example). The read function start after 60 seconds of power up! This literally eats the battery.
If you test code without Deep Sleep youâll see some disconnections from Blynk that in console are reported like âtimeoutâ
yes, you should change to lowest possible number, thanks!
sorry, i wasnât paying much attention to the consoleâŚ
OK for anyone playing at home - they WERE fake batteriesâŚ
i have some Green Panasonic NCR18650PF batteries in it now and have hit 24,510 cycles alive with total runtime of 32,425,905mS which is nearly 9 hours âawakeâ over probably six months.
also - i am using the finitespace library for BME280 nowadays: