Mini weather station web server problem

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.

I'm confused. When you say

only the time and date are displayed in the web server and the air quality and dust data is zero

what do you mean? I don't see "air quality" or "dust" in the picture.
Do you mean those values aren't there at all or that they should be xxx and are showing as 0.0?

All the values you display on the OLED are correct in the web output. Tthe values that are zero in the web output you don't display on the OLED. So my guess is a hardware problem. As you failed to provide a wiring diagram we cannot help there.

when i disable "trend calculation" section in the void loop , other results show correctly.

Do you think this section has a problem?

What exactly does "other results" mean?

All values you use in the "Trend Calculation" part are displayed correctly in the web output.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.