diff --git a/Sensors.c b/Sensors.c
index 80f7243..d35e319 100644
--- a/Sensors.c
+++ b/Sensors.c
@@ -72,7 +72,7 @@ const Interface ONE_WIRE = {
//static const Interface* interfaces[] = {&SINGLE_WIRE, &I2C, &ONE_WIRE};
//Перечень датчиков
static const SensorType* sensorTypes[] =
- {&DHT11, &DHT12_SW, &DHT21, &DHT22, &AM2320_SW, &AM2320_I2C, &LM75, &BMP280, &Dallas};
+ {&DHT11, &DHT12_SW, &DHT21, &DHT22, &AM2320_SW, &AM2320_I2C, &LM75, &BMP280, &BME280, &Dallas};
const SensorType* unitemp_sensors_getTypeFromInt(uint8_t index) {
if(index > SENSOR_TYPES_COUNT) return NULL;
diff --git a/Sensors.h b/Sensors.h
index 52545ec..52e6165 100644
--- a/Sensors.h
+++ b/Sensors.h
@@ -318,6 +318,7 @@ const GPIO*
//DS18x2x
#include "./interfaces/OneWireSensor.h"
#include "./sensors/LM75.h"
-#include "./sensors/BMP280.h"
+//BMP280, BME280
+#include "./sensors/BMx280.h"
#include "./sensors/AM2320.h"
#endif
diff --git a/sensors/BMP280.c b/sensors/BMP280.c
deleted file mode 100644
index 1be79fc..0000000
--- a/sensors/BMP280.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- Unitemp - Universal temperature reader
- Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-#include "BMP280.h"
-
-const SensorType BMP280 = {
- .typename = "BMP280",
- .interface = &I2C,
- .datatype = UT_DATA_TYPE_TEMP_PRESS,
- .pollingInterval = 500,
- .allocator = unitemp_BMP280_alloc,
- .mem_releaser = unitemp_BMP280_free,
- .initializer = unitemp_BMP280_init,
- .deinitializer = unitemp_BMP280_deinit,
- .updater = unitemp_BMP280_update};
-
-//Интервал обновления калибровочных значений
-#define BMP280_CAL_UPDATE_INTERVAL 60000
-
-#define TEMP_CAL_START_ADDR 0x88
-#define PRESS_CAL_START_ADDR 0x8E
-#define BMP280_ID 0x58
-
-#define BMP280_REG_STATUS 0xF3
-#define BMP280_REG_CTRL_MEAS 0xF4
-#define BMP280_REG_CONFIG 0xF5
-//Преддескретизация температуры
-#define BMP280_TEMP_OVERSAMPLING_SKIP 0b00000000
-#define BMP280_TEMP_OVERSAMPLING_1 0b00100000
-#define BMP280_TEMP_OVERSAMPLING_2 0b01000000
-#define BMP280_TEMP_OVERSAMPLING_4 0b01100000
-#define BMP280_TEMP_OVERSAMPLING_8 0b10000000
-#define BMP280_TEMP_OVERSAMPLING_16 0b10100000
-//Преддескретизация давления
-#define BMP280_PRESS_OVERSAMPLING_SKIP 0b00000000
-#define BMP280_PRESS_OVERSAMPLING_1 0b00000100
-#define BMP280_PRESS_OVERSAMPLING_2 0b00001000
-#define BMP280_PRESS_OVERSAMPLING_4 0b00001100
-#define BMP280_PRESS_OVERSAMPLING_8 0b00010000
-#define BMP280_PRESS_OVERSAMPLING_16 0b00010100
-//Режимы работы датчика
-#define BMP280_MODE_SLEEP 0b00000000 //Спит и мало кушает
-#define BMP280_MODE_FORCED 0b00000001 //Обновляет значения 1 раз, после чего уходит в сон
-#define BMP280_MODE_NORMAL 0b00000011 //Регулярно обновляет значения
-//Период обновления в нормальном режиме
-#define BMP280_STANDBY_TIME_0_5 0b00000000
-#define BMP280_STANDBY_TIME_62_5 0b00100000
-#define BMP280_STANDBY_TIME_125 0b01000000
-#define BMP280_STANDBY_TIME_250 0b01100000
-#define BMP280_STANDBY_TIME_500 0b10000000
-#define BMP280_STANDBY_TIME_1000 0b10100000
-#define BMP280_STANDBY_TIME_2000 0b11000000
-#define BMP280_STANDBY_TIME_4000 0b11100000
-//Коэффициент фильтрации значений
-#define BMP280_FILTER_COEFF_1 0b00000000
-#define BMP280_FILTER_COEFF_2 0b00000100
-#define BMP280_FILTER_COEFF_4 0b00001000
-#define BMP280_FILTER_COEFF_8 0b00001100
-#define BMP280_FILTER_COEFF_16 0b00010000
-//Разрешить работу по SPI
-#define BMP280_SPI_3W_ENABLE 0b00000001
-#define BMP280_SPI_3W_DISABLE 0b00000000
-
-static float bmp280_compensate_T_float(I2CSensor* i2c_sensor, int32_t adc_T) {
- BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
- int32_t var1, var2;
- var1 = ((((adc_T >> 3) - ((int32_t)bmp280_instance->temp_cal.dig_T1 << 1))) *
- ((int32_t)bmp280_instance->temp_cal.dig_T2)) >>
- 11;
- var2 = (((((adc_T >> 4) - ((int32_t)bmp280_instance->temp_cal.dig_T1)) *
- ((adc_T >> 4) - ((int32_t)bmp280_instance->temp_cal.dig_T1))) >>
- 12) *
- ((int32_t)bmp280_instance->temp_cal.dig_T3)) >>
- 14;
- bmp280_instance->t_fine = var1 + var2;
- return ((bmp280_instance->t_fine * 5 + 128) >> 8) / 100.0f;
-}
-
-static float bmp280_compensate_P_float(I2CSensor* i2c_sensor, int32_t adc_P) {
- BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
-
- int32_t var1, var2;
- uint32_t p;
- var1 = (((int32_t)bmp280_instance->t_fine) >> 1) - (int32_t)64000;
- var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t)bmp280_instance->press_cal.dig_P6);
- var2 = var2 + ((var1 * ((int32_t)bmp280_instance->press_cal.dig_P5)) << 1);
- var2 = (var2 >> 2) + (((int32_t)bmp280_instance->press_cal.dig_P4) << 16);
- var1 = (((bmp280_instance->press_cal.dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) +
- ((((int32_t)bmp280_instance->press_cal.dig_P2) * var1) >> 1)) >>
- 18;
- var1 = ((((32768 + var1)) * ((int32_t)bmp280_instance->press_cal.dig_P1)) >> 15);
- if(var1 == 0) {
- return 0; // avoid exception caused by division by zero
- }
- p = (((uint32_t)(((int32_t)1048576) - adc_P) - (var2 >> 12))) * 3125;
- if(p < 0x80000000) {
- p = (p << 1) / ((uint32_t)var1);
- } else {
- p = (p / (uint32_t)var1) * 2;
- }
- var1 = (((int32_t)bmp280_instance->press_cal.dig_P9) *
- ((int32_t)(((p >> 3) * (p >> 3)) >> 13))) >>
- 12;
- var2 = (((int32_t)(p >> 2)) * ((int32_t)bmp280_instance->press_cal.dig_P8)) >> 13;
- p = (uint32_t)((int32_t)p + ((var1 + var2 + bmp280_instance->press_cal.dig_P7) >> 4));
- return p;
-}
-
-static bool bmp280_readCalValues(I2CSensor* i2c_sensor) {
- BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
- if(!unitemp_i2c_readRegArray(
- i2c_sensor, TEMP_CAL_START_ADDR, 6, (uint8_t*)&bmp280_instance->temp_cal))
- return false;
-#ifdef UNITEMP_DEBUG
- FURI_LOG_D(
- APP_NAME,
- "Sensor BMP280 (0x%02X) calibration values: T1: %d, T2: %d, T3: %d",
- i2c_sensor->currentI2CAdr,
- bmp280_instance->temp_cal.dig_T1,
- bmp280_instance->temp_cal.dig_T2,
- bmp280_instance->temp_cal.dig_T3);
-#endif
-
- if(!unitemp_i2c_readRegArray(
- i2c_sensor, PRESS_CAL_START_ADDR, 18, (uint8_t*)&bmp280_instance->press_cal))
- return false;
-#ifdef UNITEMP_DEBUG
- FURI_LOG_D(
- APP_NAME,
- "Sensor BMP280 (0x%02X): P1-9: %d, %d, %d, %d, %d, %d, %d, %d, %d",
- i2c_sensor->currentI2CAdr,
- bmp280_instance->press_cal.dig_P1,
- bmp280_instance->press_cal.dig_P2,
- bmp280_instance->press_cal.dig_P3,
- bmp280_instance->press_cal.dig_P4,
- bmp280_instance->press_cal.dig_P5,
- bmp280_instance->press_cal.dig_P6,
- bmp280_instance->press_cal.dig_P7,
- bmp280_instance->press_cal.dig_P8,
- bmp280_instance->press_cal.dig_P9);
-#endif
-
- bmp280_instance->last_cal_update_time = furi_get_tick();
- return true;
-}
-static bool bmp280_isMeasuring(Sensor* sensor) {
- I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
- return (bool)((unitemp_i2c_readReg(i2c_sensor, BMP280_REG_STATUS) & 0x08) >> 3);
-}
-
-bool unitemp_BMP280_alloc(Sensor* sensor, char* args) {
- UNUSED(args);
- I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
- BMP280_instance* bmp280_instance = malloc(sizeof(BMP280_instance));
- if(bmp280_instance == NULL) {
- FURI_LOG_E(APP_NAME, "Failed to allocation sensor %s instance", sensor->name);
- return false;
- }
- i2c_sensor->sensorInstance = bmp280_instance;
-
- i2c_sensor->minI2CAdr = 0x76 << 1;
- i2c_sensor->maxI2CAdr = 0x77 << 1;
- return true;
-}
-
-bool unitemp_BMP280_init(Sensor* sensor) {
- I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
- //Перезагрузка
- unitemp_i2c_writeReg(i2c_sensor, 0xE0, 0xB6);
- //Чтение ID датчика
- uint8_t id = unitemp_i2c_readReg(i2c_sensor, 0xD0);
- if(id != BMP280_ID) {
- FURI_LOG_E(
- APP_NAME,
- "Sensor %s returned wrong ID 0x%02X, expected 0x%02X",
- sensor->name,
- id,
- BMP280_ID);
- return false;
- }
-
- //Чтение калибровочных значений
- if(!bmp280_readCalValues(i2c_sensor)) {
- FURI_LOG_E(APP_NAME, "Failed to read calibration values sensor %s", sensor->name);
- return false;
- }
- //Настройка режимов работы
- unitemp_i2c_writeReg(
- i2c_sensor,
- BMP280_REG_CTRL_MEAS,
- BMP280_TEMP_OVERSAMPLING_2 | BMP280_PRESS_OVERSAMPLING_4 | BMP280_MODE_NORMAL);
- //Настройка периода опроса и фильтрации значений
- unitemp_i2c_writeReg(
- i2c_sensor,
- BMP280_REG_CONFIG,
- BMP280_STANDBY_TIME_500 | BMP280_FILTER_COEFF_16 | BMP280_SPI_3W_DISABLE);
-
- return true;
-}
-
-bool unitemp_BMP280_deinit(Sensor* sensor) {
- I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
- //Перевод в сон
- unitemp_i2c_writeReg(i2c_sensor, BMP280_REG_CTRL_MEAS, BMP280_MODE_SLEEP);
- return true;
-}
-
-UnitempStatus unitemp_BMP280_update(Sensor* sensor) {
- I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
- BMP280_instance* instance = i2c_sensor->sensorInstance;
-
- uint32_t t = furi_get_tick();
-
- if(furi_get_tick() - instance->last_cal_update_time > BMP280_CAL_UPDATE_INTERVAL) {
- bmp280_readCalValues(i2c_sensor);
- }
-
- uint8_t buff[3];
- //Проверка инициализированности датчика
- unitemp_i2c_readRegArray(i2c_sensor, 0xF4, 2, buff);
- if(buff[0] == 0) {
- FURI_LOG_W(APP_NAME, "Sensor %s is not initialized!", sensor->name);
- return UT_SENSORSTATUS_ERROR;
- }
-
- while(bmp280_isMeasuring(sensor)) {
- if(furi_get_tick() - t > 100) {
- return UT_SENSORSTATUS_TIMEOUT;
- }
- }
-
- if(!unitemp_i2c_readRegArray(i2c_sensor, 0xFA, 3, buff)) return UT_SENSORSTATUS_TIMEOUT;
- int32_t adc_T = ((int32_t)buff[0] << 12) | ((int32_t)buff[1] << 4) | ((int32_t)buff[2] >> 4);
- if(!unitemp_i2c_readRegArray(i2c_sensor, 0xF7, 3, buff)) return UT_SENSORSTATUS_TIMEOUT;
- int32_t adc_P = ((int32_t)buff[0] << 12) | ((int32_t)buff[1] << 4) | ((int32_t)buff[2] >> 4);
- sensor->temp = bmp280_compensate_T_float(i2c_sensor, adc_T);
- sensor->pressure = bmp280_compensate_P_float(i2c_sensor, adc_P);
- return UT_SENSORSTATUS_OK;
-}
-
-bool unitemp_BMP280_free(Sensor* sensor) {
- I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
- free(i2c_sensor->sensorInstance);
- return true;
-}
\ No newline at end of file
diff --git a/sensors/BMx280.c b/sensors/BMx280.c
new file mode 100644
index 0000000..a64daaa
--- /dev/null
+++ b/sensors/BMx280.c
@@ -0,0 +1,352 @@
+/*
+ Unitemp - Universal temperature reader
+ Copyright (C) 2022 Victor Nikitchuk (https://github.com/quen0n)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+#include "BMx280.h"
+
+const SensorType BMP280 = {
+ .typename = "BMP280",
+ .interface = &I2C,
+ .datatype = UT_TEMPERATURE | UT_PRESSURE,
+ .pollingInterval = 500,
+ .allocator = unitemp_BMx280_alloc,
+ .mem_releaser = unitemp_BMx280_free,
+ .initializer = unitemp_BMx280_init,
+ .deinitializer = unitemp_BMx280_deinit,
+ .updater = unitemp_BMx280_update};
+const SensorType BME280 = {
+ .typename = "BME280",
+ .interface = &I2C,
+ .datatype = UT_TEMPERATURE | UT_HUMIDITY | UT_PRESSURE,
+
+ .pollingInterval = 500,
+ .allocator = unitemp_BMx280_alloc,
+ .mem_releaser = unitemp_BMx280_free,
+ .initializer = unitemp_BMx280_init,
+ .deinitializer = unitemp_BMx280_deinit,
+ .updater = unitemp_BMx280_update};
+
+//Интервал обновления калибровочных значений
+#define BOSCH_CAL_UPDATE_INTERVAL 60000
+
+#define TEMP_CAL_START_ADDR 0x88
+#define PRESS_CAL_START_ADDR 0x8E
+#define HUM_CAL_H1_ADDR 0xA1
+#define HUM_CAL_H2_ADDR 0xE1
+
+#define BMP280_ID 0x58
+#define BME280_ID 0x60
+
+#define BMx280_I2C_ADDR_MIN (0x76 << 1)
+#define BMx280_I2C_ADDR_MAX (0x77 << 1)
+
+#define BMx280_REG_STATUS 0xF3
+#define BMx280_REG_CTRL_MEAS 0xF4
+#define BMx280_REG_CONFIG 0xF5
+#define BME280_REG_CTRL_HUM 0xF2
+//Преддескретизация температуры
+#define BMx280_TEMP_OVERSAMPLING_SKIP 0b00000000
+#define BMx280_TEMP_OVERSAMPLING_1 0b00100000
+#define BMx280_TEMP_OVERSAMPLING_2 0b01000000
+#define BMx280_TEMP_OVERSAMPLING_4 0b01100000
+#define BMx280_TEMP_OVERSAMPLING_8 0b10000000
+#define BMx280_TEMP_OVERSAMPLING_16 0b10100000
+//Преддескретизация давления
+#define BMx280_PRESS_OVERSAMPLING_SKIP 0b00000000
+#define BMx280_PRESS_OVERSAMPLING_1 0b00000100
+#define BMx280_PRESS_OVERSAMPLING_2 0b00001000
+#define BMx280_PRESS_OVERSAMPLING_4 0b00001100
+#define BMx280_PRESS_OVERSAMPLING_8 0b00010000
+#define BMx280_PRESS_OVERSAMPLING_16 0b00010100
+//Преддескретизация влажности
+#define BME280_HUM_OVERSAMPLING_SKIP 0b00000000
+#define BME280_HUM_OVERSAMPLING_1 0b00000001
+#define BME280_HUM_OVERSAMPLING_2 0b00000010
+#define BME280_HUM_OVERSAMPLING_4 0b00000011
+#define BME280_HUM_OVERSAMPLING_8 0b00000100
+#define BME280_HUM_OVERSAMPLING_16 0b00000101u
+//Режимы работы датчика
+#define BMx280_MODE_SLEEP 0b00000000 //Наелся и спит
+#define BMx280_MODE_FORCED 0b00000001 //Обновляет значения 1 раз, после чего уходит в сон
+#define BMx280_MODE_NORMAL 0b00000011 //Регулярно обновляет значения
+//Период обновления в нормальном режиме
+#define BMx280_STANDBY_TIME_0_5 0b00000000
+#define BMx280_STANDBY_TIME_62_5 0b00100000
+#define BMx280_STANDBY_TIME_125 0b01000000
+#define BMx280_STANDBY_TIME_250 0b01100000
+#define BMx280_STANDBY_TIME_500 0b10000000
+#define BMx280_STANDBY_TIME_1000 0b10100000
+#define BMx280_STANDBY_TIME_2000 0b11000000
+#define BMx280_STANDBY_TIME_4000 0b11100000
+//Коэффициент фильтрации значений
+#define BMx280_FILTER_COEFF_1 0b00000000
+#define BMx280_FILTER_COEFF_2 0b00000100
+#define BMx280_FILTER_COEFF_4 0b00001000
+#define BMx280_FILTER_COEFF_8 0b00001100
+#define BMx280_FILTER_COEFF_16 0b00010000
+//Разрешить работу по SPI
+#define BMx280_SPI_3W_ENABLE 0b00000001
+#define BMx280_SPI_3W_DISABLE 0b00000000
+
+static float BMx280_compensate_temperature(I2CSensor* i2c_sensor, int32_t adc_T) {
+ BMx280_instance* bmx280_instance = (BMx280_instance*)i2c_sensor->sensorInstance;
+ int32_t var1, var2;
+ var1 = ((((adc_T >> 3) - ((int32_t)bmx280_instance->temp_cal.dig_T1 << 1))) *
+ ((int32_t)bmx280_instance->temp_cal.dig_T2)) >>
+ 11;
+ var2 = (((((adc_T >> 4) - ((int32_t)bmx280_instance->temp_cal.dig_T1)) *
+ ((adc_T >> 4) - ((int32_t)bmx280_instance->temp_cal.dig_T1))) >>
+ 12) *
+ ((int32_t)bmx280_instance->temp_cal.dig_T3)) >>
+ 14;
+ bmx280_instance->t_fine = var1 + var2;
+ return ((bmx280_instance->t_fine * 5 + 128) >> 8) / 100.0f;
+}
+
+static float BMx280_compensate_pressure(I2CSensor* i2c_sensor, int32_t adc_P) {
+ BMx280_instance* bmx280_instance = (BMx280_instance*)i2c_sensor->sensorInstance;
+
+ int32_t var1, var2;
+ uint32_t p;
+ var1 = (((int32_t)bmx280_instance->t_fine) >> 1) - (int32_t)64000;
+ var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t)bmx280_instance->press_cal.dig_P6);
+ var2 = var2 + ((var1 * ((int32_t)bmx280_instance->press_cal.dig_P5)) << 1);
+ var2 = (var2 >> 2) + (((int32_t)bmx280_instance->press_cal.dig_P4) << 16);
+ var1 = (((bmx280_instance->press_cal.dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) +
+ ((((int32_t)bmx280_instance->press_cal.dig_P2) * var1) >> 1)) >>
+ 18;
+ var1 = ((((32768 + var1)) * ((int32_t)bmx280_instance->press_cal.dig_P1)) >> 15);
+ if(var1 == 0) {
+ return 0; // avoid exception caused by division by zero
+ }
+ p = (((uint32_t)(((int32_t)1048576) - adc_P) - (var2 >> 12))) * 3125;
+ if(p < 0x80000000) {
+ p = (p << 1) / ((uint32_t)var1);
+ } else {
+ p = (p / (uint32_t)var1) * 2;
+ }
+ var1 = (((int32_t)bmx280_instance->press_cal.dig_P9) *
+ ((int32_t)(((p >> 3) * (p >> 3)) >> 13))) >>
+ 12;
+ var2 = (((int32_t)(p >> 2)) * ((int32_t)bmx280_instance->press_cal.dig_P8)) >> 13;
+ p = (uint32_t)((int32_t)p + ((var1 + var2 + bmx280_instance->press_cal.dig_P7) >> 4));
+ return p;
+}
+
+static float BMx280_compensate_humidity(I2CSensor* i2c_sensor, int32_t adc_H) {
+ BMx280_instance* bmx280_instance = (BMx280_instance*)i2c_sensor->sensorInstance;
+ int32_t v_x1_u32r;
+ v_x1_u32r = (bmx280_instance->t_fine - ((int32_t)76800));
+
+ v_x1_u32r =
+ (((((adc_H << 14) - (((int32_t)bmx280_instance->hum_cal.dig_H4) << 20) -
+ (((int32_t)bmx280_instance->hum_cal.dig_H5) * v_x1_u32r)) +
+ ((int32_t)16384)) >>
+ 15) *
+ (((((((v_x1_u32r * ((int32_t)bmx280_instance->hum_cal.dig_H6)) >> 10) *
+ (((v_x1_u32r * ((int32_t)bmx280_instance->hum_cal.dig_H3)) >> 11) +
+ ((int32_t)32768))) >>
+ 10) +
+ ((int32_t)2097152)) *
+ ((int32_t)bmx280_instance->hum_cal.dig_H2) +
+ 8192) >>
+ 14));
+
+ v_x1_u32r =
+ (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
+ ((int32_t)bmx280_instance->hum_cal.dig_H1)) >>
+ 4));
+
+ v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
+ v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
+ return ((uint32_t)(v_x1_u32r >> 12)) / 1024.0f;
+}
+
+static bool bmx280_readCalValues(I2CSensor* i2c_sensor) {
+ BMx280_instance* bmx280_instance = (BMx280_instance*)i2c_sensor->sensorInstance;
+ if(!unitemp_i2c_readRegArray(
+ i2c_sensor, TEMP_CAL_START_ADDR, 6, (uint8_t*)&bmx280_instance->temp_cal))
+ return false;
+#ifdef UNITEMP_DEBUG
+ FURI_LOG_D(
+ APP_NAME,
+ "Sensor BMx280 (0x%02X) T1-T3: %d, %d, %d",
+ i2c_sensor->currentI2CAdr,
+ bmx280_instance->temp_cal.dig_T1,
+ bmx280_instance->temp_cal.dig_T2,
+ bmx280_instance->temp_cal.dig_T3);
+#endif
+
+ if(!unitemp_i2c_readRegArray(
+ i2c_sensor, PRESS_CAL_START_ADDR, 18, (uint8_t*)&bmx280_instance->press_cal))
+ return false;
+#ifdef UNITEMP_DEBUG
+ FURI_LOG_D(
+ APP_NAME,
+ "Sensor BMx280 (0x%02X): P1-P9: %d, %d, %d, %d, %d, %d, %d, %d, %d",
+ i2c_sensor->currentI2CAdr,
+ bmx280_instance->press_cal.dig_P1,
+ bmx280_instance->press_cal.dig_P2,
+ bmx280_instance->press_cal.dig_P3,
+ bmx280_instance->press_cal.dig_P4,
+ bmx280_instance->press_cal.dig_P5,
+ bmx280_instance->press_cal.dig_P6,
+ bmx280_instance->press_cal.dig_P7,
+ bmx280_instance->press_cal.dig_P8,
+ bmx280_instance->press_cal.dig_P9);
+#endif
+
+ if(bmx280_instance->chip_id == BME280_ID) {
+ uint8_t buff[7] = {0};
+ if(!unitemp_i2c_readRegArray(i2c_sensor, HUM_CAL_H1_ADDR, 1, buff)) return false;
+ bmx280_instance->hum_cal.dig_H1 = buff[0];
+
+ if(!unitemp_i2c_readRegArray(i2c_sensor, HUM_CAL_H2_ADDR, 7, buff)) return false;
+ bmx280_instance->hum_cal.dig_H2 = (uint16_t)(buff[0] | ((uint16_t)buff[1] << 8));
+ bmx280_instance->hum_cal.dig_H3 = buff[2];
+ bmx280_instance->hum_cal.dig_H4 = ((int16_t)buff[3] << 4) | (buff[4] & 0x0F);
+ bmx280_instance->hum_cal.dig_H5 = (buff[4] & 0x0F) | ((int16_t)buff[5] << 4);
+ bmx280_instance->hum_cal.dig_H6 = buff[6];
+
+#ifdef UNITEMP_DEBUG
+ FURI_LOG_D(
+ APP_NAME,
+ "Sensor BMx280 (0x%02X): H1-H6: %d, %d, %d, %d, %d, %d",
+ i2c_sensor->currentI2CAdr,
+ bmx280_instance->hum_cal.dig_H1,
+ bmx280_instance->hum_cal.dig_H2,
+ bmx280_instance->hum_cal.dig_H3,
+ bmx280_instance->hum_cal.dig_H4,
+ bmx280_instance->hum_cal.dig_H5,
+ bmx280_instance->hum_cal.dig_H6);
+#endif
+ }
+
+ bmx280_instance->last_cal_update_time = furi_get_tick();
+ return true;
+}
+static bool bmp280_isMeasuring(Sensor* sensor) {
+ I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+ return (bool)((unitemp_i2c_readReg(i2c_sensor, BMx280_REG_STATUS) & 0x08) >> 3);
+}
+
+bool unitemp_BMx280_alloc(Sensor* sensor, char* args) {
+ UNUSED(args);
+ I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+ BMx280_instance* bmx280_instance = malloc(sizeof(BMx280_instance));
+ if(bmx280_instance == NULL) {
+ FURI_LOG_E(APP_NAME, "Failed to allocation sensor %s instance", sensor->name);
+ return false;
+ }
+
+ if(sensor->type == &BMP280) bmx280_instance->chip_id = BMP280_ID;
+ if(sensor->type == &BME280) bmx280_instance->chip_id = BME280_ID;
+
+ i2c_sensor->sensorInstance = bmx280_instance;
+
+ i2c_sensor->minI2CAdr = BMx280_I2C_ADDR_MIN;
+ i2c_sensor->maxI2CAdr = BMx280_I2C_ADDR_MAX;
+ return true;
+}
+
+bool unitemp_BMx280_init(Sensor* sensor) {
+ I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+ //Перезагрузка
+ unitemp_i2c_writeReg(i2c_sensor, 0xE0, 0xB6);
+ //Чтение ID датчика
+ uint8_t id = unitemp_i2c_readReg(i2c_sensor, 0xD0);
+ if(id != BMP280_ID && id != BME280_ID) {
+ FURI_LOG_E(
+ APP_NAME,
+ "Sensor %s returned wrong ID 0x%02X, expected 0x%02X or 0x%02X",
+ sensor->name,
+ id,
+ BMP280_ID,
+ BME280_ID);
+ return false;
+ }
+
+ //Настройка режимов работы
+ if(id == BME280_ID) {
+ unitemp_i2c_writeReg(i2c_sensor, BME280_REG_CTRL_HUM, BME280_HUM_OVERSAMPLING_1);
+ unitemp_i2c_writeReg(
+ i2c_sensor, BME280_REG_CTRL_HUM, unitemp_i2c_readReg(i2c_sensor, BME280_REG_CTRL_HUM));
+ }
+ unitemp_i2c_writeReg(
+ i2c_sensor,
+ BMx280_REG_CTRL_MEAS,
+ BMx280_TEMP_OVERSAMPLING_2 | BMx280_PRESS_OVERSAMPLING_4 | BMx280_MODE_NORMAL);
+ //Настройка периода опроса и фильтрации значений
+ unitemp_i2c_writeReg(
+ i2c_sensor,
+ BMx280_REG_CONFIG,
+ BMx280_STANDBY_TIME_500 | BMx280_FILTER_COEFF_16 | BMx280_SPI_3W_DISABLE);
+ //Чтение калибровочных значений
+ if(!bmx280_readCalValues(i2c_sensor)) {
+ FURI_LOG_E(APP_NAME, "Failed to read calibration values sensor %s", sensor->name);
+ return false;
+ }
+ return true;
+}
+
+bool unitemp_BMx280_deinit(Sensor* sensor) {
+ I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+ //Перевод в сон
+ unitemp_i2c_writeReg(i2c_sensor, BMx280_REG_CTRL_MEAS, BMx280_MODE_SLEEP);
+ return true;
+}
+
+UnitempStatus unitemp_BMx280_update(Sensor* sensor) {
+ I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+ BMx280_instance* instance = i2c_sensor->sensorInstance;
+
+ uint32_t t = furi_get_tick();
+
+ uint8_t buff[3];
+ //Проверка инициализированности датчика
+ unitemp_i2c_readRegArray(i2c_sensor, 0xF4, 2, buff);
+ if(buff[0] == 0) {
+ FURI_LOG_W(APP_NAME, "Sensor %s is not initialized!", sensor->name);
+ return UT_SENSORSTATUS_ERROR;
+ }
+
+ while(bmp280_isMeasuring(sensor)) {
+ if(furi_get_tick() - t > 100) {
+ return UT_SENSORSTATUS_TIMEOUT;
+ }
+ }
+
+ if(furi_get_tick() - instance->last_cal_update_time > BOSCH_CAL_UPDATE_INTERVAL) {
+ bmx280_readCalValues(i2c_sensor);
+ }
+
+ if(!unitemp_i2c_readRegArray(i2c_sensor, 0xFA, 3, buff)) return UT_SENSORSTATUS_TIMEOUT;
+ int32_t adc_T = ((int32_t)buff[0] << 12) | ((int32_t)buff[1] << 4) | ((int32_t)buff[2] >> 4);
+ if(!unitemp_i2c_readRegArray(i2c_sensor, 0xF7, 3, buff)) return UT_SENSORSTATUS_TIMEOUT;
+ int32_t adc_P = ((int32_t)buff[0] << 12) | ((int32_t)buff[1] << 4) | ((int32_t)buff[2] >> 4);
+ if(!unitemp_i2c_readRegArray(i2c_sensor, 0xFD, 2, buff)) return UT_SENSORSTATUS_TIMEOUT;
+ int32_t adc_H = ((uint16_t)buff[0] << 8) | buff[1];
+ sensor->temp = BMx280_compensate_temperature(i2c_sensor, adc_T);
+ sensor->pressure = BMx280_compensate_pressure(i2c_sensor, adc_P);
+ sensor->hum = BMx280_compensate_humidity(i2c_sensor, adc_H);
+ return UT_SENSORSTATUS_OK;
+}
+
+bool unitemp_BMx280_free(Sensor* sensor) {
+ I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+ free(i2c_sensor->sensorInstance);
+ return true;
+}
\ No newline at end of file
diff --git a/sensors/BMP280.h b/sensors/BMx280.h
similarity index 76%
rename from sensors/BMP280.h
rename to sensors/BMx280.h
index 3650909..fe52a36 100644
--- a/sensors/BMP280.h
+++ b/sensors/BMx280.h
@@ -15,8 +15,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#ifndef UNITEMP_BMP280
-#define UNITEMP_BMP280
+#ifndef UNITEMP_BMx280
+#define UNITEMP_BMx280
+
#include "../unitemp.h"
#include "../Sensors.h"
#include "../interfaces/I2CSensor.h"
@@ -25,7 +26,7 @@ typedef struct {
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
-} BMP280_temp_cal;
+} BMx280_temp_cal;
typedef struct {
uint16_t dig_P1;
@@ -37,51 +38,65 @@ typedef struct {
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
-} BMP280_press_cal;
+} BMx280_press_cal;
+
+typedef struct {
+ uint8_t dig_H1;
+ int16_t dig_H2;
+ uint8_t dig_H3;
+ int16_t dig_H4;
+ int16_t dig_H5;
+ int8_t dig_H6;
+} BMx280_hum_cal;
typedef struct {
//Калибровочные значения температуры
- BMP280_temp_cal temp_cal;
+ BMx280_temp_cal temp_cal;
//Калибровочные значения давления
- BMP280_press_cal press_cal;
+ BMx280_press_cal press_cal;
+ //Калибровочные значения влажности воздуха
+ BMx280_hum_cal hum_cal;
//Время последнего обновления калибровочных значений
uint32_t last_cal_update_time;
+ //Индификатор датчика
+ uint8_t chip_id;
//Корректировочное значение температуры
int32_t t_fine;
-} BMP280_instance;
+} BMx280_instance;
extern const SensorType BMP280;
+extern const SensorType BME280;
/**
* @brief Выделение памяти и установка начальных значений датчика BMP280
* @param sensor Указатель на создаваемый датчик
* @return Истина при успехе
*/
-bool unitemp_BMP280_alloc(Sensor* sensor, char* args);
+bool unitemp_BMx280_alloc(Sensor* sensor, char* args);
/**
* @brief Инициализации датчика BMP280
* @param sensor Указатель на датчик
* @return Истина если инициализация упспешная
*/
-bool unitemp_BMP280_init(Sensor* sensor);
+bool unitemp_BMx280_init(Sensor* sensor);
/**
* @brief Деинициализация датчика
* @param sensor Указатель на датчик
*/
-bool unitemp_BMP280_deinit(Sensor* sensor);
+bool unitemp_BMx280_deinit(Sensor* sensor);
/**
* @brief Обновление значений из датчика
* @param sensor Указатель на датчик
* @return Статус опроса датчика
*/
-UnitempStatus unitemp_BMP280_update(Sensor* sensor);
+UnitempStatus unitemp_BMx280_update(Sensor* sensor);
/**
* @brief Высвободить память датчика
* @param sensor Указатель на датчик
*/
-bool unitemp_BMP280_free(Sensor* sensor);
+bool unitemp_BMx280_free(Sensor* sensor);
#endif
\ No newline at end of file
diff --git a/views/General_view.c b/views/General_view.c
index 456ccb2..e21b04d 100644
--- a/views/General_view.c
+++ b/views/General_view.c
@@ -364,8 +364,8 @@ static void _draw_carousel_info(Canvas* canvas) {
((I2CSensor*)unitemp_sensor_getActive(generalview_sensor_index)->instance)
->currentI2CAdr);
canvas_draw_str(canvas, 57, 35, app->buff);
- canvas_draw_str(canvas, 54, 46, "16 (C1)");
- canvas_draw_str(canvas, 54, 58, "15 (C0)");
+ canvas_draw_str(canvas, 54, 46, "15 (C0)");
+ canvas_draw_str(canvas, 54, 58, "16 (C1)");
}
}
static void _draw_view_sensorsCarousel(Canvas* canvas) {