Saturday, December 2, 2017

BME280 and ESP8266

Latest environmental sensor from Bosh is the BME280 which can measure:

  • temperature
  • humidity
  • pressure

and can be found in mobile phones (Nexus 5). There are rumors  that the BMP280 is a BME280 which couldn't be calibrated for humidity, but I have no confirmation on this.

BME280

Can be used for:



  • Indoor navigation (based on changing the measured altitude - pressure)
  • Outdoor navigation
  • Weather forecast
  • Home application control
  • Context awareness ( change room detection)  
  • Internet of Things.


Temperature precision is ± 1 C degree in 0-60C range.




Can be found in multiple modules, from SPI connectivity to I2C.

Make sure that if you are using the I2C version  to change the I2C address to 0x76. ( Default value for I2C address in Adafruit's library is 0x77).


I2C version

The SPI version can be found around USD 5 here.




Code is similar with the BMP280 , just read the humidity


/******************************************************
 * Catalin Batrinu bcatalin@gmail.com 
 * Read temperature, humidity and pressure from BME280
 * and send it to thingspeaks.com
*******************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <ESP8266WiFi.h>


Adafruit_BME280 bme; // I2C
// replace with your channel’s thingspeak API key,
String apiKey = "YOUR-API-KEY";
const char* ssid = "YOUR-SSID";
const char* password = "YOUR-ROUTER-PASSWORD";
const char* server = "api.thingspeak.com";
WiFiClient client;


/**************************  
 *   S E T U P
 **************************/
void setup() {
  Serial.begin(115200);
  Serial.println(F("BMP280 test"));
  
  if (!bme.begin()) {  
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
  WiFi.begin(ssid, password);
  
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");  
}

  /**************************  
 *  L O O P
 **************************/
void loop() {

    if (client.connect(server,80))  // "184.106.153.149" or api.thingspeak.com
    {
        String postStr = apiKey;
        postStr +="&field1=";
        postStr += String(bme.readTemperature());
        postStr +="&field2=";
        postStr += String(bme.readHumidity());
        postStr +="&field3=";
        postStr += String(bme.readPressure() / 100.0F);
        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: "+apiKey+"\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);    
    }
    client.stop(); 
    //every 20 sec   
    delay(20000);
}


If your readings are with almost 2 degrees more than the expected value is because the BME280 is to close to the ESP8266. Try to keep at least 10 cm between the BME280 and ESP8266 to eliminate the RF heating and heating produced by ESP8266. 

Also is possible that you run the BME280 in normal mode ( more samples per second) versus forced mode when you are reading the values exactly when you need them ( here the drift is around 0.6 degrees Celsius).

The complete datasheet can be found here.

5 comments:

  1. Hy,
    Can you tell me how can I modify the libraries to have forced mode?
    With any library used, I have a temperature with aprox 2 def higher.

    Thank you

    ReplyDelete
  2. In setup() after the bme.begin(...)

    bme.setSampling(Adafruit_BME280::MODE_FORCED,
    Adafruit_BME280::SAMPLING_X1, // temperature
    Adafruit_BME280::SAMPLING_X1, // pressure
    Adafruit_BME280::SAMPLING_X1, // humidity
    Adafruit_BME280::FILTER_OFF );

    and before bme.readTemperature(); add

    bme.takeForcedMeasurement();

    ReplyDelete

  3. how do I display two bmp280 sensors with I2C and how is the scheme, please help ??

    ReplyDelete
    Replies
    1. Depending of your board or if you can have access to your bmp280 chip ( in case you design your own PCB). Connecting the SDO pin to GND, the i2c address will be 0x76 and connecting the SDO to VDD the i2c address will be 0x77.

      By modifying bme.begin() function to take parameters ( see: bool begin(uint8_t addr = BMP280_ADDRESS, uint8_t chipid = BMP280_CHIPID);
      ) you can create two objects bme1 and bme2.

      For connecting them is just a regular i2c bus ( sda to sda, scl to scl) but make sure that you use pull-up resistors with the correct values.


      Delete
  4. You include Adafruit_BMP280.h, but you call for Adafruit_BME280 bme;

    ReplyDelete