Подключить датчик атмосферного давления 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 минут, выдавал повторные данные.
http://indianpharmacy.win/# reputable indian online pharmacy
mexican online pharmacies prescription drugs: buying from online mexican pharmacy — reputable mexican pharmacies online
http://canadianpharmacy.win/# canadian pharmacy meds reviews
http://canadianpharmacy.win/# canadian pharmacy
canadian pharmacy 24: canadian pharmacy win — canadian pharmacy meds
http://canadianpharmacy.win/# adderall canadian pharmacy
mexican rx online: buying prescription drugs in mexico online — pharmacies in mexico that ship to usa
https://indianpharmacy.win/# india pharmacy
mexican online pharmacies prescription drugs п»їbest mexican online pharmacies mexican border pharmacies shipping to usa
https://indianpharmacy.win/# top online pharmacy india
http://mexicanpharmacy.store/# mexican border pharmacies shipping to usa
buying from online mexican pharmacy: mexican border pharmacies shipping to usa — medication from mexico pharmacy
http://indianpharmacy.win/# reputable indian pharmacies
mexican border pharmacies shipping to usa best online pharmacies in mexico medicine in mexico pharmacies
best online pharmacy india: cheapest online pharmacy india — india online pharmacy
http://canadianpharmacy.win/# canadian pharmacies online
https://fastpillseasy.com/# pills for ed online
http://fastpillseasy.com/# ed meds on line
Cheap generic Viagra online: FastPillsForMen — Generic Viagra online
Cialis 20mg price Cheap Cialis cialis for sale
ed treatments online: buy ed pills online — ed medicine online
https://maxpillsformen.com/# Buy Cialis online
where can i buy ed pills: ed medications cost — cheap boner pills
online erectile dysfunction medication fast pills easy buy ed meds online
sildenafil over the counter: cheap viagra — Cheapest Sildenafil online
cialis for sale: MaxPillsForMen.com — Generic Cialis without a doctor prescription
Viagra online price FastPillsForMen Cheap Viagra 100mg
Buy Cialis online: MaxPillsForMen.com — Generic Tadalafil 20mg price
https://fastpillsformen.com/# Viagra online price
hotel Montenegro bar immobilien in Montenegro
Cialis 20mg price: Generic Cialis without a doctor prescription — Generic Cialis price
п»їcialis generic cheapest cialis Cialis 20mg price
cheapest ed treatment: erectile dysfunction pills online — top rated ed pills
Cheap generic Viagra: FastPillsForMen — sildenafil over the counter
http://maxpillsformen.com/# Buy Tadalafil 20mg
Viagra online price: cheap viagra — buy viagra here
cheapest viagra cheap viagra sildenafil 50 mg price
cialis for sale: MaxPillsForMen — Tadalafil price
viagra canada: Fast Pills For Men — sildenafil over the counter
http://fastpillseasy.com/# get ed prescription online
http://maxpillsformen.com/# Generic Cialis without a doctor prescription
sildenafil online: Viagra online price — best price for viagra 100mg
http://fastpillseasy.com/# online ed medication
online erectile dysfunction pills: FastPillsEasy — low cost ed pills
Cialis 20mg price Generic Cialis without a doctor prescription Cialis 20mg price in USA
cheapest ed online: cheap cialis — online erectile dysfunction prescription
https://fastpillsformen.com/# cheap viagra
generic sildenafil cheap viagra buy Viagra online
п»їcialis generic: MaxPillsForMen — Cialis over the counter
Generic Cialis without a doctor prescription: MaxPillsForMen.com — Cheap Cialis
buy ed pills online cheap cialis boner pills online
erectile dysfunction online: FastPillsEasy — cheapest ed treatment
Buy Tadalafil 5mg: Max Pills For Men — Cialis without a doctor prescription
best online ed medication cheap cialis what is the cheapest ed medication
sweet bonanza kazanma saatleri: sweet bonanza oyna — sweet bonanza slot
yeni deneme bonusu veren siteler: deneme bonusu veren siteler — yeni deneme bonusu veren siteler
deneme bonusu veren casino siteleri: en guvenilir casino siteleri — Casino Siteleri
en guvenilir casino siteleri Casino Siteleri Deneme Bonusu Veren Siteler
sweet bonanza yorumlar sweet bonanza slot sweet bonanza demo oyna
http://denemebonusuverensiteler25.com/# yeni deneme bonusu veren siteler
sweet bonanza: sweet bonanza demo oyna — sweet bonanza oyna
http://sweetbonanza25.com/# sweet bonanza kazanma saatleri
sweet bonanza giris: sweet bonanza yorumlar — sweet bonanza demo oyna
sweet bonanza: sweet bonanza guncel — sweet bonanza giris
Deneme Bonusu Veren Siteler: Casino Siteleri — en guvenilir casino siteleri
sweet bonanza demo oyna sweet bonanza giris sweet bonanza yorumlar
sweet bonanza demo oyna: sweet bonanza kazanma saatleri — sweet bonanza giris
https://denemebonusuverensiteler25.com/# yat?r?ms?z deneme bonusu veren siteler
«Whether you’re a tactical professional, competitive shooter, or firearm enthusiast, our triggers deliver the performance you need to excel.
https://legendarytriggers.com
en cok kazand?ran slot oyunlar?: slot oyunlar? — az parayla cok kazandiran slot oyunlar?
deneme bonusu veren yeni siteler denemebonusuverensiteler25 yat?r?ms?z deneme bonusu veren siteler
yeni deneme bonusu veren siteler: denemebonusuverensiteler25 — deneme bonusu veren siteler yeni
slot siteleri: az parayla cok kazandiran slot oyunlar? — az parayla cok kazandiran slot oyunlar?
Casino Siteleri Canl? Casino Siteleri Casino Siteleri
Deneme Bonusu Veren Siteler: Casino Siteleri — Casino Siteleri
denemebonusuverensiteler25 yeni deneme bonusu veren siteler denemebonusuverensiteler25
en kazancl? slot oyunlar?: slot siteleri — slot siteleri
canl? casino siteleri: bahis oyun siteleri — deneme bonusu veren casino siteleri
casino bahis siteleri welches online casino en iyi bet siteleri
Deneme Bonusu Veren Siteler: Casino Siteleri — Canl? Casino Siteleri
yat?r?ms?z deneme bonusu veren siteler: yeni deneme bonusu veren siteler — deneme bonusu veren siteler
denemebonusuverensiteler25 deneme bonusu veren yeni siteler yeni deneme bonusu veren siteler
deneme bonusu veren siteler: yat?r?ms?z deneme bonusu veren siteler — denemebonusuverensiteler25
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.