Подключить датчик атмосферного давления 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?
Добрый день. К примеру, на Orange Pi есть два I2C/TWI порта, так что можно подключать только два датчика. На одну шину невозможно по причине того, что нельзя менять адрес датчика.
Добрый день! А есть инструкция как подключить по командам? Как здесь, например https://www.rlocman.ru/review/article.html?di=337909 я просто новичек в этом деле и не сосем понимаю, что к чему.
Здравствуйте! Можно так:
Можете использовать:
чтобы редактировать главный файл, а именно переменную device, если у вас один I2C порт:
Спасибо большое! У меня RPi zero, сейчас попробую
Тогда вам нужно будет раскомментировать
и комментировать
потому что там только /dev/i2c-0, и компилировать снова
Все запустилось! Температура 23, давление 995, влажность 46. Спасибо еще раз за оперативную помощь и отзывчивость!)
Спасибо за код. А можно ли его модернизировать так, что бы он не все время спамил, а передавал данные по изменению давления? А если изменений не происходит, то, допустим, через 5 минут, выдавал повторные данные.
can you purchase amoxicillin online: where can i buy amoxocillin — amoxicillin without a doctors prescription
can you buy amoxicillin over the counter in canada: Com Pharm — amoxicillin 875 125 mg tab
amoxicillin medicine Amoxicillin for sale amoxicillin 500mg capsule
cheap priligy: buy priligy max pharm — Priligy tablets
amoxicillin over the counter in canada cheap amoxil amoxicillin cost australia
Descubre los mejores juegos de casino en 1xslots casino.
purchase amoxicillin 500 mg: amoxil — amoxicillin without a prescription
buy priligy: priligy — buy priligy
how can i get clomid no prescription: can you get clomid without a prescription — can i order clomid
buy priligy max pharm buy priligy dapoxetine price
can you buy clomid without dr prescription: clomid purchase online rex pharm — how can i get cheap clomid for sale
buy priligy max pharm: max pharm — cheap priligy
max pharm: priligy — dapoxetine online
cost of prednisone tablets prednisone 1 mg prednisone daily
priligy maxpharm: buy dapoxetine online — dapoxetine price
where can i get clomid without prescription: cheap clomid — how to get generic clomid for sale
buy generic clomid without prescription: cheap clomid — clomid cost
how to get amoxicillin over the counter: Amoxicillin for sale — amoxicillin 500mg capsules antibiotic
how to get generic clomid without dr prescription: rex pharm — where buy generic clomid pill
can you get cheap clomid without prescription: generic clomid — where to buy generic clomid without a prescription
prednisone 20 mg tablet price: order Prednisone — 20 mg of prednisone
https://cytpremium.com/# cytotec buy online usa
buy cytotec pills cheapest cytotec Misoprostol 200 mg buy online
lisinopril1st: cheapest Lisinopril — lisinopril1st
buying prescription drugs in mexico online https://mexicanpharmgate.com/ buying from online mexican pharmacy
buy amoxicillin canada: amoxil com pharm — generic amoxil 500 mg
lisinopril canada: cheapest Lisinopril — cheapest Lisinopril
buy cytotec over the counter [url=https://cytpremium.com/#]cheapest cytotec[/url] Abortion pills online
скачать приложения казино https://moonvapez.co.uk/onlajn-kazino-v-ukraine-rejting-top-kazino-na/
generic clomid prices: clomid online — can you buy cheap clomid without dr prescription
buy plavix: Clopidogrel Best Prices — Clopidogrel 75 MG price
dapoxetine price: priligy — priligy max pharm
cytotec pills buy online cheapest cytotec cytotec abortion pill
Cost of Plavix without insurance: Clopidogrel Best Prices — generic plavix
lisinopril1st: lisinopril1st — buy Lisinopril online
http://plavixclo.com/# cheap plavix antiplatelet drug
п»їplavix generic PlavixClo plavix medication
amoxicillin for sale online: amoxil com pharm — generic amoxicillin 500mg
buy Lisinopril 1st: cheapest Lisinopril — cheapest Lisinopril
https://cytpremium.com/# buy cytotec
prednisone 5mg daily: raypharm — prednisone 80 mg daily
lisinopril 10 mg online buy Lisinopril 1st lisinopril1st
vavada: вавада — вавада казино онлайн
https://pinup-kazi.ru/# пин ап зеркало
пинап казино pinup kazi pin up казино
вавада онлайн казино: вавада казино — вавада онлайн казино
пин ап казино онлайн: пин ап казино онлайн — пин ап казино
вавада онлайн казино: вавада онлайн казино — казино вавада
пин ап казино: pinup-kazi.ru — пин ап казино
pinup: pinup-kazi.kz — пин ап казино
вавада казино казино вавада вавада казино онлайн
pinup kazi: пин ап казино — пинап казино
вавада казино онлайн: вавада казино онлайн — вавада онлайн казино
пин ап казино: пинап казино — пин ап казино
pinup: пин ап казино официальный сайт — pinup-kazi.ru
вавада казино vavada kazi вавада казино онлайн
where to buy generic cytotec without rx As each ear receives its own unique musical note, the sound waves move toward each other and synchronize to produce a new musical note that the brain perceives
соут цена в москве внеочередная соут в москве
top ed drugs: canadian pharm — the best ed pills
buying from online mexican pharmacy: mexican pharmacy — mexican drugstore online
pharmacy online: canadian pharmacy — medicine for ed
male ed drugs https://indianpharmstar.com/# cheapest online pharmacy india