Подключить датчик атмосферного давления 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 я просто новичек в этом деле и не сосем понимаю, что к чему.
Wonderful Post. Good you explained everything in details. https://www.vivaindia.com/
Wonderful & very informative article. https://www.vivaindia.com.co/
Great Sharing, Thank you for such detailed description. Excellent Explanation. Thanks for sharing such a informative and useful post. https://www.vivaindia.com.mx/
Beginner piano sheet music piano music sheets
магазин аккаунтов социальных сетей https://marketplace-sell-accounts.ru
iphone 15 pro how much is iphone
купить аккаунт социальные сети https://social-accounts-marketplace.ru
магазин продажи аккаунтов https://akkaunt-market.ru
Доска объявлений https://estul.ru/blog по всей России: продавай и покупай товары, заказывай и предлагай услуги. Быстрое размещение, удобный поиск, реальные предложения. Каждый после регистрации получает на баланс аккаунта 100? для возможности бесплатного размещения ваших объявлений
buy thc gummies in prague cannafood in prague
Витебский университет П.М.Машерова https://vsu.by образовательный центр. Вуз является ведущим образовательным, научным и культурным центром Витебской области.
аренда машин адлер посуточно arenda-mashiny-adler.ru
снять автомобиль в аренду в сочи посуточная аренда автомобиля в сочи
мойка окон в квартире цены https://cleaning-top24.ru
аэропорт храброво аренда автомобиля прокат авто храброво аэропорт
заказ авто аренда напрокат авто посуточно
посуточная аренда авто в спб прокат авто в спб без водителя посуточно
The convenient http://www.booking-zabljak.com service will help you find the perfect hotel for car travelers and active holiday lovers. A wide range of accommodation: from cozy guest houses to modern hotels with parking, Wi-Fi and breakfast. Book in advance and relax in comfort in the heart of Montenegro!
The best online slots rise of olympus slot in one place: classics, new releases, jackpots and themed machines. Play without registration, test the demo or make real bets with bonuses.
Профессиональное агентство https://prvitruvio.ru/: разработка рекламы, брендинг, digital-маркетинг, наружка и SMM. Комплексное продвижение для бизнеса любого масштаба.
Куршская коса в Калининграде экскурсии https://kurshskaya-kosa-ekskursii.ru/ включают посещение Высоты Эфа
book comic read free digital comics reader
omniscient manga romance manga online free
найкращі фільми 2025 онлайн українське кіно онлайн 2025
фильм драма 2025 новинки кино 2025 онлайн бесплатно
фильмы 2025 уже вышедшие смотреть кино на телефоне в Full HD
кино фильмы 2025 онлайн фильмы в 4К бесплатно онлайн
лучшие фильмы 2025 онлайн фантастика 2025 смотреть бесплатно
маркетплейс аккаунтов соцсетей magazin-akkauntov-online.ru
фильмы драмы лучшие драмы 2025 смотреть онлайн
фильмы комедии 2025 ужасы 2025 смотреть онлайн HD
смотреть фильмы бесплатно фантастика 2025 смотреть бесплатно
фильмы на телефон фильмы в 4К бесплатно онлайн
фильмы 2025 уже вышедшие боевики 2025 смотреть бесплатно HD
хороший фильм без рекламы фильмы 2025 без регистрации и рекламы
фильм все серии подряд лучшие фильмы 2025 года в HD
смотреть фильмы в качестве лучшие фильмы онлайн без смс
размер металлического значка изготовление эмблем из металла
магазин аккаунтов социальных сетей маркетплейс аккаунтов
металлические значки на заказ москва металлические значки под заказ
маркетплейс аккаунтов соцсетей купить аккаунт
маркетплейс аккаунтов соцсетей аккаунт для рекламы
производство металлических значков металлические значки под заказ
площадка для продажи аккаунтов аккаунты с балансом
маркетплейс аккаунтов магазин аккаунтов
врач гинеколог платный гинеколог
маркетплейс аккаунтов соцсетей услуги по продаже аккаунтов
лазерная эпиляция бикини лазерная эпиляция бикини
лазерная эпиляция подмышек лазерная эпиляция отзывы
биржа аккаунтов купить аккаунт
печать буклетов дешево печать буклетов pdf
покупка аккаунтов купить аккаунт с прокачкой
печать бумажных наклеек печать маленьких наклеек
табличка на пластике пвх настольные таблички из пластика
печать плаката а4 печать плакатов поштучно
услуги по изготовлению стендов https://izgotovlenie-stendov2.ru
Account Buying Platform Account Selling Service
Account Purchase Account trading platform
Accounts marketplace accountsmarketplacehub.com
Website for Selling Accounts Account Trading
Accounts marketplace https://buyaccounts001.com
account acquisition account market
account trading buy pre-made account
database of accounts for sale accounts for sale
account exchange service accounts for sale
accounts for sale verified accounts for sale
sell accounts purchase ready-made accounts
verified accounts for sale account trading
online account store marketplace for ready-made accounts
server cloud price http://cloud-server1.com
Современный и удобный сайт rushill.ru на котором легко найти нужную информацию, товары или услуги. Простая навигация, понятный интерфейс и актуальное содержание подойдут как для новых пользователей, так и для постоянной аудитории. Работает быстро, доступен круглосуточно.
Онлайн проект online-mmo.ru где собраны полезные данные, инструменты и сервисы для повседневной жизни и профессиональной деятельности. Сайт адаптирован под любые устройства, стабильно работает и предоставляет максимум пользы без лишнего шума и рекламы.
account marketplace account purchase
database of accounts for sale account acquisition
online account store account exchange service
social media account marketplace account trading
accounts market account buying service
Современный сайт budo-sport.ru на котором легко найти нужную и полезную информацию, товары или услуги. Простая навигация, понятный интерфейс и актуальное содержание подойдут как для новых пользователей, так и для постоянной аудитории. Работает быстро, доступен круглосуточно.
курсовые на заказ https://kursoviehelp.ru
website for selling accounts account catalog
account trading accounts for sale
account buying service https://marketplace-social-accounts.org
account exchange accounts market
account exchange buy pre-made account
купить курсовую сайты для написания курсовой
купить курсовик курсач купить цена
sell account social media account marketplace
¡Hola aventureros de la fortuna !
Usa tus spins gratis sin depГіsito para probar juegos nuevos.
Empieza a jugar sin depГіsito. Disfruta de 25 tiradas gratis ahora. spins gratis sin depГіsito espaГ±a Es muy sencillo.
¡Que tengas magníficas ganancias sorprendentes !
Нужен номер для ТГ? Предлагаем https://techalpaka.online для одноразовой или постоянной активации. Регистрация аккаунта без SIM-карты, в любом регионе. Удобно, надёжно, без привязки к оператору.
social media account marketplace https://accounts-offer.org
purchase ready-made accounts https://accounts-marketplace.xyz/
find accounts for sale https://buy-best-accounts.org
guaranteed accounts https://accounts-marketplace.live/
buy account https://social-accounts-marketplace.xyz/
Вам требуется лечение? https://chemodantour.ru лечение хронических заболеваний, восстановление после операций, укрепление иммунитета. Включено всё — от клиники до трансфера и проживания.
купить игровой ноутбук хороший ноутбук цена
магазин бытовой электроники магазин бытовой электроники
купить смартфон xiaomi каталог смартфонов с ценами
account selling platform https://buy-accounts.space/
ноутбук hp цена ноутбук 16 цена
купить смартфон samsung каталог смартфонов с ценами
account marketplace https://buy-accounts.live
купить ноутбук 17 цена новых ноутбуков
купить смартфон 14 цена смартфона xiaomi
account purchase account marketplace
продать аккаунт https://akkaunty-na-prodazhu.pro/
продать аккаунт rynok-akkauntov.top
биржа аккаунтов https://akkaunt-magazin.online/
купить аккаунт https://akkaunty-market.live
ГГУ имени Ф.Скорины https://www.gsu.by/ крупный учебный и научно-исследовательский центр Республики Беларусь. Высшее образование в сфере гуманитарных и естественных наук на 12 факультетах по 35 специальностям первой ступени образования и 22 специальностям второй, 69 специализациям.
смородина с долгим плодоношением вишня с высоким урожаем
магазин аккаунтов akkaunty-optom.live
продать аккаунт купить аккаунт
Недвижимость в Болгарии у моря https://byalahome.ru квартиры, дома, апартаменты в курортных городах. Продажа от застройщиков и собственников. Юридическое сопровождение, помощь в оформлении ВНЖ, консультации по инвестициям.
Срочный выкуп квартир https://proday-kvarti.ru за сутки — решим ваш жилищный или финансовый вопрос быстро. Гарантия законности сделки, юридическое сопровождение, помощь на всех этапах. Оценка — бесплатно, оформление — за наш счёт. Обращайтесь — мы всегда на связи и готовы выкупить квартиру.
Портал о недвижимости https://akadem-ekb.ru всё, что нужно знать о продаже, покупке и аренде жилья. Актуальные объявления, обзоры новостроек, советы экспертов, юридическая информация, ипотека, инвестиции. Помогаем выбрать квартиру или дом в любом городе.
купить аккаунт kupit-akkaunt.online
мастерская цветов салон цветов
заказать цветы спб заказать цветы с доставкой санкт-петербург
¡Hola, aficionados al casino !
Los mejores casinos online ofrecen giros gratis. casino tiradas gratis por registrarte Disfruta sin pagar.
PromociГіn exclusiva: spins gratis sin depГіsito espaГ±a ВЎsin riesgos! — п»їhttps://25girosgratissindeposito.xyz/
casinogurues.com
¡Que tengas excelentes sesiones de juego !
facebook ad account buy buy facebook ad accounts
buy old facebook account for ads buying facebook ad account
buy a facebook account https://buy-ads-account.click/
buy facebook accounts cheap https://ad-account-buy.top
buy fb ad account buy fb ad account
натяжные потолки видео потолок натяжной цена с установкой
facebook ad account buy https://ad-accounts-for-sale.work
buy google ads threshold account https://buy-ads-accounts.click
помощь в написании диплома написание диплома на заказ
сколько стоит реферат сколько стоит реферат на заказ
buy fb account https://buy-accounts.click
buy google ads threshold accounts https://ads-account-buy.work/
buy verified google ads account https://buy-ads-invoice-account.top
buy google ads account buy google adwords accounts
Экспертные услуги аккредитация гидов экскурсоводов Калининград для экскурсий.
buy fb bm https://buy-business-manager.org
заказать реферат заказать реферат
сделать диплом дипломная работа срочно на заказ
verified bm buy-verified-business-manager-account.org
facebook business manager account buy https://buy-verified-business-manager.org/
парящий натяжной потолок цена кв м натяжного потолка
прокат автомобилей цены прокат автомобилей
аренда машины сколько взять машину на прокат
buy facebook business account https://business-manager-for-sale.org
buy facebook business account buy verified facebook business manager account
facebook business manager buy buy-bm.org
buy verified business manager buy-business-manager-accounts.org
buy tiktok ad account https://tiktok-ads-account-for-sale.org
tiktok ad accounts https://tiktok-agency-account-for-sale.org
tiktok agency account for sale https://buy-tiktok-ad-account.org
создание сайта на laravel сайт на laravel
tiktok ads account for sale https://buy-tiktok-ads.org
¡Saludos, maestros en apuestas !
Casinos online best son reconocidos por su innovaciГіn y fiabilidad.
Casino online en Chile: las mejores opciones para ti — https://www.youtube.com/watch?v=CRuk1wy6nA0&list=PLX0Xt4gdc3aJG7y03Wh5Qf0JrapCEgMFH
RTBet y criptomonedas en Chile estГЎn revolucionando el mundo de los casinos online. Este sitio permite apostar con monedas digitales de forma rГЎpida y segura. AdemГЎs, ofrece bonos exclusivos para quienes usan cripto.
¡Que disfrutes de beneficios inesperados !
сео продвижение seo москва цена
изготовить шильдик https://izgotovlenie-shildov-na-zakaz.ru
латунные шильды латунный шильдик на заказ
бейджи заказать москва металлические бейджи с эмалью изготовление
создание и продвижение продающих сайтов создание и разработка сайтов
типография санкт петербург типография печать
типография напечатать типография полиграфия
типография быстро типография спб
печать черных визиток печать визиток на пластике
Изготовление и печать наклеек дешево. Стикеры для бизнеса, сувениров, интерьера и упаковки. Печатаем тиражами от 1 штуки, любые материалы и формы. Качественно, недорого, с доставкой по СПб.
Безболезненная салон лазерной эпиляции Удаление волос на любом участке тела. Работаем с чувствительной кожей, используем новейшие лазеры. Акции, абонементы, индивидуальный подход.
Профессиональная https://lazernaya-epilyaciya11.ru. Эффективное удаление волос на любом участке тела, подход к любому фототипу. Сертифицированные специалисты, стерильность, скидки. Запишитесь прямо сейчас!
Избавьтесь от волос студия лазерной эпиляции спб навсегда — с помощью лазерной эпиляции. Эффективные процедуры на любом участке тела, минимальный дискомфорт, заметный результат уже после первого сеанса.
доставка цветов белые доставка цветов на дом
https://pharmau24.com/# Pharm Au24
http://eropharmfast.com/# get ed meds today
¡Hola, fanáticos de las apuestas!
El casino online bono de bienvenida ha revolucionado la forma de empezar en el juego online. casinosonlineconbonodebienvenida.xyz Ahora es mГЎs fГЎcil comenzar con ventaja.
Consigue tu slots bono de bienvenida sin depГіsito — п»їhttps://casinosonlineconbonodebienvenida.xyz/
En casinosonlineconbonodebienvenida.xyz encontrarГЎs mГєltiples opciones seguras para comenzar tu aventura de juego. La mayorГa de estos sitios ofrecen bonos atractivos con condiciones accesibles. Es ideal para jugadores que desean probar antes de depositar.
¡Que disfrutes de victorias inolvidables !
Свежие актуальные Самые свежие новости из мира спорта со всего мира. Результаты матчей, интервью, аналитика, расписание игр и обзоры соревнований. Будьте в курсе главных событий каждый день!
http://biotpharm.com/# get antibiotics without seeing a doctor
https://kampascher.shop/# acheter kamagra site fiable
http://ciasansordonnance.com/# cialis sans ordonnance
https://pharmsansordonnance.com/# pharmacie en ligne fiable
https://kampascher.shop/# achat kamagra
https://pharmsansordonnance.shop/# п»їpharmacie en ligne france
http://ciasansordonnance.com/# Acheter Cialis
customized balloons dubai dubai city balloons
chief engineer cv example engineer resumes
https://pharmsansordonnance.com/# pharmacie en ligne sans ordonnance
http://ciasansordonnance.com/# Cialis pas cher livraison rapide
https://kampascher.shop/# kamagra gel
Разнообразие от елегантни рокли за офиса и делови срещи
стилни дамски рокли http://www.rokli-damski.com/ .
Подари си комфорт с дамски комплект за уикенд разходки и почивка
дамски комплекти с намаление http://komplekti-za-jheni.com/ .
https://pharmacieexpress.shop/# tadalafil achat en ligne
https://confiapharma.com/# farmacia online en galicia
https://pharmacieexpress.shop/# ozempic sans ordonnance belgique
Създай безупречна визия с нашите дамски тениски и модерни аксесоари
модерни дамски тениски https://www.teniski-damski.com .
Вдъхнови се от новите модни решения при дамските блузи
стилни дамски блузи bluzi-damski.com .
https://confiapharma.shop/# comprar prednisona sin receta
Услуги клининга с подпиской для управляющих компаний
сайт клининговой компании kliningovaya-kompaniya0.ru .
Мир полон тайн https://phenoma.ru читайте статьи о малоизученных феноменах, которые ставят науку в тупик. Аномальные явления, редкие болезни, загадки космоса и сознания. Доступно, интересно, с научным подходом.
Читайте о необычном http://phenoma.ru научно-популярные статьи о феноменах, которые до сих пор не имеют однозначных объяснений. Психология, физика, биология, космос — самые интересные загадки в одном разделе.
Магазин шин с поддержкой подбора по VIN и консультацией экспертов
магазин шины kupit-shiny0-spb.ru .
http://farmaciasubito.com/# aircort aerosol bambini
https://farmaciasubito.shop/# galastop prezzo
Сувениры с логотипом на заказ — быстро, выгодно, надёжно
сувенирная продукция https://suvenirnaya-produktsiya-s-logotipom-1.ru .
resume civil engineer fresh graduate https://resumes-engineers.com
resume google engineer resume google engineer
https://confiapharma.shop/# se puede comprar buscapina sin receta mГ©dica
resume google engineer resume engineering fresher
https://confiapharma.com/# lordelo farmacia online
http://inpharm24.com/# india online medicine
Аренда яхты — идеальный способ отметить день рождения на воде
арендовать яхту в сочи http://arenda-yahty-sochi23.ru/ .
¡Hola, competidores hábiles !
Las casas extranjeras ofrecen programas VIP mucho mГЎs completos. casinofueradeespana.xyz Obtienes beneficios por tu actividad regular sin tener que cumplir tantas condiciones.
Descubre promociones Гєnicas en casinofueradeespana.xyz — п»їhttps://casinofueradeespana.xyz/
Casino por fuera tambiГ©n significa menos restricciones para jugadores de alto nivel. Puedes apostar grandes sumas sin necesidad de autorizaciones especiales. Es perfecto para rollers altos.
¡Que disfrutes de botes extraordinarios !
http://inpharm24.com/# pharmacy india online
https://pharmmex.shop/# the online drugstore
https://inpharm24.shop/# pharmacy india online
Jarvi — корм премиум-класса, одобренный ветеринарами
jarvi корм производитель jarvi корм производитель .
https://vgrsources.com/# viagra for sale uk
https://vgrsources.com/# sildenafil price comparison in india
https://vgrsources.com/# sildenafil 20 mg tablets price
https://vgrsources.com/# online viagra
Гагры ждут гостей — отдых у моря, который приятно вспоминать
гагра снять жилье otdyh-gagry.ru .
https://vgrsources.com/# female viagra where to buy
https://vgrsources.com/# viagra cream buy online
https://vgrsources.com/# buy cheap viagra online from india
Film tutkunlarına özel güncel ve kaliteli full hd film arşivi
4k film ize 4k film ize .
https://vgrsources.com/# cheap viagra pills free shipping
https://vgrsources.com/# how to buy viagra in usa
Поверка, калибровка и метрологическая аттестация — в чём разница
Поверка средств измерений в Москве https://www.poverka-si-msk.ru/ .
Need transportation? ship car across country car transportation company services — from one car to large lots. Delivery to new owners, between cities. Safety, accuracy, licenses and experience over 10 years.
https://vgrsources.com/# viagra pills price canada
https://lipipharm.com/# Lipi Pharm
Медицинская помощь без лишнего стресса — нарколог приезжает к вам домой
вызов врача нарколога на дом телефон https://clinic-narkolog24.ru/ .
https://semaglupharm.com/# SemagluPharm
https://semaglupharm.com/# Semaglu Pharm
Доставка алкоголя с акциями и скидками — удобно и выгодно
как купить алкоголь с доставкой на дом в москве ночью алкоголь дешево москва доставка .
https://lipipharm.com/# lipitor dosing
https://crestorpharm.com/# CrestorPharm
http://semaglupharm.com/# glp-1 semaglutide
http://prednipharm.com/# can you buy prednisone without a prescription
http://crestorpharm.com/# CrestorPharm
Бокалы для вина в скандинавском стиле — лёгкость и простота
винный бокал http://www.bokaly-dlya-vina.neocities.org .
http://prednipharm.com/# can i buy prednisone online in uk
https://lipipharm.shop/# LipiPharm
https://lipipharm.shop/# Safe atorvastatin purchase without RX
https://prednipharm.shop/# prednisone uk over the counter
http://prednipharm.com/# Predni Pharm
Доступный императорский фарфор — премиум-посуда по разумным ценам
ломоносовский фарфоровый завод https://imperatorskiy-farfor.kesug.com .
https://crestorpharm.shop/# myalgia and crestor
http://prednipharm.com/# no prescription online prednisone
https://crestorpharm.com/# Crestor 10mg / 20mg / 40mg online
https://crestorpharm.com/# zetia vs crestor
Crestor Pharm: side effects of crestor medication — Crestor Pharm
LipiPharm LipiPharm Safe atorvastatin purchase without RX
https://semaglupharm.com/# does rybelsus cause insomnia
medicine prednisone 5mg: Predni Pharm — prednisone 5093
https://semaglupharm.com/# Semaglu Pharm