diff --git a/applications/plugins/unitemp/README.md b/applications/plugins/unitemp/README.md index baae10ee9..c40ed520a 100644 --- a/applications/plugins/unitemp/README.md +++ b/applications/plugins/unitemp/README.md @@ -1,10 +1,9 @@ ![Flipper usage](https://user-images.githubusercontent.com/10090793/206618263-c1e212e4-58dc-432e-87a8-5c19fd835b35.png) # Unitemp - Universal temperature sensor reader [![GitHub release](https://img.shields.io/github/release/quen0n/unitemp-flipperzero?include_prereleases=&sort=semver&color=blue)](https://github.com/quen0n/unitemp-flipperzero/releases/) -[![GitHub all releases](https://img.shields.io/github/downloads/quen0n/unitemp-flipperzero/total)]() [![GitHub](https://img.shields.io/github/license/quen0n/unitemp-flipperzero)](https://github.com/quen0n/unitemp-flipperzero/blob/dev/LICENSE.md) -[Flipper Zero](https://flipperzero.one/) application for reading temperature, pressure and pressure sensors using Onewire, Singlewire, I2C protocols. +[Flipper Zero](https://flipperzero.one/) application for reading temperature, humidity and pressure sensors using Onewire, Singlewire, I2C protocols. ## List of supported sensors (supplemented) -![image](https://user-images.githubusercontent.com/10090793/208480561-e98a6192-d44d-4ad9-8692-a91ccaae47c7.png) +![image](https://user-images.githubusercontent.com/10090793/208763931-d15e9883-1016-4add-bd00-14d7842fd82d.png) ## Installation Copy the contents of the repository to the `applications/plugins/unitemp` folder and build the project. Flash FZ along with resources. [More...](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/fbt.md) diff --git a/applications/plugins/unitemp/Sensors.c b/applications/plugins/unitemp/Sensors.c index d35e31931..f81daa827 100644 --- a/applications/plugins/unitemp/Sensors.c +++ b/applications/plugins/unitemp/Sensors.c @@ -71,8 +71,19 @@ 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, &BME280, &Dallas}; +static const SensorType* sensorTypes[] = { + &DHT11, + &DHT12_SW, + &DHT20, + &DHT21, + &DHT22, + &Dallas, + &AM2320_SW, + &AM2320_I2C, + &AHT10, + &LM75, + &BMP280, + &BME280}; const SensorType* unitemp_sensors_getTypeFromInt(uint8_t index) { if(index > SENSOR_TYPES_COUNT) return NULL; diff --git a/applications/plugins/unitemp/Sensors.h b/applications/plugins/unitemp/Sensors.h index 52e6165f5..cb98e1783 100644 --- a/applications/plugins/unitemp/Sensors.h +++ b/applications/plugins/unitemp/Sensors.h @@ -321,4 +321,5 @@ const GPIO* //BMP280, BME280 #include "./sensors/BMx280.h" #include "./sensors/AM2320.h" +#include "./sensors/DHT20.h" #endif diff --git a/applications/plugins/unitemp/interfaces/SingleWireSensor.c b/applications/plugins/unitemp/interfaces/SingleWireSensor.c index 183bfc872..e601e086e 100644 --- a/applications/plugins/unitemp/interfaces/SingleWireSensor.c +++ b/applications/plugins/unitemp/interfaces/SingleWireSensor.c @@ -43,7 +43,7 @@ const SensorType DHT12_SW = { .updater = unitemp_singlewire_update}; const SensorType DHT21 = { .typename = "DHT21", - .altname = "DHT21 (AM2301)", + .altname = "DHT21/AM2301", .interface = &SINGLE_WIRE, .datatype = UT_DATA_TYPE_TEMP_HUM, .pollingInterval = 1000, @@ -54,7 +54,7 @@ const SensorType DHT21 = { .updater = unitemp_singlewire_update}; const SensorType DHT22 = { .typename = "DHT22", - .altname = "DHT22 (AM2302)", + .altname = "DHT22/AM2302", .interface = &SINGLE_WIRE, .datatype = UT_DATA_TYPE_TEMP_HUM, .pollingInterval = 2000, diff --git a/applications/plugins/unitemp/sensors/DHT20.c b/applications/plugins/unitemp/sensors/DHT20.c index ee1b042c9..f16e8dfc1 100644 --- a/applications/plugins/unitemp/sensors/DHT20.c +++ b/applications/plugins/unitemp/sensors/DHT20.c @@ -20,15 +20,62 @@ const SensorType DHT20 = { .typename = "DHT20", - .altname = "DHT20 (AM2108)", + .altname = "DHT20/AM2108/AHT20", .interface = &I2C, .datatype = UT_TEMPERATURE | UT_HUMIDITY, - .pollingInterval = 2000, + .pollingInterval = 1000, .allocator = unitemp_DHT20_I2C_alloc, .mem_releaser = unitemp_DHT20_I2C_free, .initializer = unitemp_DHT20_init, .deinitializer = unitemp_DHT20_I2C_deinit, .updater = unitemp_DHT20_I2C_update}; +const SensorType AHT10 = { + .typename = "AHT10", + .interface = &I2C, + .datatype = UT_TEMPERATURE | UT_HUMIDITY, + .pollingInterval = 1000, + .allocator = unitemp_DHT20_I2C_alloc, + .mem_releaser = unitemp_DHT20_I2C_free, + .initializer = unitemp_DHT20_init, + .deinitializer = unitemp_DHT20_I2C_deinit, + .updater = unitemp_DHT20_I2C_update}; + +static uint8_t DHT20_get_status(I2CSensor* i2c_sensor) { + uint8_t status[1] = {0}; + unitemp_i2c_readArray(i2c_sensor, 1, status); + return status[0]; +} + +static uint8_t DHT20_calc_CRC8(uint8_t* message, uint8_t Num) { + uint8_t i; + uint8_t byte; + uint8_t crc = 0xFF; + for(byte = 0; byte < Num; byte++) { + crc ^= (message[byte]); + for(i = 8; i > 0; --i) { + if(crc & 0x80) + crc = (crc << 1) ^ 0x31; + else + crc = (crc << 1); + } + } + return crc; +} + +static void DHT20_reset_reg(I2CSensor* i2c_sensor, uint8_t addr) { + uint8_t data[3] = {addr, 0x00, 0x00}; + + unitemp_i2c_writeArray(i2c_sensor, 3, data); + + furi_delay_ms(5); + + unitemp_i2c_readArray(i2c_sensor, 3, data); + + furi_delay_ms(10); + + data[0] = 0xB0 | addr; + unitemp_i2c_writeArray(i2c_sensor, 3, data); +} bool unitemp_DHT20_I2C_alloc(Sensor* sensor, char* args) { UNUSED(args); @@ -36,7 +83,7 @@ bool unitemp_DHT20_I2C_alloc(Sensor* sensor, char* args) { //Адреса на шине I2C (7 бит) i2c_sensor->minI2CAdr = 0x38 << 1; - i2c_sensor->maxI2CAdr = 0x38 << 1; + i2c_sensor->maxI2CAdr = (sensor->type == &DHT20) ? (0x38 << 1) : (0x39 << 1); return true; } @@ -47,8 +94,16 @@ bool unitemp_DHT20_I2C_free(Sensor* sensor) { } bool unitemp_DHT20_init(Sensor* sensor) { - //Нечего инициализировать - UNUSED(sensor); + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + + uint8_t data[3] = {0xA8, 0x00, 0x00}; + if(!unitemp_i2c_writeArray(i2c_sensor, 3, data)) return false; + furi_delay_ms(10); + data[0] = (sensor->type == &DHT20) ? 0xBE : 0xE1; + data[1] = 0x08; + if(!unitemp_i2c_writeArray(i2c_sensor, 3, data)) return false; + furi_delay_ms(10); + return true; } @@ -59,7 +114,41 @@ bool unitemp_DHT20_I2C_deinit(Sensor* sensor) { } UnitempStatus unitemp_DHT20_I2C_update(Sensor* sensor) { - //I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; - UNUSED(sensor); + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + + if(DHT20_get_status(i2c_sensor) != 0x18) { + DHT20_reset_reg(i2c_sensor, 0x1B); + DHT20_reset_reg(i2c_sensor, 0x1C); + DHT20_reset_reg(i2c_sensor, 0x1E); + } + furi_delay_ms(10); + + uint8_t data[7] = {0xAC, 0x33, 0x00}; + if(!unitemp_i2c_writeArray(i2c_sensor, 3, data)) return UT_SENSORSTATUS_TIMEOUT; + furi_delay_ms(80); + uint32_t t = furi_get_tick(); + while(DHT20_get_status(i2c_sensor) == 0x80) { + if(furi_get_tick() - t > 10) return UT_SENSORSTATUS_TIMEOUT; + } + + if(!unitemp_i2c_readArray(i2c_sensor, 7, data)) return UT_SENSORSTATUS_TIMEOUT; + + if(DHT20_calc_CRC8(data, 6) != data[6]) { + return UT_SENSORSTATUS_BADCRC; + } + uint32_t RetuData = 0; + RetuData = (RetuData | data[1]) << 8; + RetuData = (RetuData | data[2]) << 8; + RetuData = (RetuData | data[3]); + RetuData = RetuData >> 4; + sensor->hum = RetuData * 100 * 10 / 1024.0f / 1024.0f / 10.0f; + + RetuData = 0; + RetuData = (RetuData | data[3]) << 8; + RetuData = (RetuData | data[4]) << 8; + RetuData = (RetuData | data[5]); + RetuData = RetuData & 0xfffff; + sensor->temp = (RetuData * 200 * 10.0f / 1024.0f / 1024.0f - 500) / 10.0f; + return UT_SENSORSTATUS_OK; } diff --git a/applications/plugins/unitemp/sensors/DHT20.h b/applications/plugins/unitemp/sensors/DHT20.h index e2e89bf18..db49495dc 100644 --- a/applications/plugins/unitemp/sensors/DHT20.h +++ b/applications/plugins/unitemp/sensors/DHT20.h @@ -21,6 +21,7 @@ #include "../unitemp.h" #include "../Sensors.h" extern const SensorType DHT20; +extern const SensorType AHT10; /** * @brief Выделение памяти и установка начальных значений датчика DHT20 * diff --git a/applications/plugins/unitemp/sensors/Sensors.xlsx b/applications/plugins/unitemp/sensors/Sensors.xlsx index 2b6578e0e..03522a643 100644 Binary files a/applications/plugins/unitemp/sensors/Sensors.xlsx and b/applications/plugins/unitemp/sensors/Sensors.xlsx differ diff --git a/applications/plugins/unitemp/views/General_view.c b/applications/plugins/unitemp/views/General_view.c index e21b04de2..fc1408b1a 100644 --- a/applications/plugins/unitemp/views/General_view.c +++ b/applications/plugins/unitemp/views/General_view.c @@ -362,7 +362,8 @@ static void _draw_carousel_info(Canvas* canvas) { BUFF_SIZE, "0x%02X", ((I2CSensor*)unitemp_sensor_getActive(generalview_sensor_index)->instance) - ->currentI2CAdr); + ->currentI2CAdr >> + 1); canvas_draw_str(canvas, 57, 35, app->buff); canvas_draw_str(canvas, 54, 46, "15 (C0)"); canvas_draw_str(canvas, 54, 58, "16 (C1)"); diff --git a/applications/plugins/unitemp/views/SensorEdit_view.c b/applications/plugins/unitemp/views/SensorEdit_view.c index 4d5bc17db..d1660bc2e 100644 --- a/applications/plugins/unitemp/views/SensorEdit_view.c +++ b/applications/plugins/unitemp/views/SensorEdit_view.c @@ -214,9 +214,9 @@ static void _gpio_change_callback(VariableItem* item) { static void _i2caddr_change_callback(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); ((I2CSensor*)editable_sensor->instance)->currentI2CAdr = - ((I2CSensor*)editable_sensor->instance)->minI2CAdr + index; + ((I2CSensor*)editable_sensor->instance)->minI2CAdr + index * 2; char buff[5]; - snprintf(buff, 5, "0x%2X", ((I2CSensor*)editable_sensor->instance)->currentI2CAdr); + snprintf(buff, 5, "0x%2X", ((I2CSensor*)editable_sensor->instance)->currentI2CAdr >> 1); variable_item_set_current_value_text(item, buff); } /** @@ -335,11 +335,15 @@ void unitemp_SensorEdit_switch(Sensor* sensor) { VariableItem* item = variable_item_list_add( variable_item_list, "I2C address", - ((I2CSensor*)sensor->instance)->maxI2CAdr - ((I2CSensor*)sensor->instance)->minI2CAdr + - 1, + (((I2CSensor*)sensor->instance)->maxI2CAdr >> 1) - + (((I2CSensor*)sensor->instance)->minI2CAdr >> 1) + 1, _i2caddr_change_callback, app); - snprintf(app->buff, 5, "0x%2X", ((I2CSensor*)sensor->instance)->currentI2CAdr); + snprintf(app->buff, 5, "0x%2X", ((I2CSensor*)sensor->instance)->currentI2CAdr >> 1); + variable_item_set_current_value_index( + item, + (((I2CSensor*)sensor->instance)->currentI2CAdr >> 1) - + (((I2CSensor*)sensor->instance)->minI2CAdr >> 1)); variable_item_set_current_value_text(item, app->buff); }