ESP8266 Weather Station v2

ESP8266 Weather Station displaying temperature, humidity, pressure & dust on an OLED display with a touch button.

projectImage

Things used in this project

 

Hardware components

HARDWARE LIST
1 DFRobot Gravity: I2C BME280 Environmental Sensor
1 Espressif Wemos D1 Mini
1 1.3-inch i2c OLED Display
11 Jumper wires (generic)
1 Breadboard (generic)
1 USB-A to Micro-USB Cable
1 Seeed Studio Grove - Dust Sensor(PPD42NS)
1 Capacitive Touch Sensor

Story

 

A simple weather station displaying temperature, humidity, pressure & dust information and the current time/date on an OLED display using an ESP8266, BME280 sensor and a Grove dust sensor with touch sensor control.

The wiring of this project is extremely simple as all components (except the dust sensor & touch sensor) use the i2c interface, making use of four pins only. As both the OLED display and the BME280 sensor make use of this interface, the wiring is as follows:

VCC (on the sensor/OLED) - 3.3V (on the microcontroller)

GND - GND

SCL - D1

SDA - D2

The wiring for the dust sensor is as follows:

VCC (on the sensor) - 3.3V (on the microcontroller)

GND - GND

Signal - D3

The wiring for the touch sensor is as follows:

VCC (on the sensor) - 3.3V ( on the microcontroller)

GND - GND

Signal - D0

More information about the code and wiring is shown in this video:


 

Code

Project Code

C/C++

CODE
#include <ESP8266WiFi.h>
#include <time.h>
#include <U8x8lib.h>
#include "DFRobot_BME280.h"
 
const char* ssid = "WIFI";              
const char* password = "PASSWORD";      
 
const char* NTP_SERVER = "ch.pool.ntp.org";
const char* TZ_INFO    = "GMT+0BST-1,M3.5.0/01:00:00,M10.5.0/02:00:00";  // enter your time zone (https://remotemonitoringsystems.ca/time-zone-abbreviations.php)
 
tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
 
U8X8_SH1106_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // OLEDs without Reset of the Display
 
typedef DFRobot_BME280_IIC    BME;    // 
BME   bme(&Wire, 0x77);   // select TwoWire peripheral and set sensor address
#define SEA_LEVEL_PRESSURE    1015.0f
 
const int touchPin = D0;
int touchState = 0;
int pageNumber = 0;
 
int dustPin = D3;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 2000; 
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
 
void printLastOperateStatus(BME::eStatus_t eStatus) // show last sensor operate status
{
  switch(eStatus) {
  case BME::eStatusOK:    Serial.println("everything ok"); break;
  case BME::eStatusErr:   Serial.println("unknow error"); break;
  case BME::eStatusErrDeviceNotDetected:    Serial.println("device not detected"); break;
  case BME::eStatusErrParameter:    Serial.println("parameter error"); break;
  default: Serial.println("unknow status"); break;
  }
}
 
void setup()
{
  pinMode(touchPin, INPUT);
  pinMode(dustPin,INPUT);
  starttime = millis(); 
  u8x8.begin();
  Serial.begin(9600);
  WiFi.begin(ssid, password);
 
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);    
    if (++counter > 100) 
      ESP.restart();
  }
 
  configTime(0, 0, NTP_SERVER);
  // See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
  setenv("GMT0BST,M3.5.0/1,M10.5.0", TZ_INFO, 1);
 
  if (getNTPtime(10)) 
  {  
    // Wait up to 10 seconds to sync
  } 
  else 
  {
    ESP.restart();
  }
  showTime(&timeinfo);
  lastNTPtime = time(&now);
  lastEntryTime = millis();
    
  bme.reset();
  while(bme.begin() != BME::eStatusOK) {
    printLastOperateStatus(bme.lastOperateStatus);
    delay(2000);
  }
  delay(100);
}
 
void loop()
{ 
  duration = pulseIn(dustPin, LOW);
  lowpulseoccupancy = lowpulseoccupancy+duration;
  if ((millis()-starttime) >= sampletime_ms)
  {
    ratio = lowpulseoccupancy/(sampletime_ms*10.0);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; 
    lowpulseoccupancy = 0;
    starttime = millis();
  }
  touchState = digitalRead(touchPin);
  getNTPtime(10);
  showTime(&timeinfo);
  
  float   temp = bme.getTemperature();
  uint32_t press = bme.getPressure();
  float   alti = bme.calAltitude(SEA_LEVEL_PRESSURE, press);
  float   humi = bme.getHumidity();
 
  char temp_buff[9]; char hum_buff[9]; char pres_buff[9]; char alt_buff[9]; char dust_buff[15];
  char cel_buff[11] = "C";
  char per_buff[11] = "%";
  char pa_buff[11] = " Pa";
  char met_buff[11] = "m";
  char pcs_buff[11] = " pcs";
 
  dtostrf(temp, 3, 1, temp_buff);
  strcat(temp_buff, cel_buff); 
  dtostrf(humi, 3, 0, hum_buff);
  strcat(hum_buff, per_buff);
  dtostrf(press, 5, 0, pres_buff);
  strcat(pres_buff, pa_buff);
  dtostrf(alti, 5, 2, alt_buff);
  strcat(alt_buff, met_buff);
  dtostrf(concentration, 3, 1, dust_buff);
  strcat(dust_buff, pcs_buff);
  
  if(touchState == HIGH){
    if(pageNumber < 2){
      u8x8.clearDisplay();
      pageNumber=pageNumber + 1;
    }
    else {
      pageNumber = 0;
    }
  }
 
  if(pageNumber == 0){
  u8x8.setFont(u8x8_font_artossans8_r);
  u8x8.setCursor(0,2);
  u8x8.print("Temp: ");
  u8x8.setCursor(6,2); 
  u8x8.print(temp_buff);
  u8x8.setCursor(0,4);
  u8x8.print("Humi: "); 
  u8x8.setCursor(6,4);
  u8x8.print(hum_buff);
  u8x8.setCursor(0,6);
  u8x8.print("Pres: "); 
  u8x8.setCursor(6,6);
  u8x8.print(pres_buff);
  }
  else if(pageNumber == 1){
  u8x8.setFont(u8x8_font_artossans8_r);
  u8x8.setCursor(0,2);
  u8x8.print("Alti: ");
  u8x8.setCursor(6,2); 
  u8x8.print(alt_buff);
  u8x8.setCursor(0,4);
  u8x8.print("Dust: ");
  u8x8.setCursor(6,4);
  u8x8.print(dust_buff);
  }
  else if(pageNumber == 2){
  u8x8.setFont(u8x8_font_artossans8_r);
  u8x8.setCursor(0,2);
  u8x8.print("Page 3"); 
  }
}
  
bool getNTPtime(int sec) 
{
  {
    uint32_t start = millis();
    do
    {
      time(&now);
      localtime_r(&now, &timeinfo);
      delay(10);
    } while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
    
    if (timeinfo.tm_year <= (2016 - 1900)) 
        return false;  // the NTP call was not successful
  }
  return true;
}
 
void showTime(tm *localTime) 
{
  char time_output[30];
  
  u8x8.setFont(u8x8_font_artossans8_n);
  u8x8.setCursor(0,0);
  sprintf(time_output, "%02d:%02d", localTime->tm_hour, localTime->tm_min);
  u8x8.print(time_output);
  
  u8x8.setFont(u8x8_font_artossans8_r);
  u8x8.setCursor(7,0);
  sprintf(time_output, "%02d/%02d/%02d", localTime->tm_mday, localTime->tm_mon + 1, localTime->tm_year - 100);
  u8x8.print(time_output);
}

The article was first published in hackster, June 1, 2022

cr: https://www.hackster.io/infoelectorials/esp8266-weather-station-v2-3b8629

author: Electorials Electronics


 

License
All Rights
Reserved
licensBg
1