Подключить датчик атмосферного давления BMP280 к Orange Pi PC можно как по I2C, так и по SPI, благо их несколько у Orange Pi PC. Также для работы с GPIO необходимо установить WiringOP, если вы работаете с Orange Pi, а если у вас Banana Pi — BPI-WiringPi.
Барометр на BMP280
BMP280 – это датчик атмосферного давления от BOSCH Sensortec и является улучшенной версией датчика BMP180. Отличается от него меньшими размерами (2 x 2.5 x 0.95 мм), пониженным энергопотреблением, высокой точностью работы и наличием точной заводской калибровки и двумя последовательными интерфейсами: I2C и SPI.
Логика работы датчика BMP280 осталась такой же, но претерпела некоторые долгожданные улучшения.
В таблице приведены улучшения, которые претерпел датчик BMP280:
Параметр | BMP180 | BMP280 |
---|---|---|
Размеры | 3.6 x 3.8 mm | 2.0 x 2.5 mm |
Мин VDD | 1.80 V | 1.71 V |
Мин VDDIO | 1.62 V | 1.20 V |
Потребляемый ток @3 Pa RMS шум | 12 μA | 2.7 μA |
RMS Шум | 3 Pa | 1.3 Pa |
Разрешение давления | 1 Pa | 0.16 Pa |
Разрешение температуры | 0.1°C | 0.01°C |
Интерфейсы | I²C | I²C & SPI (3 и 4 линии связи, mode ‘00’ and ‘11’) |
Режимы измерения | Только P или T, принудительное | P и T, принудительное или периодическое |
Частота измерений | до 120 Гц | до 157 Гц |
Параметры фильтра | Нет | Пять параметров фильтрации |
Режимами работы
От предыдущих моделей (BMP085 и BMP180) датчик отличается тремя режимами работы:
- SLEEP — режим пониженного энергопотребления
- FORCED – режим, аналогичный, режиму работы датчиков BMP085 и BMP180. По команде контроллера датчик выходит из режима сна, производит измерения, выдает результаты измерения контроллеру и переходит в режим пониженного энергопотребления
- NORMAL — уникальный для этого датчика режим. Датчик самостоятельно просыпается, производит измерения давления и температуры и засыпает. Все временные параметры этого режима программируются независимо. Считывать данные в этом режиме можно в любое время.
Фильтрация результатов измерений
В датчике предусмотрена фильтрация результатов измерений с настройкой таких параметров фильтрации:
- OVERSAMPLING для температуры (16, 17, 18, 19, 20 бит)
- OVERSAMPLING для давления (16, 17, 18, 19, 20 бит)
- TSB – время между между измерениями (0.5, 62.5, 125, 250, 500, 1000, 2000, 4000 мс)
- FILTER_COEFFICIENT – коэффициент фильтрации
Характеристики:
- Напряжение питания: от 1.71 В до 3.6 В
- Макс скорость I2C интерфейса: 3.4 МГц
- Потребляемый ток: 2.7 мкA при частоте отсчетов в 1 Гц
- Интерфейс: I2C, SPI (4 Провода), SPI (3 Провода)
- Калибровка: заводская
- Уровень шума: до 0.2 Па (1.7 см) и 0.01 температуры
- Диапазон измеряемого давления: от 300 hPa до 1100 hPa (9000 м до -500 м)
- Размер: 2.5 мм х 2.0 мм х 0.95 мм
BMP280 библиотека
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(curentMode | 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); }
Схема подключения BMP280 к Orange Pi
Я с этими датчиками работаю только по I2C. Подключяется BMP280 к Orange Pi очень просто: на Vcc даём 3.3 В, GND, SCL и SDA.
Рабочее напряжение датчика от 1.71 В до 3.6 В. Не стоит питать от 5 В, так как вероятность того, что он выйдет из строя, очень высока.
Ниже приведён пример программы для проверки вышеуказанной библиотеки.
Данная программа создаёт новый объект для работы с датчиком:
BMP280 * bmp280 = new BMP280(device, devId);
соединяется с датчиком:
int fd = bmp280->init();
и сбрасывает все его настройки:
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);
и раз в секунду читает и выводит на экран данные с 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; }
Результат
Скачать проект CodeLite
Для программирования на С/С++ я использую CodeLite IDE, так как с Code::Blocks у меня были проблемы.
Проект: BMP280_Banana_Pi_M3.zip
Flyer: BST-BMP280-FL000-00 (Bosch_Sensortec_Flyer_BMP280_onl.pdf)
Datasheet: BST-BMP280-DS001-12 (BST-BMP280-DS001-12.pdf)
Driver: BMP280 driver
Добрый день! Есть вопрос по данному поводу, подскажите пожалуйста, сколько датчиков BMP280 можно подключать к одному gpio?
Добрый день! А есть инструкция как подключить по командам? Как здесь, например https://www.rlocman.ru/review/article.html?di=337909 я просто новичек в этом деле и не сосем понимаю, что к чему.
Спасибо за код. А можно ли его модернизировать так, что бы он не все время спамил, а передавал данные по изменению давления? А если изменений не происходит, то, допустим, через 5 минут, выдавал повторные данные.
hotel Montenegro bar immobilien in Montenegro
Wonderful Post. Good you explained everything in details. https://www.vivaindia.com/
Wonderful & very informative article. https://www.vivaindia.com.co/
buy thc joint in prague https://shop-cannabis-prague.com
Нужны деньги срочно займ онлайн с быстрым одобрением и моментальным переводом на карту. Минимум документов, удобные условия и прозрачные ставки. Оформите займ прямо сейчас!
Промокоды для игр https://esportpromo.com/standoff/ggstandoff/ это бесплатные бонусы, скидки и эксклюзивные награды! Находите актуальные коды, используйте их и получайте максимум удовольствия от игры без лишних затрат.
Лучшие игровые промокоды ггстандофф промокоды на барабан в одном месте! Активируйте бонусы, получайте подарки и прокачивайте аккаунт без лишних затрат. Следите за обновлениями, чтобы не пропустить новые промо!
Хотите проверить компанию https://innproverka.ru по ИНН? Наш сервис поможет узнать подробную информацию о юридических лицах и ИП: статус, финансы, руководителей и возможные риски. Защищайте себя от ненадежных партнеров!
Раскрутка в соцсетях https://nakrytka.com без лишних затрат! Привлекаем реальную аудиторию, повышаем охваты и активность. Эффективные инструменты для роста вашего бренда.
Логистические услуги в Москве https://bvs-logistica.com доставка, хранение, грузоперевозки. Надежные решения для бизнеса и частных клиентов. Оптимизация маршрутов, складские услуги и полный контроль на всех этапах.
смотреть лучшие сериалы 2024 https://lordserialss.life
The full special bip39 Word List consists of 2048 words used to protect cryptocurrency wallets. Allows you to create backups and restore access to digital assets. Check out the full list.
thc joint in prague https://sale-weed-prague.com
The most comprehensive bip39 for securely creating and restoring cryptocurrency wallets. Learn how mnemonic coding works and protect your digital assets!
international moving Prague airport transfer Prague
casino en ligne partouche twin casino en ligne
New full bip39 phrase 2048 words used to create and restore crypto wallets. Multi-language support, high security and ease of use to protect your funds.
перевезти телевизор https://perevozimgruz.by/gruzoperevozki-po-belarusi/gruzoperevozki-minsk-vitebsk/
популярные фильмы 2025 бесплатно hd rezka сериалы боевики на планшете
Каталог финансовых организаций srochno-zaym-online ru в которых можно получить срочные онлайн займы и кредиты не выходя из дома.
Great Sharing, Thank you for such detailed description. Excellent Explanation. Thanks for sharing such a informative and useful post. https://www.vivaindia.com.mx/
новые смотреть фильмы без смс и регистрации 2025 лучшие сериалы в 4K UHD фильмы
smm boost service smm panel telegram
Нужны финансы срочно? Получите микрозайм на пластиковую карту за 10 минут. https://zaym-bez-proverok.ru/ Оформите форму без документов и получите согласие уже моментально!
top online casino игровые автоматы эльдорадо
top online casino топ 10 игровых автоматов онлайн
киного фильмы для мобильных устройств киного фильмы для детей
kinogo 720p киного мультфильмы
Our vehicle tuning services are designed to enhance your journey. We offer unique upgrades that improve the efficiency and style of your car. Whether you’re interested in suspension modifications or enhancing specific parts, we provide superior solutions for every need. Trust our experts to deliver flawless results that will improve your ride. For more details, visit our website at https://accurateautobodyrepair.com/ and discover how we can help you.