diff --git a/firmware/common/i2cdev_bh1750.cpp b/firmware/common/i2cdev_bh1750.cpp index f4e20032c..500c2a2fc 100644 --- a/firmware/common/i2cdev_bh1750.cpp +++ b/firmware/common/i2cdev_bh1750.cpp @@ -32,7 +32,7 @@ namespace i2cdev { bool I2cDev_BH1750::init(uint8_t addr_) { if (addr_ != I2CDEV_BH1750_ADDR_1) return false; addr = addr_; - model = I2CDECMDL_BH1750; + model = I2CDEVMDL_BH1750; query_interval = 3; // power up diff --git a/firmware/common/i2cdev_sht4x.cpp b/firmware/common/i2cdev_sht4x.cpp new file mode 100644 index 000000000..ff0e99e22 --- /dev/null +++ b/firmware/common/i2cdev_sht4x.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 HTotoo. + * + * This file is part of PortaPack. + * + * 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 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "i2cdev_sht4x.hpp" + +namespace i2cdev { + +bool I2cDev_SHT4x::init(uint8_t addr_) { + if (addr_ != I2CDEV_SHT4X_ADDR_1 && addr_ != I2CDEV_SHT4X_ADDR_2) return false; + addr = addr_; // store the addr + model = I2C_DEVMDL::I2CDEVMDL_SHT4X; // set the device model!!!!!!!!!!!!!!!!!! + query_interval = 10; // set update interval in sec + chThdSleepMilliseconds(50); + uint8_t tmp[1]; // command buffer + uint8_t rx[6]; // response buffer + tmp[0] = SHT4X_SERIAL_NUMBER_CMD_ID; + if (!i2c_write(nullptr, 0, tmp, 1)) return false; // get serial number + chThdSleepMilliseconds(10); + if (!i2c_read(nullptr, 0, rx, 6)) return false; // read serial number + return true; +} + +void I2cDev_SHT4x::update() { + float temp = 0; + float hum = 0; + uint8_t cmd[1]; + cmd[0] = SHT4X_MEASURE_MEDIUM_PRECISION_TICKS_CMD_ID; + uint8_t res[6]; + if (!i2c_write(nullptr, 0, cmd, 1)) return; + chThdSleepMilliseconds(5); // wait for measurement, 10 for high precision, 5 for medium, 2 for low + if (!i2c_read(nullptr, 0, res, 6)) return; + uint16_t temptick = (uint16_t)res[0] << 8 | (uint16_t)res[1]; + uint16_t humtick = (uint16_t)res[3] << 8 | (uint16_t)res[4]; + + temp = -45 + (((float)temptick * 175.0) / 65535.0); + hum = -6 + 125.0 * (float)humtick / 65535.0; + if (hum < 0) hum = 0; + if (hum > 100) hum = 100; + EnvironmentDataMessage msg{temp, hum}; // create the system message + EventDispatcher::send_message(msg); // and send it +} + +} // namespace i2cdev \ No newline at end of file diff --git a/firmware/common/i2cdev_sht4x.hpp b/firmware/common/i2cdev_sht4x.hpp new file mode 100644 index 000000000..7ead63dc7 --- /dev/null +++ b/firmware/common/i2cdev_sht4x.hpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2025 HTotoo. + * + * This file is part of PortaPack. + * + * 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 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __I2CDEV_SHT4X_H__ +#define __I2CDEV_SHT4X_H__ + +#include "i2cdevmanager.hpp" + +namespace i2cdev { + +class I2cDev_SHT4x : public I2cDev { + public: + typedef enum { + SHT4X_MEASURE_HIGH_PRECISION_TICKS_CMD_ID = 0xfd, + SHT4X_MEASURE_MEDIUM_PRECISION_TICKS_CMD_ID = 0xf6, + SHT4X_MEASURE_LOWEST_PRECISION_TICKS_CMD_ID = 0xe0, + SHT4X_ACTIVATE_HIGHEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x39, + SHT4X_ACTIVATE_HIGHEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x32, + SHT4X_ACTIVATE_MEDIUM_HEATER_POWER_LONG_TICKS_CMD_ID = 0x2f, + SHT4X_ACTIVATE_MEDIUM_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x24, + SHT4X_ACTIVATE_LOWEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x1e, + SHT4X_ACTIVATE_LOWEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x15, + SHT4X_SERIAL_NUMBER_CMD_ID = 0x89, + SHT4X_SOFT_RESET_CMD_ID = 0x94, + } SHT4xCmdId; + bool init(uint8_t addr_) override; // sets the addr to our local variable, set the model, try to init the module, and only return true if it is really that module, and inited ok + void update() override; // query the module for recent data, and send it to the system via the corresponding Message + + private: + float read_temperature(); + float read_humidity(); +}; +} // namespace i2cdev + +#endif \ No newline at end of file diff --git a/firmware/common/i2cdevlist.hpp b/firmware/common/i2cdevlist.hpp index 34ad71269..4395af182 100644 --- a/firmware/common/i2cdevlist.hpp +++ b/firmware/common/i2cdevlist.hpp @@ -34,14 +34,18 @@ enum I2C_DEVMDL { I2CDEVMDL_SHT3X, I2CDEVMDL_BMP280, I2CDEVMDL_BME280, - I2CDECMDL_BH1750, + I2CDEVMDL_BH1750, I2CDECMDL_PPMOD, + I2CDEVMDL_SHT4X, }; #define I2CDEV_BMX280_ADDR_1 0x76 #define I2CDEV_BMX280_ADDR_2 0x77 #define I2CDEV_SHT3X_ADDR_1 0x44 #define I2CDEV_SHT3X_ADDR_2 0x45 +// sadly sht4x uses the same addr as sht3x, but the init script can decide which is which +#define I2CDEV_SHT4X_ADDR_1 0x44 +#define I2CDEV_SHT4X_ADDR_2 0x45 #define I2CDEV_MAX17055_ADDR_1 0x36 #define I2CDEV_ADS1110_ADDR_1 0x48 diff --git a/firmware/common/i2cdevmanager.cpp b/firmware/common/i2cdevmanager.cpp index 67a2ea57c..c1bef6a8e 100644 --- a/firmware/common/i2cdevmanager.cpp +++ b/firmware/common/i2cdevmanager.cpp @@ -32,6 +32,7 @@ #include "i2cdev_ads1110.hpp" #include "i2cdev_bh1750.hpp" #include "i2cdev_ppmod.hpp" +#include "i2cdev_sht4x.hpp" namespace i2cdev { @@ -73,6 +74,11 @@ bool I2CDevManager::found(uint8_t addr) { if (!item.dev->init(addr)) item.dev = nullptr; } + if (!item.dev && (addr == I2CDEV_SHT4X_ADDR_1 || addr == I2CDEV_SHT4X_ADDR_2)) { + item.dev = std::make_unique(); + if (!item.dev->init(addr)) item.dev = nullptr; + } + if (!item.dev && (addr == I2CDEV_MAX17055_ADDR_1)) { item.dev = std::make_unique(); if (!item.dev->init(addr)) item.dev = nullptr;