Connecting BMP280 Barometric Pressure Sensor to Orange Pi, Banana Pi, Raspberry Pi

 

Connecting BMP280 to Orange Pi, Banana Pi, Raspberry Pi - BMP280You can connect the BMP280 atmospheric pressure sensor to the Orange Pi PC using both I2C and SPI, since Orange Pi PC has several of them. Also, to work with GPIO, you need to install WiringOP if you work with Orange Pi, and if you have Banana Pi - BPI-WiringPi .

Barometer on BMP280

The BMP280 is an atmospheric pressure sensor from BOSCH Sensortec and is an improved version of the BMP180 sensor It differs from it in smaller dimensions (2 x 2.5 x 0.95 mm), lower power consumption, high operating accuracy and the presence of accurate factory calibration and two serial interfaces: I2C and SPI.
The logic of the BMP280 sensor remains the same, but has undergone some long-awaited improvements.

The table shows the improvements that the BMP280 sensor has undergone:

ParameterBMP180BMP280
Dimensions (edit)3.6 x 3.8 mm2.0 x 2.5 mm
Min VDD1.80 V1.71 V
Min VDDIO1.62 V1.20 V
Current consumption @ 3 Pa RMS noise12 μA2.7 μA
RMS Noise3 Pa1.3 Pa
Pressure resolution1 Pa0.16 Pa
Temperature resolution0.1°C0.01°C
InterfacesI²CI²C & SPI (3 and 4 communication lines,
mode '00' and '11')
Measurement modesP or T only, forcedP and T, forced or intermittent
Measurement frequencyup to 120 Hzup to 157 Hz
Filter optionsNotFive filtering options

Operating modes


The sensor differs from previous models (BMP085 and BMP180) in three modes of operation:

  1. SLEEP - low power consumption mode
  2. FORCED - a mode similar to that of BMP085 and BMP180 sensors. At the command of the controller, the sensor exits the sleep mode, takes measurements, outputs the measurement results to the controller and goes into a low power consumption mode
  3. NORMAL is a mode unique to this sensor. The sensor wakes up on its own, measures pressure and temperature, and falls asleep. All time parameters of this mode are programmable independently. You can read data in this mode at any time.

Filtering measurement results

The sensor provides for filtering the measurement results with the setting of the following filtering parameters:

  1. OVERSAMPLING for temperature (16, 17, 18, 19, 20 bit)
  2. OVERSAMPLING for pressure (16, 17, 18, 19, 20 bit)
  3. TSB - time between measurements (0.5, 62.5, 125, 250, 500, 1000, 2000, 4000 ms)
  4. FILTER_COEFFICIENT - filtration coefficient

Specifications:

  • Supply voltage: 1.71 V to 3.6 V
  • Max speed of I2C interface: 3.4 MHz
  • Current consumption: 2.7 μA @ 1 Hz sampling rate
  • Interface: I2C, SPI (4 Wires), SPI (3 Wires)
  • Calibration: Factory
  • Noise level: up to 0.2 Pa (1.7 cm) and 0.01 temperature
  • Measured pressure range: from 300 hPa to 1100 hPa (9000 m to -500 m)
  • Size: 2.5 mm x 2.0 mm x 0.95 mm

BMP280 library

BMP280RawData.h

#include <stdint.h>

class BMP280RawData {
private:
uint8_t pmsb;
uint8_t plsb;
uint8_t pxsb;

uint8_t tmsb;
uint8_t tlsb;
uint8_t txsb;


uint32_t temperature;
uint32_t pressure;
public:

BMP280RawData(
uint8_t pmsb, uint8_t plsb, uint8_t pxsb,
uint8_t tmsb, uint8_t tlsb, uint8_t txsb,
uint32_t temperature, uint32_t pressure) {
this->pmsb = pmsb;
this->plsb = plsb;
this->pxsb = pxsb;
this->tmsb = tmsb;
this->tlsb = tlsb;
this->txsb = txsb;
this->temperature = temperature;
this->pressure = pressure;
}

BMP280RawData() {
this->pmsb = 0;
this->plsb = 0;
this->pxsb = 0;
this->tmsb = 0;
this->tlsb = 0;
this->txsb = 0;
this->temperature = 0;
this->pressure = 0;
}

virtual ~BMP280RawData() {
}


void setPlsb(uint8_t plsb) {
this->plsb = plsb;
}


void setPmsb(uint8_t pmsb) {
this->pmsb = pmsb;
}


void setPressure(uint32_t pressure) {
this->pressure = pressure;
}


void setPxsb(uint8_t pxsb) {
this->pxsb = pxsb;
}


void setTemperature(uint32_t temperature) {
this->temperature = temperature;
}


void setTlsb(uint8_t tlsb) {
this->tlsb = tlsb;
}


void setTmsb(uint8_t tmsb) {
this->tmsb = tmsb;
}


void setTxsb(uint8_t txsb) {
this->txsb = txsb;
}


uint8_t getPlsb() {

return plsb;
}


uint8_t getPmsb() {

return pmsb;
}


uint32_t getPressure() {
return pressure;
}


uint8_t getPxsb() {
return pxsb;
}


uint32_t getTemperature() {
return temperature;
}

uint8_t getTlsb() {
return tlsb;
}


uint8_t getTmsb() {
return tmsb;
}


uint8_t getTxsb() {
return txsb;
}

};

BMP280CalibrationData.h

#include <stdint.h>

class BMP280CalibrationData {
private:
uint16_t T1;

int16_t T2;
int16_t T3;

uint16_t P1;

int16_t P2;
int16_t P3;
int16_t P4;
int16_t P5;
int16_t P6;
int16_t P7;
int16_t P8;
int16_t P9;

public:

BMP280CalibrationData() {
T1 = 0;

T2 = 0;
T3 = 0;

P1 = 0;
P2 = 0;
P3 = 0;
P4 = 0;
p5 = 0;

P6 = 0;

P7 = 0;
P8 = 0;

P9 = 0;

}


BMP280CalibrationData(
uint16_t T1, int16_t T2, int16_t T3,

uint16_t P1, int16_t P2, int16_t P3,
int16_t P4, int16_t P5, int16_t P6,
int16_t P7, int16_t P8, int16_t P9) {
this->P1 = P1;
this->P2 = P2;
this->P3 = P3;
this->P4 = P4;
this->P5 = P5;
this->P6 = P6;
this->P7 = P7;
this->P8 = P8;
this->P9 = P9;
this->T1 = T1;
this->T2 = T2;
this->T3 = T3;
}

virtual ~BMP280CalibrationData() {
}


void setP1(uint16_t P1) {
this->P1 = P1;
}


void setP2(int16_t P2) {
this->P2 = P2;
}


void setP3(int16_t P3) {
this->P3 = P3;

}


void setP4(int16_t P4) {
this->P4 = P4;

}


void setP5(int16_t P5) {
this->P5 = P5;

}


void setP6(int16_t P6) {
this->P6 = P6;

}


void setP7(int16_t P7) {
this->P7 = P7;

}


void setP8(int16_t P8) {
this->P8 = P8;

}


void setP9(int16_t P9) {
this->P9 = P9;

}


void setT1(uint16_t T1) {
this->T1 = T1;

}


void setT2(int16_t T2) {
this->T2 = T2;

}


void setT3(int16_t T3) {
this->T3 = T3;

}


uint16_t getP1() {

return P1;
}


int16_t getP2() {
return P2;
}


int16_t getP3() {
return P3;
}


int16_t getP4() {

return P4;
}


int16_t getP5() {

return P5;
}


int16_t getP6() {

return P6;
}


int16_t getP7() {

return P7;
}

int16_t getP8() {

return P8;
}


int16_t getP9() {
return P9;
}


uint16_t getT1() {
return T1;
}


int16_t getT2() {
return T2;
}


int16_t getT3() {
return T3;
}

};

BMP280Data.h

class BMP280Data {
private:
double pressure; // hPa
double temperature; // m
double altitude; // °C
public:

BMP280Data() {
pressure = 0;
temperature = 0;
altitude = 0;
}


BMP280Data(double pressure, double temperature, double altitude) {
this->pressure = pressure;
this->temperature = temperature;
this->altitude = altitude;
}


virtual ~BMP280Data() {
}


void setAltitude(double altitude) {
this->altitude = altitude;

}


void setPressure(double pressure) {
this->pressure = pressure;

}


void setTemperature(double temperature) {
this->temperature = temperature;

}


double getAltitude() {
return altitude;
}


double getPressure() {
return pressure;
}


double getTemperature() {
return temperature;
}
};

bmp280.h

#include <stdint.h>
#include "BMP280CalibrationData.h"
#include "BMP280RawData.h"
#include "BMP280Data.h"

#define MEAN_SEA_LEVEL_PRESSURE 1013

/**\name CHIP ID DEFINITION */
/***********************************************/
#define BMP280_CHIP_ID1 (0x56)
#define BMP280_CHIP_ID2 (0x57)
#define BMP280_CHIP_ID3 (0x58)
/************************************************/
/**\name I2C ADDRESS DEFINITION */
/***********************************************/

#define BMP280_I2C_ADDRESS1 (0x76)
#define BMP280_I2C_ADDRESS2 (0x77)
/************************************************/

/**\name POWER MODE DEFINITION */
/***********************************************/

/* Sensor Specific constants */
#define BMP280_SLEEP_MODE (0x00)
#define BMP280_FORCED_MODE (0x01)
#define BMP280_NORMAL_MODE (0x03)
#define BMP280_SOFT_RESET_CODE (0xB6)
/************************************************/
/**\name STANDBY TIME DEFINITION */
/***********************************************/
#define BMP280_STANDBY_TIME_1_MS (0x00)
#define BMP280_STANDBY_TIME_63_MS (0x01)
#define BMP280_STANDBY_TIME_125_MS (0x02)
#define BMP280_STANDBY_TIME_250_MS (0x03)
#define BMP280_STANDBY_TIME_500_MS (0x04)
#define BMP280_STANDBY_TIME_1000_MS (0x05)
#define BMP280_STANDBY_TIME_2000_MS (0x06)
#define BMP280_STANDBY_TIME_4000_MS (0x07)
/************************************************/

/**\name OVERSAMPLING DEFINITION */
/***********************************************/

#define BMP280_OVERSAMP_SKIPPED (0x00)
#define BMP280_OVERSAMP_1X (0x01)
#define BMP280_OVERSAMP_2X (0x02)
#define BMP280_OVERSAMP_4X (0x03)
#define BMP280_OVERSAMP_8X (0x04)
#define BMP280_OVERSAMP_16X (0x05)
/************************************************/
/**\name WORKING MODE DEFINITION */
/***********************************************/
#define BMP280_ULTRA_LOW_POWER_MODE (0x00)
#define BMP280_LOW_POWER_MODE (0x01)
#define BMP280_STANDARD_RESOLUTION_MODE (0x02)
#define BMP280_HIGH_RESOLUTION_MODE (0x03)
#define BMP280_ULTRA_HIGH_RESOLUTION_MODE (0x04)

#define BMP280_ULTRALOWPOWER_OVERSAMP_PRESSURE BMP280_OVERSAMP_1X
#define BMP280_ULTRALOWPOWER_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X

#define BMP280_LOWPOWER_OVERSAMP_PRESSURE BMP280_OVERSAMP_2X
#define BMP280_LOWPOWER_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X

#define BMP280_STANDARDRESOLUTION_OVERSAMP_PRESSURE BMP280_OVERSAMP_4X
#define BMP280_STANDARDRESOLUTION_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X

#define BMP280_HIGHRESOLUTION_OVERSAMP_PRESSURE BMP280_OVERSAMP_8X
#define BMP280_HIGHRESOLUTION_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X

#define BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_PRESSURE BMP280_OVERSAMP_16X
#define BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_2X
/************************************************/
/**\name FILTER DEFINITION */
/***********************************************/
#define BMP280_FILTER_COEFF_OFF (0x00)
#define BMP280_FILTER_COEFF_2 (0x01)
#define BMP280_FILTER_COEFF_4 (0x02)
#define BMP280_FILTER_COEFF_8 (0x03)
#define BMP280_FILTER_COEFF_16 (0x04)
/************************************************/


/*
* REGISTERS
*/
enum {
BMP280_REGISTER_DIG_T1 = 0x88,
BMP280_REGISTER_DIG_T2 = 0x8A,
BMP280_REGISTER_DIG_T3 = 0x8C,

BMP280_REGISTER_DIG_P1 = 0x8E,
BMP280_REGISTER_DIG_P2 = 0x90,
BMP280_REGISTER_DIG_P3 = 0x92,
BMP280_REGISTER_DIG_P4 = 0x94,
BMP280_REGISTER_DIG_P5 = 0x96,
BMP280_REGISTER_DIG_P6 = 0x98,
BMP280_REGISTER_DIG_P7 = 0x9A,
BMP280_REGISTER_DIG_P8 = 0x9C,
BMP280_REGISTER_DIG_P9 = 0x9E,

BMP280_REGISTER_CHIPID = 0xD0,
BMP280_REGISTER_VERSION = 0xD1,
BMP280_REGISTER_SOFTRESET = 0xE0,

BMP280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0

BMP280_REGISTER_STATUS = 0xF3,
BMP280_REGISTER_CONTROL = 0xF4,
BMP280_REGISTER_CONFIG = 0xF5,
BMP280_REGISTER_PRESSUREDATA_MSB = 0xF7,
BMP280_REGISTER_PRESSUREDATA_LSB = 0xF8,
BMP280_REGISTER_PRESSUREDATA_XLSB = 0xF9,
BMP280_REGISTER_TEMPDATA_MSB = 0xFA,
BMP280_REGISTER_TEMPDATA_LSB = 0xFB,
BMP280_REGISTER_TEMPDATA_XLSB = 0xFC
};

class BMP280 {
private:
char * device;
int devId;
int fd;

uint8_t chipId;
BMP280CalibrationData * bmp280CalibrationData;
BMP280RawData * bmp280RawData;

void write8(uint8_t, uint8_t);
uint8_t read8(uint8_t);
uint16_t read16(uint8_t);
int16_t readS16(uint8_t);
uint16_t readU16(uint8_t);

int32_t getTemperatureC(int32_t adc_T);
double getAltitude(double pressure);
double compensateT(int32_t t_fine);
double compensateP(int32_t adc_P, int32_t t_fine);
BMP280CalibrationData * getCalibrationData();
BMP280RawData * getRawData ();


public:
BMP280(int);
BMP280(char *, int);
virtual ~BMP280();

BMP280CalibrationData * getBmp280CalibrationData();
BMP280Data * getBMP280Data();

int init();
void reset();
void spi3wEnable();
void spi3wDisable();
void setPowerMode(uint8_t);
void setTemperatureOversampling(uint8_t);
void setPressureOversampling(uint8_t);
void setStandbyTime(uint8_t);
void setIrrFilter(uint8_t);

uint8_t getPowerMode();

uint8_t getPressureOversampling();

uint8_t getTemperatureOversampling();

uint8_t getIrrFilter();

uint8_t getStandbyTime();
uint8_t getSpi3w();
uint8_t getMeasuringStatus();
uint8_t getImUpdateStatus();
uint8_t getConfig();
uint8_t getStatus();
uint8_t getControl();
uint8_t getChipId();
uint8_t getChipVersion();

void setReset(uint8_t);
void setConfig(uint8_t);
void setStatus(uint8_t);
void setControl(uint8_t);
void setDevice(char *);
};

bmp280.cpp

#include <string.h>
#include <stdint.h>
#include <stdexcept>
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <wiringPiI2C.h>
#include <wiringPi.h>
#include "bmp280.h"

BMP280::BMP280(char * device, int devId) : fd(0), chipId(0), bmp280CalibrationData(0), bmp280RawData(0) {
setDevice(device);
this->devId = devId;
}

BMP280::BMP280(int devId) : device(0), fd(0), chipId(0), bmp280CalibrationData(0), bmp280RawData(0) {
this->devId = devId;

}


BMP280::~BMP280() {
delete bmp280CalibrationData;
delete bmp280RawData;
delete[] device;
}


int BMP280::init() {
int fd = -1;

if (device) {
fd = wiringPiI2CSetupInterface(device, devId);
} else {
int rev = piBoardRev();

if (rev == 1) {
setDevice("/dev/i2c-0");
} else if (rev == 2) {
setDevice("/dev/i2c-1");
} else if (rev == 3) {
setDevice("/dev/i2c-2");
} else {
setDevice("/dev/i2c-3");
}

fd = wiringPiI2CSetupInterface(device, devId);
}
if (fd < 0) {
char buffer[256];
sprintf(buffer, "Device not found: I2C device: %s, device ID: %d", device, devId);
throw std::logic_error(buffer);
}

this->fd = fd;

uint8_t chipId = getChipId();
switch (chipId) {
case BMP280_CHIP_ID1:
case BMP280_CHIP_ID2:
case BMP280_CHIP_ID3:
this->chipId = chipId;
break;
default:
{
char buffer[256];
sprintf(buffer, "Device Chip ID error: chip ID = %d", chipId);
throw std::logic_error(buffer);
}

}

if (bmp280CalibrationData) {
delete bmp280CalibrationData;
}

bmp280CalibrationData = getCalibrationData();
return fd;
}

BMP280CalibrationData * BMP280::getCalibrationData() {
uint16_t T1, P1;

int16_t T2, T3, P2, P3, P4, P5, P6, P7, P8, P9;

T1 = readU16(BMP280_REGISTER_DIG_T1);
T2 = readS16(BMP280_REGISTER_DIG_T2);
T3 = readS16(BMP280_REGISTER_DIG_T3);
P1 = readU16(BMP280_REGISTER_DIG_P1);
P2 = readS16(BMP280_REGISTER_DIG_P2);
P3 = readS16(BMP280_REGISTER_DIG_P3);
P4 = readS16(BMP280_REGISTER_DIG_P4);
P5 = readS16(BMP280_REGISTER_DIG_P5);
P6 = readS16(BMP280_REGISTER_DIG_P6);
P7 = readS16(BMP280_REGISTER_DIG_P7);
P8 = readS16(BMP280_REGISTER_DIG_P8);
P9 = readS16(BMP280_REGISTER_DIG_P9);

return new BMP280CalibrationData(T1, T2, T3, P1, P2, P3, P4, P5, P6, P7, P8, P9);
}


BMP280CalibrationData * BMP280::getBmp280CalibrationData() {
return bmp280CalibrationData;
}

BMP280RawData * BMP280::getRawData() {
uint8_t pmsb, plsb, pxsb;
uint8_t tmsb, tlsb, txsb;
uint32_t temperature, pressure;

plsb = read8(BMP280_REGISTER_PRESSUREDATA_LSB);
pmsb = read8(BMP280_REGISTER_PRESSUREDATA_MSB);
pxsb = read8(BMP280_REGISTER_PRESSUREDATA_XLSB);

tmsb = read8(BMP280_REGISTER_TEMPDATA_MSB);
tlsb = read8(BMP280_REGISTER_TEMPDATA_LSB);
txsb = read8(BMP280_REGISTER_TEMPDATA_XLSB);

temperature = 0;
temperature = (temperature | tmsb) << 8;
temperature = (temperature | tlsb) << 8;
temperature = (temperature | txsb) >> 4;

pressure = 0;
pressure = (pressure | pmsb) << 8;
pressure = (pressure | plsb) << 8;
pressure = (pressure | pxsb) >> 4;

return new BMP280RawData(pmsb, plsb, pxsb, tmsb, tlsb, txsb, temperature, pressure);
}

void BMP280::reset() {
setReset(BMP280_SOFT_RESET_CODE);
}


void BMP280::spi3wEnable() {
uint8_t config = getConfig();
setConfig(config | 0b00000001);
}


void BMP280::spi3wDisable() {
uint8_t config = getConfig();

setConfig(config & 0b11111110);
}


void BMP280::setPowerMode(uint8_t mode) {
switch (mode) {
case BMP280_FORCED_MODE:
case BMP280_NORMAL_MODE:
case BMP280_SLEEP_MODE:
{
uint8_t curentMode = getControl() & 0b11111100;
setControl (currentMode | mode);

break;
}
default:break;
}
}


void BMP280::setTemperatureOversampling(uint8_t oversampling) {
switch (oversampling) {
case BMP280_OVERSAMP_SKIPPED:
case BMP280_OVERSAMP_1X:
case BMP280_OVERSAMP_2X:
case BMP280_OVERSAMP_4X:
case BMP280_OVERSAMP_8X:
case BMP280_OVERSAMP_16X:
{
uint8_t curentOversampling = getControl() & 0b00011111;
setControl(curentOversampling | (oversampling << 5));
break;
}
default:break;
}
}

void BMP280::setPressureOversampling(uint8_t oversampling) {
switch (oversampling) {
case BMP280_OVERSAMP_SKIPPED:
case BMP280_OVERSAMP_1X:
case BMP280_OVERSAMP_2X:
case BMP280_OVERSAMP_4X:

case BMP280_OVERSAMP_8X:

case BMP280_OVERSAMP_16X:

{

uint8_t curentOversampling = getControl() & 0b11100011;
setControl(curentOversampling | (oversampling << 2));
break;

}

default:break;

}

}


void BMP280::setStandbyTime(uint8_t tStandby) {
switch (tStandby) {
case BMP280_STANDBY_TIME_1_MS:
case BMP280_STANDBY_TIME_63_MS:
case BMP280_STANDBY_TIME_125_MS:
case BMP280_STANDBY_TIME_250_MS:
case BMP280_STANDBY_TIME_500_MS:
case BMP280_STANDBY_TIME_1000_MS:
case BMP280_STANDBY_TIME_2000_MS:
case BMP280_STANDBY_TIME_4000_MS:
{
uint8_t config = getConfig() & 0b00011111;
setConfig(config | (tStandby << 5));
break;
}
default:break;
}
}

void BMP280::setIrrFilter(uint8_t irrFilter) {
switch (irrFilter) {
case BMP280_FILTER_COEFF_OFF:
case BMP280_FILTER_COEFF_2:
case BMP280_FILTER_COEFF_4:
case BMP280_FILTER_COEFF_8:
case BMP280_FILTER_COEFF_16:
{

uint8_t config = getConfig() & 0b11100011;
setConfig(config | (irrFilter << 2));
break;

}

default:break;

}

}


uint8_t BMP280::getPowerMode() {

return getControl() & 0b00000011;
}


uint8_t BMP280::getPressureOversampling() {

return (getControl() & 0b00011100) >> 2;
}

uint8_t BMP280::getTemperatureOversampling() {

return (getControl() & 0b11100000) >> 5;
}


uint8_t BMP280::getIrrFilter() {

return (getConfig() & 0b00011100) >> 2;
}


uint8_t BMP280::getStandbyTime() {
return (getConfig() & 0b11100000) >> 5;
}


uint8_t BMP280::getSpi3w() {
return (getConfig() & 0b00000001);
}


uint8_t BMP280::getMeasuringStatus() {
return (getStatus() >> 3) & 0b00000001;
}


uint8_t BMP280::getImUpdateStatus() {
return getStatus() & 0b00000001;
}


uint8_t BMP280::getConfig() {
return read8(BMP280_REGISTER_CONFIG);
}


uint8_t BMP280::getStatus() {
return read8(BMP280_REGISTER_STATUS);
}


uint8_t BMP280::getControl() {
return read8(BMP280_REGISTER_CONTROL);
}


uint8_t BMP280::getChipId() {
return read8(BMP280_REGISTER_CHIPID);
}

uint8_t BMP280::getChipVersion() {
return read8(BMP280_REGISTER_VERSION);
}


void BMP280::setReset(uint8_t value) {
write8(BMP280_REGISTER_SOFTRESET, value);
}


void BMP280::setConfig(uint8_t value) {
return write8(BMP280_REGISTER_CONFIG, value);
}


void BMP280::setStatus(uint8_t value) {
return write8(BMP280_REGISTER_STATUS, value);
}


void BMP280::setControl(uint8_t value) {
return write8(BMP280_REGISTER_CONTROL, value);
}


double BMP280::getAltitude(double pressure) {
return 44330.0 * (1.0 - pow(pressure / MEAN_SEA_LEVEL_PRESSURE, 0.190294957));
}


int32_t BMP280::getTemperatureC(int32_t adc_T) {
int32_t var1 = ((((adc_T >> 3) - ((int32_t) bmp280CalibrationData->getT1() << 1))) *
((int32_t) bmp280CalibrationData->getT2())) >> 11;

int32_t var2 = (((((adc_T >> 4) - ((int32_t) bmp280CalibrationData->getT1())) *
((adc_T >> 4) - ((int32_t) bmp280CalibrationData->getT1()))) >> 12) *
((int32_t) bmp280CalibrationData->getT3())) >> 14;

return var1 + var2;
}

double BMP280::compensateT(int32_t t_fine) {
double T = (t_fine * 5 + 128) >> 8;
return T / 100;
}


double BMP280::compensateP(int32_t adc_P, int32_t t_fine) {
int64_t var1, var2, p;

var1 = ((int64_t) t_fine) - 128000;
var2 = var1 * var1 * (int64_t) bmp280CalibrationData->getP6();
var2 = var2 + ((var1 * (int64_t) bmp280CalibrationData->getP5()) << 17);
var2 = var2 + (((int64_t) bmp280CalibrationData->getP4()) << 35);
var1 = ((var1 * var1 * (int64_t) bmp280CalibrationData->getP3()) >> 8) +
((var1 * (int64_t) bmp280CalibrationData->getP2()) << 12);
var1 = (((((int64_t) 1) << 47) + var1))*((int64_t) bmp280CalibrationData->getP1()) >> 33;

if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - adc_P;
p = (((p << 31) - var2)*3125) / var1;
var1 = (((int64_t) bmp280CalibrationData->getP9()) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t) bmp280CalibrationData->getP8()) * p) >> 19;

p = ((p + var1 + var2) >> 8) + (((int64_t) bmp280CalibrationData->getP7()) << 4);
return (double) p / 256;
}

BMP280Data * BMP280::getBMP280Data() {
int32_t t_fine;
double t, p, a;
while (getMeasuringStatus()) {
}
if (bmp280RawData) {
delete bmp280RawData;
}

bmp280RawData = getRawData ();

t_fine = getTemperatureC(bmp280RawData->getTemperature());
t = compensateT(t_fine); // C
p = compensateP(bmp280RawData->getPressure(), t_fine) / 100; // hPa
a = getAltitude(p); // meters

return new BMP280Data(p, t, a);
}

void BMP280::setDevice(char * device) {
if (device) {
this->device = new char[strlen(device)];
strcpy(this->device, device);
}

}


void BMP280::write8(uint8_t reg, uint8_t value) {
wiringPiI2CWriteReg8(fd, reg, value);
}


uint8_t BMP280::read8(uint8_t reg) {
return wiringPiI2CReadReg8(fd, reg);
}


uint16_t BMP280::read16(uint8_t reg) {
return wiringPiI2CReadReg16(fd, reg);
}


int16_t BMP280::readS16(uint8_t reg) {
return (int16_t) read16(reg);
}


uint16_t BMP280::readU16(uint8_t reg) {
return (uint16_t) read16(reg);
}

Connection diagram BMP280 to Orange Pi

Connecting BMP280 to Orange Pi, Banana Pi, Raspberry Pi - GPIO40I work with these sensors only on I2C. Connecting BMP280 to Orange Pi is very simple: we give 3.3 V, GND, SCL and SDA to Vcc.

The operating voltage of the sensor is from 1.71 V to 3.6 V. It is not necessary to supply from 5 V, as the probability that it will fail is very high.

Below is an example program to test the above library.

This program creates a new object for working with the sensor:

BMP280 * bmp280 = new BMP280(device, devId);

connects to the sensor:

int fd = bmp280->init();

and resets all its settings:


bmp280->reset();

then sets new settings (operating mode, filters, etc.):

bmp280->setPowerMode(BMP280_NORMAL_MODE);
bmp280->setTemperatureOversampling(BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_TEMPERATURE);
bmp280->setPressureOversampling(BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_PRESSURE);
bmp280->setIrrFilter(BMP280_FILTER_COEFF_16);
bmp280->setStandbyTime(BMP280_STANDBY_TIME_250_MS);

and once a second reads and displays data from the BMP280:

while (1) {
delay(1000);
BMP280Data * bmp280Data = bmp280->getBMP280Data();
printf("pressure : %.2f hPa\n", bmp280Data->getPressure());
printf("temperature: %.2f °C\n", bmp280Data->getTemperature());
printf("altitude : %.2f m\n\n", bmp280Data->getAltitude());
delete bmp280Data;
}

main.cpp

#include <stdio.h>
#include <iostream>
#include <stdexcept>
#include <wiringPi.h>
#include "bmp280.h"

int main(int argc, char **argv) {
// char * device = "/dev/i2c-0";
// char * device = "/dev/i2c-1";
char * device = "/dev/i2c-2";
// char * device = "/dev/i2c-3";
int devId = BMP280_I2C_ADDRESS1;

try {
BMP280 * bmp280 = new BMP280(device, devId);
int fd = bmp280->init();
if (fd < 0) {
printf("Device not found");
return -1;
}

printf("fd : 0x%02x\n", fd);
printf("chip id : 0x%02x\n", bmp280->getChipId());
printf("chip ver : 0x%02x\n", bmp280->getChipVersion());

bmp280->reset();
bmp280->setPowerMode(BMP280_NORMAL_MODE);
bmp280->setTemperatureOversampling(BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_TEMPERATURE);
bmp280->setPressureOversampling(BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_PRESSURE);
bmp280->setIrrFilter(BMP280_FILTER_COEFF_16);
bmp280->setStandbyTime(BMP280_STANDBY_TIME_250_MS);

printf("---------------\n");
printf("pw mode : 0x%02x\n", bmp280->getPowerMode());
printf("osrs_p : 0x%02x\n", bmp280->getPressureOversampling());
printf("osrs_t : 0x%02x\n", bmp280->getTemperatureOversampling());
printf("---------------\n");

printf("filter : 0x%02x\n", bmp280->getIrrFilter());
printf("t_sb : 0x%02x\n", bmp280->getStandbyTime());
printf("---------------\n");

printf("spi3w sts: 0x%02x\n", bmp280->getSpi3w());
printf("measuring: 0x%02x\n", bmp280->getMeasuringStatus());
printf("im_update: 0x%02x\n", bmp280->getImUpdateStatus());
printf("---------------\n");


while (1) {
delay(1000);
BMP280Data * bmp280Data = bmp280->getBMP280Data();
printf("pressure : %.2f hPa\n", bmp280Data->getPressure());
printf("temperature: %.2f °C\n", bmp280Data->getTemperature());
printf("altitude : %.2f m\n\n", bmp280Data->getAltitude());
delete bmp280Data;
}
delete bmp280;
} catch (std::exception & e) {
printf("%s\n", e.what());
}
return 0;
}

Result

Connecting BMP280 to Orange Pi, Banana Pi, Raspberry Pi - Result

Previous Post Next Post

Contact Form