Thursday, December 1, 2016

BMP280 and ESP8266

The BMP280 is the next generation sensor from Bosch and follows its predecessors BMP085 - BMP180.




Key parameters

  •  Pressure range 300 … 1100 hPa (equiv. to +9000…-500 m above/below sea level)
  •  Package 8-pin LGA metal-lid
  • Footprint : 2.0 × 2.5 mm², height: 0.95 mm
  •  Relative accuracy ±0.12 hPa, equiv. to ±1 m
  •  (950 … 1050hPa @25°C)
  •  Absolute accuracy typ. ±1 hPa  (950 ...1050 hPa, 0 ...+40 °C)
  •  Temperature coefficient offset 1.5 Pa/K, equiv. to 12.6 cm/K  (25 ... 40°C @900hPa)
  •  Digital interfaces I²C (up to 3.4 MHz) SPI (3 and 4 wire, up to 10 MHz)
  •  Current consumption 2.7µA @ 1 Hz sampling rate
  •  Temperature range -40 … +85 °C


Typical applications

  • Enhancement of GPS navigation
  •  (e.g. time-to-first-fix improvement, dead-reckoning, slope detection)
  •  Indoor navigation (floor detection, elevator detection)
  •  Outdoor navigation, leisure and sports applications
  •  Weather forecast
  •  Health care applications (e.g. spirometry)
  •  Vertical velocity indication (e.g. rise/sink speed)









For connecting the BMP280 to ESP8266 the following pins need to be connected: 


BMP280
NodeMCU / WeMos D1 mini
Other ESP8266
VCC
3V3

GND
GND

SCL
D1
GPIO 5
SDA
D2
GPIO 4
CSB
3V3

SDO
3V3




The BMP280 supports the I²C and SPI digital interfaces; it acts as a slave for both protocols. 

The I²C interface supports the Standard, Fast and High Speed modes. 

The SPI interface supports both SPI mode ‘00’ (CPOL = CPHA = ‘0’) and mode ‘11’ (CPOL = CPHA = ‘1’) in 4- wire and 3-wire configuration. The following transactions are supported: Single byte write  multiple byte write (using pairs of register addresses and register data) single byte read multiple byte read (using a single register address which is auto-incremented) 


Connect the CSB pin to GND to have SPI and to VCC(3V3) for I2C.

The 7-bit device address is 111011x. The 6 MSB bits are fixed. The last bit is changeable by SDO value and can be changed during operation. 

Connecting SDO to GND results in slave address 1110110 (0x76), connecting it to VCC results in slave address 1110111 (0x77), which is the same as BMP180’s I²C address. 

The SDO pin cannot be left floating, if left floating, the I²C address will be undefined.

In my setup I've connected CSB and SDO to VCC to have I2C and 0x77 as address.


To run a quick test I've installed the Adafruit Sensor library and Adafruit BMP280 library .

The code to test the BMP280 is the example code from library.

This code assume that the SDA and SCL are connected on GPIO 4 and GPIO 5. If you need to assign new pins to your BMP280 use the Wire.begin(2,0) where the GPIO 2 is connected to SDA and GPIO 0 is connected to  SCL.

Now its time to add some code to read the temperature and pressure, post them to the thingspeak.com and also update the temperature gauge on this blog.



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

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

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11 
#define BMP_CS 10

Adafruit_BMP280 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(9600);
  Serial.println(F("BMP280 test"));
  
  if (!bme.begin()) {  
    Serial.println("Could not find a valid BMP280 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() {
    Serial.print("T=");
    Serial.print(bme.readTemperature());
    Serial.print(" *C");
    
    Serial.print(" P=");
    Serial.print(bme.readPressure());
    Serial.print(" Pa");

    Serial.print(" A= ");
    Serial.print(bme.readAltitude(1013.25)); // this should be adjusted to your local forcase
    Serial.println(" m");

    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.readPressure());
        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);
}


Temperature logging














3 comments:

  1. I follow your procedure but it doesn't work.

    ReplyDelete
  2. Perfectly working, thank you very much.

    ReplyDelete
  3. thank you so much... this really help me...

    ReplyDelete