Hello
I want to build a simple home weather station by these parts:
Wemos D1 mini
SSD1306 OLED
BME280 (Temperature,Pressure,Humidity Sensor)
MQ135 (Air Quality Sensor)
DSM501a (Dust Sensor)
Three 5mm LEDs (for display Temperature, Pressure and Humidity Trend).
The results of the sensors are displayed in two ways:
Temperature, pressure and humidity through oled display.
Air quality and dust are sent to the mobile through the web server.
My problem is that the results are displayed correctly in oled ; also 5mm led working properly but only the time and date are displayed in the web server and the air quality and dust data is zero (see picture).
My main code is here:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include<string.h>
#include <MQUnifiedsensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
///////////////////////////////////////////////////////////////////////////////////////////////
#define SEALEVELPRESSURE_HPA (1013.25) //BME 280 SETTINGS
#define PM1PIN 3 //DSM501A input PIN ***
#define PM25PIN 1 //DSM501A input PIN ***
#define placa "Wemos D1 Mini"
#define Voltage_Resolution 5
#define pin A0 // MQ135 Analog input PIN ***
#define type "MQ-135" //MQ135
#define ADC_Bit_Resolution 10 // For arduino UNO/MEGA/NANO
#define RatioMQ135CleanAir 3.6//RS / R0 = 3.6 ppm
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
///////////////////////////////////////////////////////////////////////////////////////////////
WiFiUDP ntpUDP; const long utcOffsetInSeconds = 16200; NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
unsigned long epochTime = timeClient.getEpochTime(); struct tm *ptm = gmtime ((time_t *)&epochTime);
///////////////////////////////////////////////////////////////////////////////////////////////
const char*Wifi_ssid = " "; // SSID of your Router OR mobile hotspot
const char*Wifi_password = " "; // PASSWORD of your Router or Mobile hotspot see below example
const char *Apssid = " "; //give Accesspoint SSID, your esp's hotspot name
const char *Appassword = " "; //password of your esp's hotspot
ESP8266WebServer server(80);
///////////////////////////////////////////////////////////////////////////////////////////////
String SendHTML(float TemperatureWeb, float PressureWeb, float HumidityWeb, float PM1Web, float PM25Web, float COWeb, float AlcoholWeb, float CO2Web, float ToluenWeb, float NH4Web, float AcetonWeb, String TimeWeb, String DateWeb);
void handle_OnConnect();
void handle_NotFound();
float t, t1, t2;
float Temperature; float Pressure; float Humidity; float PM1; float PM25; float CO; float Alcohol; float CO2; float Toluen; float NH4; float Aceton;
String formattedTime; String Date;
int Day; int Month; int Year;
bool state = true; bool count = true;
///////////////////////////////////////////////////////////////////////////////////////////////
Adafruit_BME280 bme;
byte buff[2];
unsigned long durationPM1;
unsigned long durationPM25;
unsigned long starttime;
unsigned long endtime;
unsigned long sampletime_ms = 30000;
unsigned long lowpulseoccupancyPM1 = 0;
unsigned long lowpulseoccupancyPM25 = 0;
const int REDLED = 13;
const int GREENLED = 16;
const int REDLED_P = 0;
const int GREENLED_P = 2;
const int REDLED_H = 14;
const int GREENLED_H = 12;
int i=0;
int t_interval = 2000;
float p_ave = 0;
float t_ave = 0;
float h_ave = 0;
int count5 = 60; //60 * 5 sec in 5 min assuming t_interval = 5000msec
//ring buffer to allow trend detection
const int length=30; //size of buffer: 36 places allows a time interval of 36 * 5 min = 3 hours
float data[length]; //buffer array
int put_index=0; //index to array
float t_now, t_was;
float p_now, p_was;//current pressure and old pressure
float h_now, h_was;
float temperature, humidity, pressure, change_P, change_T, change_H;
///////////////////////////////////////////////////////////////////////////////////////////////
MQUnifiedsensor MQ135(placa, Voltage_Resolution, ADC_Bit_Resolution, pin, type);
///////////////////////////////////////////////////////////////////////////////////////////////
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
///////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
///////////////////////////////////////////////////////////////////////////////////////////////
//initialise array values to zero
for(put_index=0; put_index<length; put_index++){
data[put_index]=0;
}
put_index=0; //reset ready for data entry
int change = 0;
delay(100);
WiFi.mode(WIFI_AP_STA); //changing ESP9266 wifi mode to AP + STATION
WiFi.softAP(Apssid, Appassword, 1, 1); //Starting AccessPoint on given credential
IPAddress myIP = WiFi.softAPIP(); //IP Address of our Esp8266 accesspoint(where we can host webpages, and see data)
delay(10);
WiFi.begin(Wifi_ssid, Wifi_password); // to tell ESP8266 Where to connect and trying to connect
while (WiFi.status() != WL_CONNECTED) { // While loop for checking Internet Connected or not
delay(10); }
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
timeClient.begin();
///////////////////////////////////////////////////////////////////////////////////////////////
//Trend Section
Serial.begin(9600);
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while(1);
}
bme.setSampling(Adafruit_BME280::MODE_NORMAL,
Adafruit_BME280::SAMPLING_X16, // temperature
Adafruit_BME280::SAMPLING_X16, // pressure
Adafruit_BME280::SAMPLING_X16, // humidity
Adafruit_BME280::FILTER_X16,
//Adafruit_BME280::STANDBY_MS_0_5 );
Adafruit_BME280::STANDBY_MS_250 ); //standby to 250msec
// 1 + (2 * T_ovs) + (2 * P_ovs + 0.5) + (2 * H_ovs + 0.5)
// T_ovs = 16 ; // P_ovs = 16 ; // H_ovs = 16 ; // = 50ms
// with standby time that should really be 300ms - take no more than 1 reading per second
pinMode(REDLED,OUTPUT);
pinMode(GREENLED,OUTPUT);
digitalWrite(REDLED,HIGH);
digitalWrite(GREENLED,HIGH);
pinMode(REDLED_P,OUTPUT);
pinMode(GREENLED_P,OUTPUT);
digitalWrite(REDLED_P,HIGH);
digitalWrite(GREENLED_P,HIGH);
pinMode(REDLED_H,OUTPUT);
pinMode(GREENLED_H,OUTPUT);
digitalWrite(REDLED_H,HIGH);
digitalWrite(GREENLED_H,HIGH);
/////////////////////////////////////////////////////////////////////////////////////////////////Dust Sensor(DSM501a)
//Serial.println("Starting please wait 30s");
pinMode(PM1PIN,INPUT);
pinMode(PM25PIN,INPUT);
starttime = millis();
///////////////////////////////////////////////////////////////////////////////////////////////
//MQ135(Air Quality)
MQ135.setRegressionMethod(1); //_PPM = a*ratio^b
MQ135.init();
MQ135.setRL(22);
Serial.print("Calibrating please wait.");
float calcR0 = 0;
for(int i = 1; i<=10; i ++)
{
MQ135.update(); // Update data, the arduino will read the voltage from the analog pin
calcR0 += MQ135.calibrate(RatioMQ135CleanAir);
Serial.print(".");
}
MQ135.setR0(calcR0/22);
Serial.println(" done!.");
if(isinf(calcR0)) {Serial.println("Warning: Conection issue, R0 is infinite (Open circuit detected) please check your wiring and supply"); while(1);}
if(calcR0 == 0){Serial.println("Warning: Conection issue found, R0 is zero (Analog pin shorts to ground) please check your wiring and supply"); while(1);}
///////////////////////////////////////////////////////////////////////////////////////////////
//SSD1306_OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display();
delay(10);
display.clearDisplay();
display.display();
display.setTextSize(2);
display.setTextColor(WHITE);
}
///////////////////////////////////////////////////////////////////////////////////////////////
//Dust Sensor(DSM501a)
float calculateConcentration(long lowpulseInMicroSeconds, long durationinSeconds){
float ratio = (lowpulseInMicroSeconds/1000000.0)/30.0*100.0; //Calculate the ratio
float concentration = 0.001915 * pow(ratio,2) + 0.09522 * ratio - 0.04884;//Calculate the mg/m3
//Serial.print("lowpulseoccupancy:");
//Serial.print(lowpulseInMicroSeconds);
//Serial.print(" ratio:");
//Serial.print(ratio);
//Serial.print(" Concentration:");
//Serial.println(concentration);
return concentration;
}
///////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
///////////////////////////////////////////////////////////////////////////////////////////////
server.handleClient();
///////////////////////////////////////////////////////////////////////////////////////////////
//SSD1306_OLED
display.setCursor(0,0);
display.clearDisplay();
display.print("T: "); display.println(bme.readTemperature()); //display.println(" C");
display.print("P: "); display.println(bme.readPressure() / 100.0F); //display.println(" H");
display.print("H: "); display.println(bme.readHumidity()); //display.println("%");
display.display();
//Dust Sensor(DSM501a)
durationPM1 = pulseIn(PM1PIN, LOW);
durationPM25 = pulseIn(PM25PIN, LOW);
lowpulseoccupancyPM1 += durationPM1;
lowpulseoccupancyPM25 += durationPM25;
endtime = millis();
if ((endtime-starttime) > sampletime_ms) //Only after 30s has passed we calcualte the ratio
{
float PM1 = calculateConcentration(lowpulseoccupancyPM1,30);
float PM25 = calculateConcentration(lowpulseoccupancyPM25,30);
//Serial.print("PM 1.0=> ");
//Serial.print(PM1);
//Serial.print(" PM 2.5=> ");
//Serial.println(PM25);
lowpulseoccupancyPM1 = 0;
lowpulseoccupancyPM25 = 0;
starttime = millis();
}
//Trend Calculation
for (int i = 0; i < count5; i++) {
temperature = bme.readTemperature();
pressure = bme.readPressure() / 100.0F; //bme280
humidity = bme.readHumidity();
delay(t_interval);
t_ave += temperature;
p_ave += pressure;
h_ave += humidity;
}
t_ave /= count5;
p_ave /= count5;
h_ave /= count5;
t_was = put(t_ave);
p_was = put(p_ave);
h_was = put(h_ave);
change_T = t_ave - t_was; //change reading
change_P = p_ave - p_was; //change reading
change_H = h_ave - h_was; //change reading
t_ave = 0; //reset ready for next calculation
p_ave = 0; //reset ready for next calculation
h_ave = 0; //reset ready for next calculation
if (change_T > 0.11){
digitalWrite(REDLED,LOW);
digitalWrite(GREENLED,HIGH);
}
else if (change_T < -0.11){
digitalWrite(REDLED,HIGH);
digitalWrite(GREENLED,LOW);
}
else if (change_T > -0.1 && change_T < 0.1){
digitalWrite(REDLED,HIGH);
digitalWrite(GREENLED,HIGH);
}
if (change_P > 0.11){
digitalWrite(REDLED_P,LOW);
digitalWrite(GREENLED_P,HIGH);
}
else if (change_P < -0.11){
digitalWrite(REDLED_P,HIGH);
digitalWrite(GREENLED_P,LOW);
}
else if (change_P > -0.1 && change_P < 0.1){
digitalWrite(REDLED_P,HIGH);
digitalWrite(GREENLED_P,HIGH);
}
if (change_H > 1.01){
digitalWrite(REDLED_H,LOW);
digitalWrite(GREENLED_H,HIGH);
}
else if (change_H < -1.01){
digitalWrite(REDLED_H,HIGH);
digitalWrite(GREENLED_H,LOW);
}
else if (change_H > -1 && change_H < 1){
digitalWrite(REDLED_H,HIGH);
digitalWrite(GREENLED_H,HIGH);
}
}
//Trend Calculation
float put(float value){
Serial.print("T-now = ");
Serial.print(value, 2);
data[put_index] = value;
put_index=(put_index+1)% length;
value=data[put_index];
Serial.print(": T-was = ");
Serial.println(value, 2);
Serial.print("P-now = ");
Serial.print(value, 2);
data[put_index] = value;
put_index=(put_index+1)% length;
value=data[put_index];
Serial.print(": P-was = ");
Serial.println(value, 2);
Serial.print("H-now = ");
Serial.print(value, 2);
data[put_index] = value;
put_index=(put_index+1)% length;
value=data[put_index];
Serial.print(": H-was = ");
Serial.println(value, 2);
Serial.print("Change_T = ");
Serial.println(change_T);
Serial.print("Change_P = ");
Serial.println(change_P);
Serial.print("Change_H = ");
Serial.println(change_H);
return(value);
}
///////////////////////////////////////////////////////////////////////////////////////////////
//ESP8266 Webserver
void handle_OnConnect() {
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
String formattedTime = timeClient.getFormattedTime();
struct tm *ptm = gmtime ((time_t *)&epochTime);
int monthDay = ptm->tm_mday;
int currentMonth = ptm->tm_mon+1;
int currentYear = ptm->tm_year+1900;
formattedTime = timeClient.getFormattedTime();
Date = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
float Temperature = bme.readTemperature();
float Pressure = bme.readPressure() / 100.0F;
float Humidity = bme.readHumidity();
float PM1 = calculateConcentration(lowpulseoccupancyPM1,30);
float PM25 = calculateConcentration(lowpulseoccupancyPM25,30);
MQ135.update();
MQ135.setA(605.18); MQ135.setB(-3.937);
float CO = MQ135.readSensor();
MQ135.setA(77.255); MQ135.setB(-3.18);
float Alcohol = MQ135.readSensor();
MQ135.setA(110.47); MQ135.setB(-2.862);
float CO2 = MQ135.readSensor() + 421.37;
MQ135.setA(44.947); MQ135.setB(-3.445);
float Toluen = MQ135.readSensor();
MQ135.setA(102.2 ); MQ135.setB(-2.473);
float NH4 = MQ135.readSensor();
MQ135.setA(34.668); MQ135.setB(-3.369);
float Aceton = MQ135.readSensor();
server.send(200, "text/html", SendHTML(Temperature, Pressure, Humidity, PM1, PM25, CO, Alcohol, CO2, Toluen, NH4, Aceton, formattedTime, Date));
}
void handle_NotFound(){server.send(404, "text/plain", "Not found"); }
//////////////////////////////////////////////////////////////////////////////////////////////
//ESP8266 Webserver
String SendHTML(float TemperatureWeb, float PressureWeb, float HumidityWeb, float PM1Web, float PM25Web, float COWeb, float AlcoholWeb, float CO2Web, float ToluenWeb, float NH4Web, float AcetonWeb, String TimeWeb, String DateWeb){String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Global Server</title>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 Global Server</h1>\n";
ptr +="<p>Date: ";
ptr +=(String)DateWeb;
ptr +="</p>";
ptr +="<p>Time: ";
ptr +=(String)TimeWeb;
ptr +="</p>";
ptr +="<p>Temperature: ";
ptr +=(float)TemperatureWeb;
ptr +=" *C</p>";
ptr +="<p>Pressure: ";
ptr +=(float)PressureWeb;
ptr +=" hPa</p>";
ptr +="</p>Humidity: ";
ptr +=(float)HumidityWeb;
ptr +=" %</p>";
ptr +="</p>PM 1.0: ";
ptr +=(float)PM1Web;
ptr +=" mg/m3</p>";
ptr +="</p>PM 2.5: ";
ptr +=(float)PM25Web;
ptr +=" mg/m3</p>";
ptr +="</p>CO: ";
ptr +=(float)COWeb;
ptr +=" PPM</p>";
ptr +="</p>CO2: ";
ptr +=(float)CO2Web;
ptr +=" PPM</p>";
ptr +="</p>Alcohol: ";
ptr +=(float)AlcoholWeb;
ptr +=" PPM</p>";
ptr +="</p>Toluen: ";
ptr +=(float)ToluenWeb;
ptr +=" PPM</p>";
ptr +="</p>NH4: ";
ptr +=(float)NH4Web;
ptr +=" PPM</p>";
ptr +="</p>Aceton: ";
ptr +=(float)AcetonWeb;
ptr +=" PPM</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
please help me to solve this problem.
thanks.