1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-27 07:32:22 +01:00

[htu21d] Fix I2C NACK issue and buffer overrun (#10801)

This commit is contained in:
Jonathan Swoboda
2025-09-25 16:54:38 -04:00
committed by GitHub
parent 28f09f9ed1
commit cef9cf49bf
2 changed files with 14 additions and 19 deletions

View File

@@ -9,8 +9,8 @@ static const char *const TAG = "htu21d";
static const uint8_t HTU21D_ADDRESS = 0x40; static const uint8_t HTU21D_ADDRESS = 0x40;
static const uint8_t HTU21D_REGISTER_RESET = 0xFE; static const uint8_t HTU21D_REGISTER_RESET = 0xFE;
static const uint8_t HTU21D_REGISTER_TEMPERATURE = 0xF3; static const uint8_t HTU21D_REGISTER_TEMPERATURE = 0xE3;
static const uint8_t HTU21D_REGISTER_HUMIDITY = 0xF5; static const uint8_t HTU21D_REGISTER_HUMIDITY = 0xE5;
static const uint8_t HTU21D_WRITERHT_REG_CMD = 0xE6; /**< Write RH/T User Register 1 */ static const uint8_t HTU21D_WRITERHT_REG_CMD = 0xE6; /**< Write RH/T User Register 1 */
static const uint8_t HTU21D_REGISTER_STATUS = 0xE7; static const uint8_t HTU21D_REGISTER_STATUS = 0xE7;
static const uint8_t HTU21D_WRITEHEATER_REG_CMD = 0x51; /**< Write Heater Control Register */ static const uint8_t HTU21D_WRITEHEATER_REG_CMD = 0x51; /**< Write Heater Control Register */
@@ -57,7 +57,6 @@ void HTU21DComponent::update() {
if (this->temperature_ != nullptr) if (this->temperature_ != nullptr)
this->temperature_->publish_state(temperature); this->temperature_->publish_state(temperature);
this->status_clear_warning();
if (this->write(&HTU21D_REGISTER_HUMIDITY, 1) != i2c::ERROR_OK) { if (this->write(&HTU21D_REGISTER_HUMIDITY, 1) != i2c::ERROR_OK) {
this->status_set_warning(); this->status_set_warning();
@@ -79,10 +78,11 @@ void HTU21DComponent::update() {
if (this->humidity_ != nullptr) if (this->humidity_ != nullptr)
this->humidity_->publish_state(humidity); this->humidity_->publish_state(humidity);
int8_t heater_level; this->status_clear_warning();
// HTU21D does have a heater module but does not have heater level // HTU21D does have a heater module but does not have heater level
// Setting heater level to 1 in case the heater is ON // Setting heater level to 1 in case the heater is ON
uint8_t heater_level = 0;
if (this->sensor_model_ == HTU21D_SENSOR_MODEL_HTU21D) { if (this->sensor_model_ == HTU21D_SENSOR_MODEL_HTU21D) {
if (this->is_heater_enabled()) { if (this->is_heater_enabled()) {
heater_level = 1; heater_level = 1;
@@ -97,34 +97,30 @@ void HTU21DComponent::update() {
if (this->heater_ != nullptr) if (this->heater_ != nullptr)
this->heater_->publish_state(heater_level); this->heater_->publish_state(heater_level);
this->status_clear_warning();
}); });
}); });
} }
bool HTU21DComponent::is_heater_enabled() { bool HTU21DComponent::is_heater_enabled() {
uint8_t raw_heater; uint8_t raw_heater;
if (this->read_register(HTU21D_REGISTER_STATUS, reinterpret_cast<uint8_t *>(&raw_heater), 2) != i2c::ERROR_OK) { if (this->read_register(HTU21D_REGISTER_STATUS, &raw_heater, 1) != i2c::ERROR_OK) {
this->status_set_warning(); this->status_set_warning();
return false; return false;
} }
raw_heater = i2c::i2ctohs(raw_heater); return (bool) ((raw_heater >> HTU21D_REG_HTRE_BIT) & 0x01);
return (bool) (((raw_heater) >> (HTU21D_REG_HTRE_BIT)) & 0x01);
} }
void HTU21DComponent::set_heater(bool status) { void HTU21DComponent::set_heater(bool status) {
uint8_t raw_heater; uint8_t raw_heater;
if (this->read_register(HTU21D_REGISTER_STATUS, reinterpret_cast<uint8_t *>(&raw_heater), 2) != i2c::ERROR_OK) { if (this->read_register(HTU21D_REGISTER_STATUS, &raw_heater, 1) != i2c::ERROR_OK) {
this->status_set_warning(); this->status_set_warning();
return; return;
} }
raw_heater = i2c::i2ctohs(raw_heater);
if (status) { if (status) {
raw_heater |= (1 << (HTU21D_REG_HTRE_BIT)); raw_heater |= (1 << HTU21D_REG_HTRE_BIT);
} else { } else {
raw_heater &= ~(1 << (HTU21D_REG_HTRE_BIT)); raw_heater &= ~(1 << HTU21D_REG_HTRE_BIT);
} }
if (this->write_register(HTU21D_WRITERHT_REG_CMD, &raw_heater, 1) != i2c::ERROR_OK) { if (this->write_register(HTU21D_WRITERHT_REG_CMD, &raw_heater, 1) != i2c::ERROR_OK) {
this->status_set_warning(); this->status_set_warning();
return; return;
@@ -138,14 +134,13 @@ void HTU21DComponent::set_heater_level(uint8_t level) {
} }
} }
int8_t HTU21DComponent::get_heater_level() { uint8_t HTU21DComponent::get_heater_level() {
int8_t raw_heater; uint8_t raw_heater;
if (this->read_register(HTU21D_READHEATER_REG_CMD, reinterpret_cast<uint8_t *>(&raw_heater), 2) != i2c::ERROR_OK) { if (this->read_register(HTU21D_READHEATER_REG_CMD, &raw_heater, 1) != i2c::ERROR_OK) {
this->status_set_warning(); this->status_set_warning();
return 0; return 0;
} }
raw_heater = i2c::i2ctohs(raw_heater); return raw_heater & 0xF;
return raw_heater;
} }
float HTU21DComponent::get_setup_priority() const { return setup_priority::DATA; } float HTU21DComponent::get_setup_priority() const { return setup_priority::DATA; }

View File

@@ -26,7 +26,7 @@ class HTU21DComponent : public PollingComponent, public i2c::I2CDevice {
bool is_heater_enabled(); bool is_heater_enabled();
void set_heater(bool status); void set_heater(bool status);
void set_heater_level(uint8_t level); void set_heater_level(uint8_t level);
int8_t get_heater_level(); uint8_t get_heater_level();
float get_setup_priority() const override; float get_setup_priority() const override;