i get disconnections very often, thinking this was somewhat normal.
but i tried to set up a graph and it never keeps values, so now i think being disconnected is not that normal?
can anyone help me stabilize my connection?
the App updates my values pretty well, but the buttons are very laggy and dont always get the message to teh hardware when they change state?
this is my code:
//BASEMENT PLENUM CONTROLLER
//primaily, this sketch is to control two ventilation plenum intake actuators,
//so that only the driest air inlet (determined via dew point) is open so the fan can intake the driest air to the basement.
//it uses the median of the dew point to decide which vent to open.
//it uses three DHT22 sensors to get temp. and humidity to calculate dew point environmental values and the Rob Tillaart 1.13 library for this.
//it also has a sensor inside the plenum for monitoring purposes
//secondarily, it sends data via Blynk app to android phones
//thirdly, it logs to thingspeak channel for datalogging
//Fourthly - it emails and tweets status via Blynk
#define BLYNK_PRINT Serial //this is the debugging for Blynk
//#define BLYNK_DEBUG // Optional, this enables 'full' debugging with detailed prints
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <dht.h> //this is the Rob Tillaart "stable" version
#include "RunningMedian.h"
dht DHT;
WiFiClient client;
RunningMedian samplesRoof = RunningMedian(15);
RunningMedian samplesHouse = RunningMedian(15);
RunningMedian samplesPlenum = RunningMedian(15);
RunningMedian samplesBase = RunningMedian(15);
#define ROOF_DHT22_PIN 12 //DHT22 sensor in roof connected to GPIO12
#define HOUSE_DHT22_PIN 13 //DHT22 sensor in house connected to GPIO13
#define PLENUM_DHT22_PIN 14 //DHT22 sensor inside plenum connected to GPIO14
#define BASE_DHT22_PIN 16 //DHT22 sensor in basement connected to GPIO16
const char* ssid = "xxx";
const char* password = "xxx";
const char* serverThingspeak = "api.thingspeak.com"; //this is the Thingspeak address
String apiKeyThingspeak1 = "xxx"; //Basement plenum control channel - roof & house
String apiKeyThingspeak2 = "xxx"; //Basement plenum control channel - plenum & basement
char authBlynk[] = "xxx"; //insert token generated by Blynk
SimpleTimer timer;
int roofVent = 2; // relay for roof vent connected to GPIO2 - ***WARNING GPIO2 is a VERY sensitive pin for boot****
int houseVent = 5; // relay for house vent connected to GPIO5
int ventFan = 4; // relay for ventilation fan connected to GPIO4
int setMaxTemp = 26;
int setAuto;
int setHouseOn;
int setRoofOn;
int setMinTemp = 16;
double roofDewPoint, houseDewPoint, plenumDewPoint, baseDewPoint;
float roofHum, roofTemp, medianRoofDewPoint, houseHum, houseTemp, medianHouseDewPoint;
float plenumHum, plenumTemp, medianPlenumDewPoint, baseHum, baseTemp, medianBaseDewPoint;
BLYNK_WRITE(V22) // AUTO vent mode
{
setAuto = param.asInt();
if (setAuto == 1) {
Blynk.virtualWrite(V31, 0); // house
Blynk.virtualWrite(V23, 0); // roof
Blynk.virtualWrite(V21, 0); // cancel
autoVentLogic();
}
}
BLYNK_WRITE(V31) // HOUSE vent open mode
{
setHouseOn = param.asInt();
if (setHouseOn == 1) {
Blynk.virtualWrite(V23, 0); // roof
Blynk.virtualWrite(V22, 0); // auto
Blynk.virtualWrite(V21, 0); // cancel
houseVentOn();
}
}
BLYNK_WRITE(V23) // ROOF vent open mode
{
setRoofOn = param.asInt();
if (setRoofOn == 1) {
Blynk.virtualWrite(V31, 0); // house
Blynk.virtualWrite(V22, 0); // auto
Blynk.virtualWrite(V21, 0); // cancel
roofVentOn();
}
}
void runningMedian() { //does all the DHT22 sensor readings and calculates the running median
int chk;
Serial.println(F("Starting the running median section..."));
Serial.println("");
delay(1800); //helps the DHT22 to work properly - it needs this long to get organised
//BLYNK_LOG("");
//basement DHT22 section
chk = DHT.read22(BASE_DHT22_PIN); // READ DATA from BASEMENT sensor
baseHum = DHT.humidity;
baseTemp = DHT.temperature;
baseDewPoint = dewPoint(DHT.temperature, DHT.humidity);
medianBaseDewPoint = samplesBase.getMedian();
samplesBase.add(baseDewPoint);
BLYNK_LOG("read BASE DHT22 done");
Serial.println(F("Basement readings"));
Serial.print(baseHum);
Serial.println(F("%"));
Serial.print(baseTemp);
Serial.println(F("'C"));
Serial.print(baseDewPoint);
Serial.println("'C");
Serial.print(F("Basement Dew Point (median):"));
Serial.print(medianBaseDewPoint);
Serial.println("'C");
Serial.println("");
//roof DHT22 section
chk = DHT.read22(ROOF_DHT22_PIN); // READ DATA from ROOF sensor
roofHum = DHT.humidity;
roofTemp = DHT.temperature;
roofDewPoint = dewPoint(DHT.temperature, DHT.humidity);
medianRoofDewPoint = samplesRoof.getMedian();
samplesRoof.add(roofDewPoint); // this is the Running Median command
BLYNK_LOG("read ROOF DHT22 done");
Serial.println(F("Roof readings"));
Serial.print(roofHum);
Serial.println("%");
Serial.print(roofTemp);
Serial.println("'C");
Serial.print(roofDewPoint);
Serial.println("'C");
Serial.print(F("Roof Dew Point (median):"));
Serial.print(medianRoofDewPoint);
Serial.println("'C");
Serial.println("");
delay(1800); //helps the DHT22 to work properly - it needs this long to get organised
//house DHT22 section
chk = DHT.read22(HOUSE_DHT22_PIN); // READ DATA from HOUSE sensor
houseHum = DHT.humidity;
houseTemp = DHT.temperature;
houseDewPoint = dewPoint(DHT.temperature, DHT.humidity);
medianHouseDewPoint = samplesHouse.getMedian();
samplesHouse.add(houseDewPoint);
BLYNK_LOG("read HOUSE DHT22 done");
Serial.println(F("House readings"));
Serial.print(houseHum);
Serial.println("%");
Serial.print(houseTemp);
Serial.println("'C");
Serial.print(houseDewPoint);
Serial.println("'C");
Serial.print(F("House Dew Point (median):"));
Serial.print(medianHouseDewPoint);
Serial.println("'C");
Serial.println("");
//plenum DHT22 section
chk = DHT.read22(PLENUM_DHT22_PIN); // READ DATA from PLENUM sensor
plenumHum = DHT.humidity;
plenumTemp = DHT.temperature;
plenumDewPoint = dewPoint(DHT.temperature, DHT.humidity);
medianPlenumDewPoint = samplesPlenum.getMedian();
samplesPlenum.add(plenumDewPoint);
BLYNK_LOG("read PLENUM DHT22 done");
Serial.println(F("Plenum readings"));
Serial.print(plenumHum);
Serial.println("%");
Serial.print(plenumTemp);
Serial.println("'C");
Serial.print(plenumDewPoint);
Serial.println("'C");
Serial.print(F("Plenum Dew Point (median):"));
Serial.print(medianPlenumDewPoint);
Serial.println("'C");
Serial.println("");
}
void dataLogging() { //sends the variables to Blynk and Thingspeak
Serial.println(F("Starting data logging function (Blynk then Thingspeak)"));
long rssi = WiFi.RSSI();
Blynk.virtualWrite(V0, rssi); // this sends the WiFi Signal Strenght to Blynk
long uptime = millis() / 60000;
Blynk.virtualWrite(V20, uptime); // this sends the program uptime to Blynk
Serial.println(F("Sending to Blynk - ROOF readings:"));
Blynk.virtualWrite(V10, roofHum); // this sends the reading to the Blynk virtual pin
Serial.print(roofHum);
Serial.println("%");
Blynk.virtualWrite(V11, roofTemp); // this sends the reading to the Blynk virtual pin
Serial.print(roofTemp);
Serial.println("'C");
Blynk.virtualWrite(V16, medianRoofDewPoint); // this sends the calculation to the Blynk virtual pin
Serial.print(F("Roof Dew Point (median):"));
Serial.print(medianRoofDewPoint);
Serial.println("'C");
Serial.println(F("Sending to Blynk - HOUSE readings:"));
Blynk.virtualWrite(V12, houseHum ); // this sends the reading to the Blynk virtual pin
Serial.print(houseHum);
Serial.println("%");
Blynk.virtualWrite(V13, houseTemp); // this sends the reading to the Blynk virtual pin
Serial.print(houseTemp);
Serial.println("'C");
Blynk.virtualWrite(V17, medianHouseDewPoint); // this sends the calculation to the Blynk virtual pin
Serial.print(F("House Dew Point (median):"));
Serial.print(medianHouseDewPoint);
Serial.println("'C");
Serial.println(F("Sending to Blynk - PLENUM readings:"));
Blynk.virtualWrite(V1, plenumHum); // this sends the reading to the Blynk virtual pin
Serial.print(plenumHum);
Serial.println("%");
Blynk.virtualWrite(V2, plenumTemp); // this sends the reading to the Blynk virtual pin
Serial.print(plenumTemp);
Serial.println("'C");
Blynk.virtualWrite(V18, medianPlenumDewPoint); // this sends the calculation to the Blynk virtual pin
Serial.print(F("Plenum Dew Point (median):"));
Serial.print(medianPlenumDewPoint);
Serial.println("'C");
Serial.println(F("Sending to Blynk - BASEMENT readings:"));
Blynk.virtualWrite(V4, baseHum ); // this sends the reading to the Blynk virtual pin
Serial.print(baseHum);
Serial.println("%");
Blynk.virtualWrite(V5, baseTemp); // this sends the reading to the Blynk virtual pin
Serial.print(baseTemp);
Serial.println("'C");
Blynk.virtualWrite(V19, medianBaseDewPoint); // this sends the calculation to the Blynk virtual pin
Serial.print(F("Basement Dew Point (median):"));
Serial.print(medianBaseDewPoint);
Serial.println("'C");
Serial.println(F("Just finished the data logging Blynk section"));
Serial.println(F("Preparing Thingspeak readings"));
if (client.connect(serverThingspeak, 80))
{
String postStr = apiKeyThingspeak1;
postStr += "&field1=";
postStr += String(roofTemp);
postStr += "&field2=";
postStr += String(roofHum);
postStr += "&field3=";
postStr += String(roofDewPoint);
postStr += "&field4=";
postStr += String(houseTemp);
postStr += "&field5=";
postStr += String(houseHum);
postStr += "&field6=";
postStr += String(houseDewPoint);
postStr += "&field7=";
postStr += String(medianRoofDewPoint);
postStr += "&field8=";
postStr += String(medianHouseDewPoint);
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: " + apiKeyThingspeak1 + "\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);
Serial.println(F("Just uploaded to Thingspeak Channel ID: 76725"));
}
delay(10);
if (client.connect(serverThingspeak, 80))
{
String postStr = apiKeyThingspeak2;
postStr += "&field1=";
postStr += String(plenumTemp);
postStr += "&field2=";
postStr += String(plenumHum);
postStr += "&field3=";
postStr += String(plenumDewPoint);
postStr += "&field4=";
postStr += String(baseTemp);
postStr += "&field5=";
postStr += String(baseHum);
postStr += "&field6=";
postStr += String(baseDewPoint);
postStr += "&field7=";
postStr += String(medianPlenumDewPoint);
postStr += "&field8=";
postStr += String(medianBaseDewPoint);
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: " + apiKeyThingspeak2 + "\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);
Serial.println(F("Just uploaded to Thingspeak Channel ID: 80158"));
BLYNK_LOG("Finished dataLogging function");
}
}
void tweetUptime() { //sends tweet of status
long uptime = millis() / 60000L * 3L;
BLYNK_LOG("Tweeting every 30 minutes ;)");
Blynk.tweet(String("Basement: Controller running for ") + uptime + " minutes.");
}
void autoVentLogic()
{
Serial.println(F("Starting the ventilation logic section. "));
Serial.print(F("_________________________SetMaxTemp (max. inlet temp) = "));
Serial.print(setMaxTemp);
Serial.println(F("'C"));
//Auto mode - ERROR situation - sensor malfunction
if ((houseTemp < 0) || (roofTemp < 0) || (baseTemp < 0))
{
digitalWrite(roofVent, LOW); // roof vent closed
digitalWrite(houseVent, LOW); // house vent closed
digitalWrite(ventFan, HIGH); // ventilation fan is OFF
Serial.println(F("system = ERROR - some/all temps are below 0 'C - CHECK SENSORS"));
Serial.println(F("------------"));
Blynk.virtualWrite(6, 1023); //off LED on Blynk app
Blynk.virtualWrite(7, 1023); //hse LED on Blynk app
Blynk.virtualWrite(8, 1023); //rof LED on Blynk app
Blynk.virtualWrite(9, 1023); //bse LED on Blynk app
Blynk.tweet((String("Basement: AUTO.ERROR! - DewPoint's = R: ") + medianRoofDewPoint + (" H: ") + medianHouseDewPoint + (" P: ") + medianPlenumDewPoint + (" B: ") + medianBaseDewPoint) + ("'C"));
}
//Auto mode - roof vent air has lowest dew point scenario:
else if ((roofTemp < setMaxTemp) && (roofTemp > setMinTemp) && (medianHouseDewPoint > medianRoofDewPoint) && (medianBaseDewPoint > medianRoofDewPoint))
{
digitalWrite(roofVent, HIGH); // roof vent OPEN
digitalWrite(houseVent, LOW); // house vent closed
digitalWrite(ventFan, LOW); // house vent ON
Serial.println(F("system = ROOF air inlet selected based on lowest Dew Point"));
Serial.println(F("------------"));
Blynk.virtualWrite(6, 0); //off LED on Blynk app
Blynk.virtualWrite(7, 0); //hse LED on Blynk app
Blynk.virtualWrite(8, 1023); //rof LED on Blynk app
Blynk.virtualWrite(9, 0); //bse LED on Blynk app
Blynk.tweet((String("Basement: AUTO.ROOF - DewPoint's = R: ") + medianRoofDewPoint + (" H: ") + medianHouseDewPoint + (" P: ") + medianPlenumDewPoint + (" B: ") + medianBaseDewPoint) + ("'C"));
}
//Auto mode - house vent air has lowest dew point scenario:
else if ((houseTemp < setMaxTemp) && (houseTemp > setMinTemp) && (medianRoofDewPoint >= medianHouseDewPoint) && (medianBaseDewPoint >= medianHouseDewPoint))
{
digitalWrite(roofVent, LOW); // roof vent closed
digitalWrite(houseVent, HIGH); // house vent OPEN
digitalWrite(ventFan, LOW); // house vent ON
Serial.println(F("system = HOUSE air inlet selected based on lowest Dew Point"));
Serial.println(F("------------"));
Blynk.virtualWrite(6, 0); //off LED on Blynk app
Blynk.virtualWrite(7, 1023); //hse LED on Blynk app
Blynk.virtualWrite(8, 0); //rof LED on Blynk app
Blynk.virtualWrite(9, 0); //bse LED on Blynk app
Blynk.tweet((String("Basement: AUTO.HOUSE - DewPoint's = R: ") + medianRoofDewPoint + (" H: ") + medianHouseDewPoint + (" P: ") + medianPlenumDewPoint + (" B: ") + medianBaseDewPoint) + ("'C"));
}
//Auto mode - basement room air has lowest dew point scenario:
else if ((medianRoofDewPoint > medianBaseDewPoint) && (medianHouseDewPoint > medianBaseDewPoint))
{
digitalWrite(roofVent, LOW); // roof vent closed
digitalWrite(houseVent, LOW); // house vent closed
digitalWrite(ventFan, HIGH); // ventilation fan is off
Serial.println(F("system = BASEMENT air has the lowest Dew Point - system OFF, both vents closed."));
Serial.println(F("------------"));
Blynk.virtualWrite(6, 0); //off LED on Blynk app
Blynk.virtualWrite(7, 0); //hse LED on Blynk app
Blynk.virtualWrite(8, 0); //rof LED on Blynk app
Blynk.virtualWrite(9, 1023); //bse LED on Blynk app
Blynk.tweet((String("Basement: AUTO. System off - DewPoint's = R: ") + medianRoofDewPoint + ("H: ") + medianHouseDewPoint + ("P: ") + medianPlenumDewPoint + ("B: ") + medianBaseDewPoint) + ("'C"));
}
}
//Manual mode - roof vent open, fan on
void roofVentOn()
{
if (setRoofOn == 1)
{
digitalWrite(roofVent, HIGH); // roof vent OPEN
digitalWrite(houseVent, LOW); // house vent closed
digitalWrite(ventFan, LOW); // house vent ON
Serial.println(F("system = Roof Manual - ROOF inlet is open, FAN is on"));
Serial.println(F("------------"));
Blynk.virtualWrite(6, 1023); //off LED on Blynk app
Blynk.virtualWrite(7, 0); //hse LED on Blynk app
Blynk.virtualWrite(8, 1023); //rof LED on Blynk app
Blynk.virtualWrite(9, 0); //bse LED on Blynk app
Blynk.tweet((String("Basement: MAN.ROOF - DewPoint's = R: ") + medianRoofDewPoint + (" H: ") + medianHouseDewPoint + (" P: ") + medianPlenumDewPoint + (" B: ") + medianBaseDewPoint) + ("'C"));
}
}
//Manual mode - house vent open, fan on
void houseVentOn()
{
if (setHouseOn == 1)
{
digitalWrite(roofVent, LOW); // roof vent CLOSED
digitalWrite(houseVent, HIGH); // house vent OPEN
digitalWrite(ventFan, LOW); // house vent ON
Serial.println(F("system = House Manual - HOUSE inlet is open, FAN is on"));
Serial.println(F("------------"));
Blynk.virtualWrite(6, 1023); //off LED on Blynk app
Blynk.virtualWrite(7, 1023); //hse LED on Blynk app
Blynk.virtualWrite(8, 0); //rof LED on Blynk app
Blynk.virtualWrite(9, 0); //bse LED on Blynk app
Blynk.tweet((String("Basement: MAN.HOUSE - DewPoint's = R: ") + medianRoofDewPoint + (" H: ") + medianHouseDewPoint + (" P: ") + medianPlenumDewPoint + (" B: ") + medianBaseDewPoint) + ("'C"));
}
}
void setup()
{
Serial.begin(115200);
Serial.println(F(""));
Serial.println(F("BASEMENT VENTILATION PLENUM CONTROLLER - with Thingspeak & Blynk & Running Median & Twitter"));
Serial.print(F("File name: "));
Serial.println(__FILE__);
Serial.print(F("DHT LIBRARY VERSION: "));
Serial.println(DHT_LIB_VERSION);
Serial.print(F("Running Median Version: "));
Serial.println(RUNNING_MEDIAN_VERSION);
Serial.println();
Blynk.begin(authBlynk, ssid, password);
while (!Blynk.connect()) {
//Wait until connected
delay(50);
Serial.print(F(". "));
}
Serial.println(F(""));
Serial.println(F("Found some WiFi!"));
long rssi = WiFi.RSSI();
Serial.print(F("WiFi signal strength (RSSI): "));
Serial.print(rssi);
Serial.println(F(" dBm"));
Serial.println("");
Serial.println(F("------------"));
bool isFirstConnect = true; // Keep this flag not to re-sync on every reconnection
BLYNK_CONNECTED(); // This function will run every time Blynk initial connection is established
{
if (isFirstConnect) {
Blynk.syncAll(); // where is the sync.All function supposed to go?
isFirstConnect = false;
}
}
Serial.println(F("Blynk syncAll done! We operate under <SimpleTimer.h> now:"));
timer.setInterval(29000, runningMedian); // Setup the running median function to be called every 29 seconds
Serial.println(F("SimpleTimer begins runningMedian() at 29000 millisecond intervals..."));
timer.setInterval(121000, dataLogging); // Setup the data logging function to be called every 121 seconds (2 mins)
Serial.println(F("SimpleTimer begins dataLogging() at 121000 millisecond intervals..."));
timer.setInterval(450000, autoVentLogic); // Setup ventilation logic function to be called every 450 seconds (7.5 minutes)
Serial.println(F("SimpleTimer begins autoVentLogic() at 450000 millisecond intervals..."));
timer.setInterval(600000, tweetUptime); // Setup Twitter uptime function to be called every 600 seconds (10 minutes)
Serial.println(F("SimpleTimer begins tweetUptime() at 600000 millisecond intervals..."));
pinMode(roofVent, OUTPUT);
pinMode(houseVent, OUTPUT);
pinMode(ventFan, OUTPUT);
digitalWrite(roofVent, LOW);
digitalWrite(houseVent, LOW);
digitalWrite(ventFan, HIGH);
}
void loop()
{
Blynk.run(); // Initiates Blynk
timer.run(); // Initiates SimpleTimer
}
/*-----( 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 dewPoint(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.246);
// 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);
}
/* ( THE END ) */
are there things in the code that are making the Blynk app perform poorly?
is it the Thingspeak code in the dataLogging() section?
if so - how could i amend it?