Introduction: Humidity,Pressure and Temperature Computation Using BME280 and Photon Interfacing.

About: We are a group of makers. We work in IoT, IOS app, android app, embedded design, sensor design, raspberry pi, arduino, beaglebone, particle electron, particle photon, Bluetooth.

We come across various projects which require's temperature, pressure and humidity monitoring. Thus we realize that these parameters actually play a vital role in having an estimate of the working efficiency of a system at different atmospheric conditions. Both at the industrial level and personal systems an optimum temperature,humidity and barometric pressure level is requisite for the adequate performance of the system.

This is why we provide a complete tutorial on this sensor, in this tutorial we are going to explain the working of the BME280 humidity, pressure and temperature sensor with particle photon.

Step 1: BME280 Exploration

Electronic sector has stepped up their game with the BME280 sensor, an environmental sensor with temperature, barometric pressure and humidity! This sensor is great for all sorts of weather/environmental sensing and can even be used in I2C.

This precision sensor BME280 is the best sensing solution for measuring humidity with ±3% accuracy, barometric pressure with ±1 hPa absolute accuraccy, and temperature with ±1.0°C accuracy. Because pressure changes with altitude, and the pressure measurements are so good, you can also use it as an altimeter with ±1 meter or better accuracy!The temperature sensor has been optimized for the lowest noise and highest resolution and is used for temperature compensation of the pressure sensor and can also be used for estimation of ambient temperature. Measurements with the BME280 can be performed by the user or performed in regular intervals.

Datasheet : Click to preview or download the datasheet of BME280 sensor.

Step 2: Hardware Requirement List

We used entirely Dcube Store Parts because they're easy to use, and something about everything fitting nicely on a centimeter grid really gets us going. You can use whatever you want, but the wiring diagram will assume you're using these parts.

Step 3: Interfacing

The interfacing section basically explains the wiring connections required between the sensor and the particle photon. Ensuring correct connections is the basic necessity while working on any system for the desired output. So, the requisite connections are as follows:

The BME280 will work over I2C . Here is the example wiring diagram, demonstrating how to wire up each interface of the sensor. Out-of-the-box, the board is configured for an I2C interface, as such we recommend to use this interfacing if you’re otherwise agnostic. All you need is four wires! Only four connections are required Vcc, Gnd, SCL and SDA pins and these are connected with the help of I2C cable. These connections are demonstrated in the pictures above.

Step 4: Temperature, Pressure and Humidity Monitoring Code

The clean version of the code that we'll be using to run this is available HERE.

While using the sensor module with the Arduino, we include application.h and spark_wiring_i2c.h library. "application.h" and spark_wiring_i2c.h library contains the functions which facilitate the i2c communication between the sensor and the particle.

Click HERE to open the webpage for device monitoring

Upload the code to your board and it should start working! All the data can be obtained on the webpage as shown in the picture.

Code is provided below:

<p>// Distributed with a free-will license.<br>// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// BME280
// This code is designed to work with the BME280_I2CS I2C Mini Module available from ControlEverything.com.
#include
#include
// BME280 I2C address is 0x76(108)
#define Addr 0x76
double cTemp = 0, fTemp = 0, pressure = 0, humidity = 0;
void setup()
{
// Set variable
Particle.variable("i2cdevice", "BME280");
article.variable("cTemp", cTemp);
Particle.variable("fTemp", fTemp);
Particle.variable("pressure", pressure);
Particle.variable("humidity", humidity);
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise Serial communication, set baud rate = 9600
Serial.begin(9600);
delay(300);
}
void loop()
{
unsigned int b1[24];
unsigned int data[8];
int dig_H1 = 0;
for(int i = 0; i < 24; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((136+i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 24 bytes of data
if(Wire.available() == 1)
{
b1[i] = Wire.read();
}
}
// Convert the data
// temp coefficents
int dig_T1 = (b1[0] & 0xff) + ((b1[1] & 0xff) * 256);
int dig_T2 = b1[2] + (b1[3] * 256);
int dig_T3 = b1[4] + (b1[5] * 256);
// pressure coefficents
int dig_P1 = (b1[6] & 0xff) + ((b1[7] & 0xff ) * 256);
int dig_P2 = b1[8] + (b1[9] * 256);
int dig_P3 = b1[10] + (b1[11] * 256);
int dig_P4 = b1[12] + (b1[13] * 256);
int dig_P5 = b1[14] + (b1[15] * 256);
int dig_P6 = b1[16] + (b1[17] * 256);
int dig_P7 = b1[18] + (b1[19] * 256);
int dig_P8 = b1[20] + (b1[21] * 256);
int dig_P9 = b1[22] + (b1[23] * 256);
for(int i = 0; i < 7; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((225+i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 7 bytes of data
if(Wire.available() == 1)
{
b1[i] = Wire.read();
}
}
// Convert the data
// humidity coefficents
int dig_H2 = b1[0] + (b1[1] * 256);
int dig_H3 = b1[2] & 0xFF ;
int dig_H4 = (b1[3] * 16) + (b1[4] & 0xF);
int dig_H5 = (b1[4] / 16) + (b1[5] * 16);
int dig_H6 = b1[6];
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write(161);
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 1 byte of data
if(Wire.available() == 1)
{
dig_H1 = Wire.read();
}
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control humidity register
Wire.write(0xF2);
// Humidity over sampling rate = 1
Wire.write(0x01);
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control measurement register
Wire.write(0xF4);
// Normal mode, temp and pressure over sampling rate = 1
Wire.write(0x27);
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select config register
Wire.write(0xF5);
// Stand_by time = 1000ms
Wire.write(0xA0);
// Stop I2C Transmission
Wire.endTransmission();
for(int i = 0; i < 8; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((247+i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 8 bytes of data
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
}
// Convert pressure and temperature data to 19-bits
long adc_p = (((long)(data[0] & 0xFF) * 65536) + ((long)(data[1] & 0xFF) * 256) + (long)(data[2] & 0xF0)) / 16;
long adc_t = (((long)(data[3] & 0xFF) * 65536) + ((long)(data[4] & 0xFF) * 256) + (long)(data[5] & 0xF0)) / 16;
// Convert the humidity data long adc_h = ((long)(data[6] & 0xFF) * 256 + (long)(data[7] & 0xFF));
// Temperature offset calculations
double var1 = (((double)adc_t) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
double var2 = ((((double)adc_t) / 131072.0 - ((double)dig_T1) / 8192.0) * (((double)adc_t)/131072.0 - ((double)dig_T1)/8192.0)) * ((double)dig_T3);
double t_fine = (long)(var1 + var2);
double cTemp = (var1 + var2) / 5120.0;
double fTemp = cTemp * 1.8 + 32;
// Pressure offset calculations
var1 = ((double)t_fine / 2.0) - 64000.0;
var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
var2 = var2 + var1 * ((double)dig_P5) * 2.0;
var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
var1 = (((double) dig_P3) * var1 * var1 / 524288.0 + ((double) dig_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
double p = 1048576.0 - (double)adc_p;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
var1 = ((double) dig_P9) * p * p / 2147483648.0;
var2 = p * ((double) dig_P8) / 32768.0;
double pressure = (p + (var1 + var2 + ((double)dig_P7)) / 16.0) / 100 ;
// Humidity offset calculations
double var_H = (((double)t_fine) - 76800.0);
var_H = (adc_h - (dig_H4 * 64.0 + dig_H5 / 16384.0 * var_H)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * var_H * (1.0 + dig_H3 / 67108864.0 * var_H)));
double humidity = var_H * (1.0 - dig_H1 * var_H / 524288.0);
if(humidity > 100.0)
{
humidity = 100.0;
}
else if(humidity < 0.0)
{
humidity = 0.0;
}
// Output data to dashboard
Particle.publish("Temperature in Celsius : ", String(cTemp));
Particle.publish("Temperature in Fahrenheit : ", String(fTemp));
Particle.publish("Pressure : ", String(pressure));
Particle.publish("Relative Humidity : ", String(humidity));
delay(1000);
}</p>

Step 5: Applications:

BME280 temperature, pressure and relative humidity sensor has various industrial applications like temperature monitoring, computer peripheral thermal protection, pressure monitoring in industry. We have also employed this sensor into weather station applications as well as greenhouse monitoring system.

Other applications may inculde:

  1. Context awareness, e.g. skin detection, room change detection.
  2. Fitness monitoring / well-being - Warning regarding dryness or high temperatures.
  3. Measurement of volume and air flow.
  4. Home automation control.
  5. Control heating, ventilation, air conditioning (HVAC).
  6. Internet of things.
  7. GPS enhancement (e.g. time-to-first-fix improvement, dead reckoning, slope detection).
  8. Indoor navigation (change of floor detection, elevator detection).
  9. Outdoor navigation, leisure and sports applications.
  10. Weather forecast.
  11. Vertical velocity indication (rise/sink speed)..

Step 6: Video Tutorial

Watch our video tutorial to go through all the steps in interfacing and completing the project.

Stay tuned for other sensor's interfacing and working blog's.