Sunday, March 8, 2020

Weather station with ESP8266, DHT22 and BMP280

Objective:
  Setup a weather station with ESP8266 ESP-01, DHT22 and BMP280.  It also come with remote switch.

Note: 
  The experience from this project can be transfer to another project quickly.  Such as application with I2C and ESP8266.  The MQTT setup is not part of the scope of this project demonstration; therefore, it is not discussed here.

Learned lesson: 
1. How to program ESP8266 ESP-01.  See my other post at https://ap170210.blogspot.com/2020/03/program-esp8266-01-with-usb-to-esp8266.html
2. CH_PD/EN has to connect to 3.3V in order to work properly.
3. I2C set up with ESP8266 is different from Arduino.  For example, I must add Wire.pins(0, 2); Wire.begin(0, 2);   in order to make I2C work.  But Arduino Uno does not need it.
4. The location of SCL and SDA on ESP8266.
5. When program GPIO0 (not in this example) since it is grounded during the programming, do NOT set it to HIGH, it will damage your chip.


Code:
//Reference website
//https://lastminuteengineers.com/bmp280-esp8266-weather-station/
//https://www.theengineeringprojects.com/2019/05/introduction-to-esp-01.html
//https://www.instructables.com/id/One-More-Arduino-Weather-Station-ESP-01-BMP280-DHT/
//In order function properly, CH_PD/EN must connect to 3.3V

//BMP280 SDA -- ESP-01 GPIO0
//BMP280 SCL -- ESP-01 GPIO2
//BMP280 VCC -- 3.3V
//BMP280 GND -- GND
//DHT22 signal -- Tx(GPIO1)
//DHT22 VCC -- 3.3V
//DHT22 GND -- GND
//ESP-01 CH_PD/EN -- 3.3V

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include "DHT.h"

/************************* WiFi Access Point *********************************/
#define WLAN_SSID       "**********"
#define WLAN_PASS      "**********"
/************************* Adafruit.io Setup *********************************/
#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "**********"
#define AIO_KEY         "**********"

// DHT Sensor
#define DHTTYPE DHT22
uint8_t DHTPin = 1;  
DHT dht(DHTPin, DHTTYPE); 
float temperature_dht, humidity_dht;  

//Initialize BMP sensor              
Adafruit_BMP280 bmp;
float temperature, pressure, altitude;

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/
Adafruit_MQTT_Publish bmp_temp =      Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/bmp_temp");
Adafruit_MQTT_Publish bmp_pressure =  Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/bmp_pressure");
Adafruit_MQTT_Publish dht_humidity =  Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/dht_humidity");
Adafruit_MQTT_Publish dht_temperature =  Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/dht_temperature");
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");

int onoffpin=1;
/*************************** Sketch Code ************************************/
void MQTT_connect();

void setup() {
  //I2C stuff, without it, ESP8266 ESP-01 cannot work properly
  Wire.pins(0, 2); Wire.begin(0, 2);    
  bmp.begin(0x76); delay(100);

  pinMode(DHTPin, INPUT);
  dht.begin(); delay(100);
  
  WiFi.begin(WLAN_SSID, WLAN_PASS); while (WiFi.status() != WL_CONNECTED) {delay(500);}
  pinMode(onoffpin, OUTPUT); mqtt.subscribe(&onoffbutton);
}

void loop() {
  MQTT_connect();
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &onoffbutton) {
      if(onoffbutton.lastread[1]==78){digitalWrite(onoffpin,LOW);}
      if(onoffbutton.lastread[1]==70){digitalWrite(onoffpin,HIGH);}
    }
  }
  temperature = bmp.readTemperature()-2.1;  //2.1 is the calibration factor
  pressure = bmp.readPressure() / 100.0F;
  //altitude = bmp.readAltitude(1015);  //1015 is the pressure at ~San Jose sea level
  temperature_dht =dht.readTemperature()-0.9; //0.9 is a calibration factor
  humidity_dht=dht.readHumidity();
  
  // Now we can publish stuff!
  if (pressure>0){
    bmp_temp.publish(temperature);delay(2000);
    bmp_pressure.publish(pressure);delay(2000);
  }
  if (humidity_dht>0){
    dht_temperature.publish(temperature_dht);delay(2000);
    dht_humidity.publish(humidity_dht);delay(2000);
  }
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;
  // Stop if already connected.
  if (mqtt.connected()) {return;}
  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       mqtt.disconnect(); delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {while (1);} // basically die and wait for WDT to reset me   
  }  
}



No comments:

Post a Comment