BME280 представляет собой интегрированный датчик окружающей среды, разработанный специально для мобильных устройств, где размер и низкое энергопотребление являются ключевыми.
Датчик BME280 очень похож с BMP280, различие в том, что BME280 имеет датчик влажности от чего его корпус шире чем у BMP280. Количество выводов и их расположение на корпусах совпадают. Более детальное описание датчика вы можете найти на странице BME280 — датчик давления, температуры и влажности.
Подключить датчик окружающей среды BME280 к Orange Pi PC можно по I2C и по SPI, их несколько как у Orange Pi, так и у Banana Pi и Raspberry Pi. Также для работы с GPIO необходимо установить WiringOP, если вы работаете с Orange Pi, а если у вас Banana Pi — BPI-WiringPi.
Схема подключения BME280 к Orange Pi/Banana Pi/Raspberry Pi
С этим датчиком я работаю только по I2C. Подключается BME280 к Orange Pi также, как к Banana Pi и Raspberry Pi, у всех GPIO (на 40 пинов) похожие. В данном случае я использовал порт /dev/i2c-2, потому что удобно расположен.
Код программы
Проект написан на С/С++. Использую среду разработки CodeLite IDE, так как среда Code::Blocks у меня не работает нормально.
BME280RawData.h
#include <stdint.h>
class BME280RawData {
private:
uint8_t pmsb;
uint8_t plsb;
uint8_t pxsb;
uint8_t tmsb;
uint8_t tlsb;
uint8_t txsb;
uint8_t hmsb;
uint8_t hlsb;
uint32_t temperature;
uint32_t pressure;
uint32_t humidity;
public:
BME280RawData(uint8_t pmsb, uint8_t plsb, uint8_t pxsb, uint8_t tmsb, uint8_t tlsb, uint8_t txsb, uint8_t hmsb, uint8_t hlsb, uint32_t temperature, uint32_t pressure,
uint32_t humidity) {
this->pmsb = pmsb;
this->plsb = plsb;
this->pxsb = pxsb;
this->tmsb = tmsb;
this->tlsb = tlsb;
this->txsb = txsb;
this->hmsb = hmsb;
this->hlsb = hlsb;
this->temperature = temperature;
this->pressure = pressure;
this->humidity = humidity;
}
BME280RawData() {
this->pmsb = 0;
this->plsb = 0;
this->pxsb = 0;
this->tmsb = 0;
this->tlsb = 0;
this->txsb = 0;
this->hmsb = 0;
this->hlsb = 0;
this->temperature = 0;
this->pressure = 0;
this->humidity = 0;
}
virtual ~BME280RawData() {
}
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;
}
void setHlsb(uint8_t hlsb) {
this->hlsb = hlsb;
}
void setHmsb(uint8_t hmsb) {
this->hmsb = hmsb;
}
void setHumidity(uint32_t humidity) {
this->humidity = humidity;
}
uint8_t getHlsb() {
return hlsb;
}
uint8_t getHmsb() {
return hmsb;
}
uint32_t getHumidity() {
return humidity;
}
};
BME280CalibrationData.h
#include <stdint.h>
class BME280CalibrationData {
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;
uint8_t H1;
int16_t H2;
uint8_t H3;
int16_t H4;
int16_t H5;
int8_t H6;
public:
BME280CalibrationData() {
T1 = 0;
T2 = 0;
T3 = 0;
P1 = 0;
P2 = 0;
P3 = 0;
P4 = 0;
P5 = 0;
P6 = 0;
P7 = 0;
P8 = 0;
P9 = 0;
H1 = 0;
H2 = 0;
H3 = 0;
H4 = 0;
H5 = 0;
H6 = 0;
}
BME280CalibrationData(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,
uint8_t H1, int16_t H2, uint8_t H3, int16_t H4, int16_t H5, int8_t H6) {
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;
this->H1 = H1;
this->H2 = H2;
this->H3 = H3;
this->H4 = H4;
this->H5 = H5;
this->H6 = H6;
}
virtual ~BME280CalibrationData() {
}
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;
}
void setH1(uint8_t H1) {
this->H1 = H1;
}
void setH2(int16_t H2) {
this->H2 = H2;
}
void setH3(uint8_t H3) {
this->H3 = H3;
}
void setH4(int16_t H4) {
this->H4 = H4;
}
void setH5(int16_t H5) {
this->H5 = H5;
}
void setH6(int8_t H6) {
this->H6 = H6;
}
uint8_t getH1() {
return H1;
}
int16_t getH2() {
return H2;
}
uint8_t getH3() {
return H3;
}
int16_t getH4() {
return H4;
}
int16_t getH5() {
return H5;
}
int8_t getH6() {
return H6;
}
};
BME280Data.h
class BMP280Data {
private:
double pressure; // hPa
double temperature; // m
double humidity; // %
double altitude; // °C
public:
BMP280Data() {
pressure = 0;
temperature = 0;
altitude = 0;
humidity = 0;
}
BMP280Data(double pressure, double temperature, double humidity, double altitude) {
this->pressure = pressure;
this->temperature = temperature;
this->humidity = humidity;
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;
}
void setHumidity(double humidity) {
this->humidity = humidity;
}
double getHumidity() {
return humidity;
}
};
bme280.h
#include <stdint.h>
#include "BME280CalibrationData.h"
#include "BME280RawData.h"
#include "BME280Data.h"
#define MEAN_SEA_LEVEL_PRESSURE 1013
/**\name CHIP ID DEFINITION */
/***********************************************/
#define BME280_CHIP_ID1 (0x60)
/************************************************/
/**\name I2C ADDRESS DEFINITION */
/***********************************************/
#define BME280_I2C_ADDRESS1 (0x76)
#define BME280_I2C_ADDRESS2 (0x77)
/************************************************/
/**\name POWER MODE DEFINITION */
/***********************************************/
/* Sensor Specific constants */
#define BME280_SLEEP_MODE (0x00)
#define BME280_FORCED_MODE (0x01)
#define BME280_NORMAL_MODE (0x03)
#define BME280_SOFT_RESET_CODE (0xB6)
/************************************************/
/**\name STANDBY TIME DEFINITION */
/***********************************************/
#define BME280_STANDBY_TIME_1_MS (0x00)
#define BME280_STANDBY_TIME_63_MS (0x01)
#define BME280_STANDBY_TIME_125_MS (0x02)
#define BME280_STANDBY_TIME_250_MS (0x03)
#define BME280_STANDBY_TIME_500_MS (0x04)
#define BME280_STANDBY_TIME_1000_MS (0x05)
#define BME280_STANDBY_TIME_2000_MS (0x06)
#define BME280_STANDBY_TIME_4000_MS (0x07)
/************************************************/
/**\name OVERSAMPLING DEFINITION */
/***********************************************/
#define BME280_OVERSAMP_SKIPPED (0x00)
#define BME280_OVERSAMP_1X (0x01)
#define BME280_OVERSAMP_2X (0x02)
#define BME280_OVERSAMP_4X (0x03)
#define BME280_OVERSAMP_8X (0x04)
#define BME280_OVERSAMP_16X (0x05)
/************************************************/
/**\name WORKING MODE DEFINITION */
/***********************************************/
#define BME280_ULTRA_LOW_POWER_MODE (0x00)
#define BME280_LOW_POWER_MODE (0x01)
#define BME280_STANDARD_RESOLUTION_MODE (0x02)
#define BME280_HIGH_RESOLUTION_MODE (0x03)
#define BME280_ULTRA_HIGH_RESOLUTION_MODE (0x04)
#define BME280_ULTRALOWPOWER_OVERSAMP_PRESSURE BME280_OVERSAMP_1X
#define BME280_ULTRALOWPOWER_OVERSAMP_HUMIDITY BME280_OVERSAMP_1X
#define BME280_ULTRALOWPOWER_OVERSAMP_TEMPERATURE BME280_OVERSAMP_1X
#define BME280_LOWPOWER_OVERSAMP_PRESSURE BME280_OVERSAMP_2X
#define BME280_LOWPOWER_OVERSAMP_HUMIDITY BME280_OVERSAMP_2X
#define BME280_LOWPOWER_OVERSAMP_TEMPERATURE BME280_OVERSAMP_1X
#define BME280_STANDARDRESOLUTION_OVERSAMP_PRESSURE BME280_OVERSAMP_4X
#define BME280_STANDARDRESOLUTION_OVERSAMP_HUMIDITY BME280_OVERSAMP_4X
#define BME280_STANDARDRESOLUTION_OVERSAMP_TEMPERATURE BME280_OVERSAMP_1X
#define BME280_HIGHRESOLUTION_OVERSAMP_PRESSURE BME280_OVERSAMP_8X
#define BME280_HIGHRESOLUTION_OVERSAMP_HUMIDITY BME280_OVERSAMP_8X
#define BME280_HIGHRESOLUTION_OVERSAMP_TEMPERATURE BME280_OVERSAMP_1X
#define BME280_ULTRAHIGHRESOLUTION_OVERSAMP_PRESSURE BME280_OVERSAMP_16X
#define BME280_ULTRAHIGHRESOLUTION_OVERSAMP_HUMIDITY BME280_OVERSAMP_16X
#define BME280_ULTRAHIGHRESOLUTION_OVERSAMP_TEMPERATURE BME280_OVERSAMP_2X
/************************************************/
/**\name FILTER DEFINITION */
/***********************************************/
#define BME280_FILTER_COEFF_OFF (0x00)
#define BME280_FILTER_COEFF_2 (0x01)
#define BME280_FILTER_COEFF_4 (0x02)
#define BME280_FILTER_COEFF_8 (0x03)
#define BME280_FILTER_COEFF_16 (0x04)
/************************************************/
/*
* REGISTERS
*/
#define BME280_ADDRESS 0x76
#define BME280_REGISTER_DIG_T1 0x88
#define BME280_REGISTER_DIG_T2 0x8A
#define BME280_REGISTER_DIG_T3 0x8C
#define BME280_REGISTER_DIG_P1 0x8E
#define BME280_REGISTER_DIG_P2 0x90
#define BME280_REGISTER_DIG_P3 0x92
#define BME280_REGISTER_DIG_P4 0x94
#define BME280_REGISTER_DIG_P5 0x96
#define BME280_REGISTER_DIG_P6 0x98
#define BME280_REGISTER_DIG_P7 0x9A
#define BME280_REGISTER_DIG_P8 0x9C
#define BME280_REGISTER_DIG_P9 0x9E
#define BME280_REGISTER_DIG_H1 0xA1
#define BME280_REGISTER_DIG_H2 0xE1
#define BME280_REGISTER_DIG_H3 0xE3
#define BME280_REGISTER_DIG_H4 0xE4
#define BME280_REGISTER_DIG_H5 0xE5
#define BME280_REGISTER_DIG_H6 0xE7
#define BME280_REGISTER_CHIPID 0xD0
#define BME280_REGISTER_VERSION 0xD1
#define BME280_REGISTER_SOFTRESET 0xE0
#define BME280_RESET 0xB6
#define BME280_REGISTER_CAL26 0xE1
#define BME280_REGISTER_CONTROLHUMID 0xF2
#define BME280_REGISTER_STATUS 0xF3
#define BME280_REGISTER_CONTROL 0xF4
#define BME280_REGISTER_CONFIG 0xF5
#define BME280_REGISTER_PRESSUREDATA_MSB 0xF7
#define BME280_REGISTER_PRESSUREDATA_LSB 0xF8
#define BME280_REGISTER_PRESSUREDATA_XLSB 0xF9
#define BME280_REGISTER_TEMPDATA_MSB 0xFA
#define BME280_REGISTER_TEMPDATA_LSB 0xFB
#define BME280_REGISTER_TEMPDATA_XLSB 0xFC
#define BME280_REGISTER_HUMIDDATA_MSB 0xFD
#define BME280_REGISTER_HUMIDDATA_LSB 0xFE
class BME280 {
private:
char * device;
int devId;
int fd;
uint8_t chipId;
BME280CalibrationData * bmp280CalibrationData;
BME280RawData * bmp280RawData;
void write8(uint8_t, uint8_t);
int read8(uint8_t);
uint8_t readU8(uint8_t);
int8_t readS8(uint8_t);
int 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 compensateTemperature(int32_t t_fine);
double compensatePressure(int32_t adc_P, int32_t t_fine);
double compensateHumidity(int32_t adc_H, int32_t t_fine);
BME280CalibrationData * getCalibrationData();
BME280RawData * getRawData();
public:
BME280(const char*, int);
BME280(int);
virtual ~BME280();
BME280CalibrationData * getBmp280CalibrationData();
BMP280Data * getBMP280Data();
int init();
void reset();
void spi3wEnable();
void spi3wDisable();
void setPowerMode(uint8_t);
void setTemperatureOversampling(uint8_t);
void setPressureOversampling(uint8_t);
void setHumidityOversampling(uint8_t);
void setStandbyTime(uint8_t);
void setIrrFilter(uint8_t);
uint8_t getPowerMode();
uint8_t getPressureOversampling();
uint8_t getHumidityOversampling();
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 getControlHumidity();
uint8_t getChipId();
uint8_t getChipVersion();
void setReset(uint8_t);
void setConfig(uint8_t);
void setStatus(uint8_t);
void setControl(uint8_t);
void setControlHumidity(uint8_t);
};
bme280.cpp
#include <string.h>
#include <stdint.h>
#include <stdexcept>
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <wiringPiI2C.h>
#include "bme280.h"
void BME280::write8(uint8_t reg, uint8_t value) {
wiringPiI2CWriteReg8(fd, reg, value);
}
int BME280::read8(uint8_t reg) {
return wiringPiI2CReadReg8(fd, reg);
}
uint8_t BME280::readU8(uint8_t reg) {
return (uint8_t) read8(reg);
}
int8_t BME280::readS8(uint8_t reg) {
return (int8_t) read8(reg);
}
int BME280::read16(uint8_t reg) {
return wiringPiI2CReadReg16(fd, reg);
}
int16_t BME280::readS16(uint8_t reg) {
return (int16_t) read16(reg);
}
uint16_t BME280::readU16(uint8_t reg) {
return (uint16_t) read16(reg);
}
BME280::BME280(const char * device, int devId) :
fd(0), chipId(0), bmp280CalibrationData(0), bmp280RawData(0) {
this->device = new char[strlen(device)];
strcpy(this->device, device);
this->devId = devId;
}
BME280::BME280(int devId) :
fd(0), chipId(0), bmp280CalibrationData(0), bmp280RawData(0) {
this->devId = devId;
}
BME280::~BME280() {
delete bmp280CalibrationData;
delete bmp280RawData;
delete[] device;
}
int BME280::init() {
int fd = wiringPiI2CSetup(devId);
if (fd < 0) {
char buffer[256];
sprintf(buffer, "Device not found: device ID = %d", devId);
throw std::logic_error(buffer);
}
this->fd = fd;
uint8_t chipId = getChipId();
switch (chipId) {
case BME280_CHIP_ID1:
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;
}
BME280CalibrationData * BME280::getCalibrationData() {
int8_t H6;
uint8_t H1, H3;
int16_t T2, T3, P2, P3, P4, P5, P6, P7, P8, P9, H2, H4, H5;
uint16_t T1, P1;
T1 = readU16(BME280_REGISTER_DIG_T1);
T2 = readS16(BME280_REGISTER_DIG_T2);
T3 = readS16(BME280_REGISTER_DIG_T3);
P1 = readU16(BME280_REGISTER_DIG_P1);
P2 = readS16(BME280_REGISTER_DIG_P2);
P3 = readS16(BME280_REGISTER_DIG_P3);
P4 = readS16(BME280_REGISTER_DIG_P4);
P5 = readS16(BME280_REGISTER_DIG_P5);
P6 = readS16(BME280_REGISTER_DIG_P6);
P7 = readS16(BME280_REGISTER_DIG_P7);
P8 = readS16(BME280_REGISTER_DIG_P8);
P9 = readS16(BME280_REGISTER_DIG_P9);
H1 = readU8(BME280_REGISTER_DIG_H1);
H2 = readS16(BME280_REGISTER_DIG_H2);
H3 = readU8(BME280_REGISTER_DIG_H3);
H4 = (int16_t)((read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4 + 1) & 0xF));
H5 = (int16_t)((read8(BME280_REGISTER_DIG_H5 + 1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4));
H6 = readS8(BME280_REGISTER_DIG_H6);
return new BME280CalibrationData(T1, T2, T3, P1, P2, P3, P4, P5, P6, P7, P8, P9, H1, H2, H3, H4, H5, H6);
}
BME280CalibrationData * BME280::getBmp280CalibrationData() {
return bmp280CalibrationData;
}
BME280RawData * BME280::getRawData() {
uint8_t pmsb, plsb, pxsb;
uint8_t tmsb, tlsb, txsb;
uint8_t hmsb, hlsb;
uint32_t temperature, pressure, humidity;
plsb = readU8(BME280_REGISTER_PRESSUREDATA_LSB);
pmsb = readU8(BME280_REGISTER_PRESSUREDATA_MSB);
pxsb = readU8(BME280_REGISTER_PRESSUREDATA_XLSB);
tmsb = readU8(BME280_REGISTER_TEMPDATA_MSB);
tlsb = readU8(BME280_REGISTER_TEMPDATA_LSB);
txsb = readU8(BME280_REGISTER_TEMPDATA_XLSB);
hmsb = readU8(BME280_REGISTER_HUMIDDATA_MSB);
hlsb = readU8(BME280_REGISTER_HUMIDDATA_LSB);
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;
humidity = 0;
humidity = (humidity | hmsb) << 8;
humidity = (humidity | hlsb);
return new BME280RawData(pmsb, plsb, pxsb, tmsb, tlsb, txsb, hmsb, hlsb, temperature, pressure, humidity);
}
void BME280::reset() {
setReset (BME280_SOFT_RESET_CODE);
}
void BME280::spi3wEnable() {
uint8_t config = getConfig();
setConfig(config | 0b00000001);
}
void BME280::spi3wDisable() {
uint8_t config = getConfig();
setConfig(config & 0b11111110);
}
void BME280::setPowerMode(uint8_t mode) {
switch (mode) {
case BME280_FORCED_MODE:
case BME280_NORMAL_MODE:
case BME280_SLEEP_MODE: {
uint8_t curentMode = getControl() & 0b11111100;
setControl(curentMode | mode);
break;
}
default:
break;
}
}
void BME280::setTemperatureOversampling(uint8_t oversampling) {
switch (oversampling) {
case BME280_OVERSAMP_SKIPPED:
case BME280_OVERSAMP_1X:
case BME280_OVERSAMP_2X:
case BME280_OVERSAMP_4X:
case BME280_OVERSAMP_8X:
case BME280_OVERSAMP_16X: {
uint8_t curentOversampling = getControl() & 0b00011111;
setControl(curentOversampling | (oversampling << 5));
break;
}
default:
break;
}
}
void BME280::setPressureOversampling(uint8_t oversampling) {
switch (oversampling) {
case BME280_OVERSAMP_SKIPPED:
case BME280_OVERSAMP_1X:
case BME280_OVERSAMP_2X:
case BME280_OVERSAMP_4X:
case BME280_OVERSAMP_8X:
case BME280_OVERSAMP_16X: {
uint8_t curentOversampling = getControl() & 0b11100011;
setControl(curentOversampling | (oversampling << 2));
break;
}
default:
break;
}
}
void BME280::setHumidityOversampling(uint8_t oversampling) {
switch (oversampling) {
case BME280_OVERSAMP_SKIPPED:
case BME280_OVERSAMP_1X:
case BME280_OVERSAMP_2X:
case BME280_OVERSAMP_4X:
case BME280_OVERSAMP_8X:
case BME280_OVERSAMP_16X: {
setControlHumidity(0b00000111 & oversampling);
break;
}
default:
break;
}
}
uint8_t BME280::getHumidityOversampling() {
return getControlHumidity() & 0b00000111;
}
void BME280::setStandbyTime(uint8_t tStandby) {
switch (tStandby) {
case BME280_STANDBY_TIME_1_MS:
case BME280_STANDBY_TIME_63_MS:
case BME280_STANDBY_TIME_125_MS:
case BME280_STANDBY_TIME_250_MS:
case BME280_STANDBY_TIME_500_MS:
case BME280_STANDBY_TIME_1000_MS:
case BME280_STANDBY_TIME_2000_MS:
case BME280_STANDBY_TIME_4000_MS: {
uint8_t config = getConfig() & 0b00011111;
setConfig(config | (tStandby << 5));
break;
}
default:
break;
}
}
void BME280::setIrrFilter(uint8_t irrFilter) {
switch (irrFilter) {
case BME280_FILTER_COEFF_OFF:
case BME280_FILTER_COEFF_2:
case BME280_FILTER_COEFF_4:
case BME280_FILTER_COEFF_8:
case BME280_FILTER_COEFF_16: {
uint8_t config = getConfig() & 0b11100011;
setConfig(config | (irrFilter << 2));
break;
}
default:
break;
}
}
uint8_t BME280::getPowerMode() {
return getControl() & 0b00000011;
}
uint8_t BME280::getPressureOversampling() {
return (getControl() & 0b00011100) >> 2;
}
uint8_t BME280::getTemperatureOversampling() {
return (getControl() & 0b11100000) >> 5;
}
uint8_t BME280::getIrrFilter() {
return (getConfig() & 0b00011100) >> 2;
}
uint8_t BME280::getStandbyTime() {
return (getConfig() & 0b11100000) >> 5;
}
uint8_t BME280::getSpi3w() {
return (getConfig() & 0b00000001) >> 5;
}
uint8_t BME280::getMeasuringStatus() {
return (getStatus() >> 3) & 0b00000001;
}
uint8_t BME280::getImUpdateStatus() {
return getStatus() & 0b00000001;
}
uint8_t BME280::getConfig() {
return readU8(BME280_REGISTER_CONFIG);
}
uint8_t BME280::getStatus() {
return readU8(BME280_REGISTER_STATUS);
}
uint8_t BME280::getControl() {
return readU8(BME280_REGISTER_CONTROL);
}
uint8_t BME280::getControlHumidity() {
return readU8(BME280_REGISTER_CONTROLHUMID);
}
uint8_t BME280::getChipId() {
return readU8(BME280_REGISTER_CHIPID);
}
uint8_t BME280::getChipVersion() {
return readU8(BME280_REGISTER_VERSION);
}
void BME280::setReset(uint8_t value) {
write8(BME280_REGISTER_SOFTRESET, value);
}
void BME280::setConfig(uint8_t value) {
write8(BME280_REGISTER_CONFIG, value);
}
void BME280::setStatus(uint8_t value) {
write8(BME280_REGISTER_STATUS, value);
}
void BME280::setControl(uint8_t value) {
write8(BME280_REGISTER_CONTROL, value);
}
void BME280::setControlHumidity(uint8_t value) {
write8(BME280_REGISTER_CONTROLHUMID, value);
}
double BME280::getAltitude(double pressure) {
return 44330.0 * (1.0 - pow(pressure / MEAN_SEA_LEVEL_PRESSURE, 0.190294957));
}
int32_t BME280::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 BME280::compensateTemperature(int32_t t_fine) {
double T = (t_fine * 5 + 128) >> 8;
return T / 100;
}
double BME280::compensatePressure(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;
}
double BME280::compensateHumidity(int32_t adc_H, int32_t t_fine) {
int32_t v_x1_u32r;
v_x1_u32r = (t_fine - ((int32_t) 76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t) bmp280CalibrationData->getH4()) << 20) - (((int32_t) bmp280CalibrationData->getH5()) * v_x1_u32r)) + ((int32_t) 16384)) >> 15)
* (((((((v_x1_u32r * ((int32_t) bmp280CalibrationData->getH6())) >> 10) * (((v_x1_u32r * ((int32_t) bmp280CalibrationData->getH3())) >> 11) + ((int32_t) 32768))) >> 10)
+ ((int32_t) 2097152)) * ((int32_t) bmp280CalibrationData->getH2()) + 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t) bmp280CalibrationData->getH1())) >> 4));
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
double h = (v_x1_u32r >> 12);
return h / 1024.0;
}
BMP280Data * BME280::getBMP280Data() {
int32_t t_fine;
double t, p, h, a;
while (getMeasuringStatus()) {
}
if (bmp280RawData) {
delete bmp280RawData;
}
bmp280RawData = getRawData();
t_fine = getTemperatureC(bmp280RawData->getTemperature());
t = compensateTemperature(t_fine); // C
p = compensatePressure(bmp280RawData->getPressure(), t_fine) / 100; // hPa
h = compensateHumidity(bmp280RawData->getHumidity(), t_fine);
a = getAltitude(p); // meters
return new BMP280Data(p, t, h, a);
}
main.cpp
#include <stdio.h>
#include <string.h>
#include <stdexcept>
#include <iostream>
#include <stdint.h>
#include <time.h>
#include <math.h>
#include <wiringPiI2C.h>
#include <wiringPi.h>
#include "bme280.h"
int main() {
// char * device = "/dev/i2c-0";
// char * device = "/dev/i2c-1";
char * device = "/dev/i2c-2";
// char * device = "/dev/i2c-3";
int devId = BME280_I2C_ADDRESS1;
try {
BME280 * bme280 = new BME280(device, devId);
int fd = bme280->init();
bme280->reset();
if (fd < 0) {
printf("Device not found");
return -1;
}
printf("fd : 0x%02x\n", fd);
printf("chip id : 0x%02x\n", bme280->getChipId());
printf("chip ver : 0x%02x\n", bme280->getChipVersion());
bme280->reset();
bme280->setPowerMode(BME280_NORMAL_MODE);
bme280->setTemperatureOversampling(BME280_ULTRAHIGHRESOLUTION_OVERSAMP_TEMPERATURE);
bme280->setPressureOversampling(BME280_ULTRAHIGHRESOLUTION_OVERSAMP_PRESSURE);
bme280->setHumidityOversampling(BME280_ULTRAHIGHRESOLUTION_OVERSAMP_HUMIDITY);
bme280->setIrrFilter(BME280_FILTER_COEFF_16);
bme280->setStandbyTime(BME280_STANDBY_TIME_250_MS);
printf("---------------\n");
printf("pw mode : 0x%02x\n", bme280->getPowerMode());
printf("osrs_p : 0x%02x\n", bme280->getPressureOversampling());
printf("osrs_t : 0x%02x\n", bme280->getTemperatureOversampling());
printf("osrs_h : 0x%02x\n", bme280->getHumidityOversampling());
printf("---------------\n");
printf("filter : 0x%02x\n", bme280->getIrrFilter());
printf("t_sb : 0x%02x\n", bme280->getStandbyTime());
printf("---------------\n");
printf("spi3w sts: 0x%02x\n", bme280->getSpi3w());
printf("measuring: 0x%02x\n", bme280->getMeasuringStatus());
printf("im_update: 0x%02x\n", bme280->getImUpdateStatus());
printf("---------------\n");
while (1) {
delay(1000);
BMP280Data * bme280Data = bme280->getBMP280Data();
printf("pressure : %.2f \tmm Hg\n", bme280Data->getPressure() / 1.3332239);
printf("humidity : %.2f \t%c\n", bme280Data->getHumidity(), '%');
printf("temperature: %.2f \t°C\n", bme280Data->getTemperature());
printf("altitude : %.2f \tm\n\n", bme280Data->getAltitude());
}
delete bme280;
} catch (std::exception & e) {
printf("%s\n", e.what());
}
return 0;
}
Результат
Скачать проект CodeLite
CodeLite проект: BME280_Banana_Pi_M3.zip
Flyer: BST-BME280-FL000-02
Datasheet: BST-BME280-DS001-11
Handling, soldering & mounting instructions: BST-BME280-HS001-06
Shipment & packaging details: BST-BME280-SP000-00
Driver: BME280 driver














