Skip to content

Commit 3863cea

Browse files
committed
2 parents 3b07e8c + a97663c commit 3863cea

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
Get environmental readings as a burst from the BME280
3+
By: Claudio Donaté
4+
Date: December 30th, 2020
5+
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
6+
7+
Feel like supporting our work? Buy a board from SparkFun!
8+
https://www.sparkfun.com/products/14348 - Qwiic Combo Board
9+
https://www.sparkfun.com/products/13676 - BME280 Breakout Board
10+
11+
This example shows how to read humidity, pressure, and current temperature from the BME280 over I2C reading all registers at once.
12+
Please check BME280 Datasheet, section 4, Data readout for detail explanations on why.
13+
14+
Hardware connections:
15+
BME280 -> Arduino
16+
GND -> GND
17+
3.3 -> 3.3
18+
SDA -> A4
19+
SCL -> A5
20+
*/
21+
22+
#include <Wire.h>
23+
24+
#include "SparkFunBME280.h"
25+
26+
#define CELSIUS_SCALE 0 //Default
27+
#define FAHRENHEIT_SCALE 1
28+
29+
BME280 mySensor;
30+
BME280_SensorMeasurements measurements;
31+
32+
void setup()
33+
{
34+
Serial.begin(9600);
35+
Serial.println("Reading basic values from BME280 as a Burst");
36+
37+
Wire.begin();
38+
39+
if (mySensor.beginI2C() == false) //Begin communication over I2C
40+
{
41+
Serial.println("The sensor did not respond. Please check wiring.");
42+
while(1); //Freeze
43+
}
44+
}
45+
46+
void loop()
47+
{
48+
while (mySensor.isMeasuring()) // Wait for sensor to finish measuring
49+
{
50+
Serial.print(".");
51+
};
52+
53+
mySensor.readAllMeasurements(&measurements); // Return temperature in Celsius
54+
// mySensor.readAllMeasurements(&measurements, FAHRENHEIT_SCALE);
55+
56+
Serial.print("\nHumidity: ");
57+
Serial.print(measurements.humidity, 0);
58+
59+
Serial.print(" Pressure: ");
60+
Serial.print(measurements.pressure, 0);
61+
62+
Serial.print(" Temp: ");
63+
Serial.print(measurements.temperature, 2);
64+
65+
Serial.println();
66+
67+
delay(50);
68+
}

src/SparkFunBME280.cpp

+105
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Distributed as-is; no warranty is given.
2020
******************************************************************************/
2121
//See SparkFunBME280.h for additional topology notes.
2222

23+
#include <math.h>
2324
#include "SparkFunBME280.h"
2425

2526
//****************************************************************************//
@@ -355,6 +356,29 @@ void BME280::reset( void )
355356

356357
}
357358

359+
//****************************************************************************//
360+
//
361+
// Burst Measurement Section
362+
//
363+
//****************************************************************************//
364+
365+
//Read all sensor registers as a burst. See BME280 Datasheet section 4. Data readout
366+
//tempScale = 0 for Celsius scale (default setting)
367+
//tempScale = 1 for Fahrenheit scale
368+
void BME280::readAllMeasurements(BME280_SensorMeasurements *measurements, byte tempScale){
369+
370+
uint8_t dataBurst[8];
371+
readRegisterRegion(dataBurst, BME280_MEASUREMENTS_REG, 8);
372+
373+
if(tempScale == 0){
374+
readTempCFromBurst(dataBurst, measurements);
375+
}else{
376+
readTempFFromBurst(dataBurst, measurements);
377+
}
378+
readFloatPressureFromBurst(dataBurst, measurements);
379+
readFloatHumidityFromBurst(dataBurst, measurements);
380+
}
381+
358382
//****************************************************************************//
359383
//
360384
// Pressure Section
@@ -390,6 +414,37 @@ float BME280::readFloatPressure( void )
390414

391415
}
392416

417+
void BME280::readFloatPressureFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements)
418+
{
419+
420+
// Set pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
421+
// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
422+
423+
int32_t adc_P = ((uint32_t)buffer[0] << 12) | ((uint32_t)buffer[1] << 4) | ((buffer[2] >> 4) & 0x0F);
424+
425+
int64_t var1, var2, p_acc;
426+
var1 = ((int64_t)t_fine) - 128000;
427+
var2 = var1 * var1 * (int64_t)calibration.dig_P6;
428+
var2 = var2 + ((var1 * (int64_t)calibration.dig_P5)<<17);
429+
var2 = var2 + (((int64_t)calibration.dig_P4)<<35);
430+
var1 = ((var1 * var1 * (int64_t)calibration.dig_P3)>>8) + ((var1 * (int64_t)calibration.dig_P2)<<12);
431+
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)calibration.dig_P1)>>33;
432+
if (var1 == 0)
433+
{
434+
measurements->pressure = 0; // avoid exception caused by division by zero
435+
}
436+
else
437+
{
438+
p_acc = 1048576 - adc_P;
439+
p_acc = (((p_acc<<31) - var2)*3125)/var1;
440+
var1 = (((int64_t)calibration.dig_P9) * (p_acc>>13) * (p_acc>>13)) >> 25;
441+
var2 = (((int64_t)calibration.dig_P8) * p_acc) >> 19;
442+
p_acc = ((p_acc + var1 + var2) >> 8) + (((int64_t)calibration.dig_P7)<<4);
443+
444+
measurements->pressure = (float)p_acc / 256.0;
445+
}
446+
}
447+
393448
// Sets the internal variable _referencePressure so the altitude is calculated properly.
394449
// This is also known as "sea level pressure" and is in Pascals. The value is probably
395450
// within 10% of 101325. This varies based on the weather:
@@ -459,6 +514,25 @@ float BME280::readFloatHumidity( void )
459514
return (float)(var1>>12) / 1024.0;
460515
}
461516

517+
void BME280::readFloatHumidityFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements)
518+
{
519+
520+
// Set humidity in %RH as unsigned 32 bit integer in Q22. 10 format (22 integer and 10 fractional bits).
521+
// Output value of “47445” represents 47445/1024 = 46. 333 %RH
522+
int32_t adc_H = ((uint32_t)buffer[6] << 8) | ((uint32_t)buffer[7]);
523+
524+
int32_t var1;
525+
var1 = (t_fine - ((int32_t)76800));
526+
var1 = (((((adc_H << 14) - (((int32_t)calibration.dig_H4) << 20) - (((int32_t)calibration.dig_H5) * var1)) +
527+
((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)calibration.dig_H6)) >> 10) * (((var1 * ((int32_t)calibration.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
528+
((int32_t)calibration.dig_H2) + 8192) >> 14));
529+
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)calibration.dig_H1)) >> 4));
530+
var1 = (var1 < 0 ? 0 : var1);
531+
var1 = (var1 > 419430400 ? 419430400 : var1);
532+
533+
measurements->humidity = (float)(var1>>12) / 1024.0;
534+
}
535+
462536
//****************************************************************************//
463537
//
464538
// Temperature Section
@@ -494,6 +568,29 @@ float BME280::readTempC( void )
494568
return output;
495569
}
496570

571+
float BME280::readTempFromBurst(uint8_t buffer[])
572+
{
573+
int32_t adc_T = ((uint32_t)buffer[3] << 12) | ((uint32_t)buffer[4] << 4) | ((buffer[5] >> 4) & 0x0F);
574+
575+
//By datasheet, calibrate
576+
int64_t var1, var2;
577+
578+
var1 = ((((adc_T>>3) - ((int32_t)calibration.dig_T1<<1))) * ((int32_t)calibration.dig_T2)) >> 11;
579+
var2 = (((((adc_T>>4) - ((int32_t)calibration.dig_T1)) * ((adc_T>>4) - ((int32_t)calibration.dig_T1))) >> 12) *
580+
((int32_t)calibration.dig_T3)) >> 14;
581+
t_fine = var1 + var2;
582+
float output = (t_fine * 5 + 128) >> 8;
583+
584+
output = output / 100 + settings.tempCorrection;
585+
586+
return output;
587+
}
588+
589+
void BME280::readTempCFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements)
590+
{
591+
measurements->temperature = readTempFromBurst(buffer);
592+
}
593+
497594
float BME280::readTempF( void )
498595
{
499596
float output = readTempC();
@@ -502,6 +599,14 @@ float BME280::readTempF( void )
502599
return output;
503600
}
504601

602+
void BME280::readTempFFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements)
603+
{
604+
float output = readTempFromBurst(buffer);
605+
output = (output * 9) / 5 + 32;
606+
607+
measurements->temperature = output;
608+
}
609+
505610
//****************************************************************************//
506611
//
507612
// Dew point Section

src/SparkFunBME280.h

+15
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ Distributed as-is; no warranty is given.
105105
#define BME280_STAT_REG 0xF3 //Status Reg
106106
#define BME280_CTRL_MEAS_REG 0xF4 //Ctrl Measure Reg
107107
#define BME280_CONFIG_REG 0xF5 //Configuration Reg
108+
#define BME280_MEASUREMENTS_REG 0xF7 //Measurements register start
108109
#define BME280_PRESSURE_MSB_REG 0xF7 //Pressure MSB
109110
#define BME280_PRESSURE_LSB_REG 0xF8 //Pressure LSB
110111
#define BME280_PRESSURE_XLSB_REG 0xF9 //Pressure XLSB
@@ -172,6 +173,14 @@ struct SensorCalibration
172173

173174
};
174175

176+
struct BME280_SensorMeasurements
177+
{
178+
public:
179+
float temperature;
180+
float pressure;
181+
float humidity;
182+
};
183+
175184
//This is the main operational class of the driver.
176185

177186
class BME280
@@ -215,18 +224,22 @@ class BME280
215224

216225
//Software reset routine
217226
void reset( void );
227+
void readAllMeasurements(BME280_SensorMeasurements *measurements, byte tempScale = 0);
218228

219229
//Returns the values as floats.
220230
float readFloatPressure( void );
221231
float readFloatAltitudeMeters( void );
222232
float readFloatAltitudeFeet( void );
233+
void readFloatPressureFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements);
223234

224235
float readFloatHumidity( void );
236+
void readFloatHumidityFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements);
225237

226238
//Temperature related methods
227239
void setTemperatureCorrection(float corr);
228240
float readTempC( void );
229241
float readTempF( void );
242+
float readTempFromBurst(uint8_t buffer[]);
230243

231244
//Dewpoint related methods
232245
//From Pavel-Sayekat: https://github.com/sparkfun/SparkFun_BME280_Breakout_Board/pull/6/files
@@ -248,6 +261,8 @@ class BME280
248261

249262
private:
250263
uint8_t checkSampleValue(uint8_t userValue); //Checks for valid over sample values
264+
void readTempCFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements);
265+
void readTempFFromBurst(uint8_t buffer[], BME280_SensorMeasurements *measurements);
251266

252267
uint8_t _wireType = HARD_WIRE; //Default to Wire.h
253268
TwoWire *_hardPort = NO_WIRE; //The generic connection to user's chosen I2C hardware

0 commit comments

Comments
 (0)