ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
htu21d.cpp
Go to the documentation of this file.
1#include "htu21d.h"
2#include "esphome/core/log.h"
3#include "esphome/core/hal.h"
4
5namespace esphome::htu21d {
6
7static const char *const TAG = "htu21d";
8
9static const uint8_t HTU21D_ADDRESS = 0x40;
10static const uint8_t HTU21D_REGISTER_RESET = 0xFE;
11static const uint8_t HTU21D_REGISTER_TEMPERATURE = 0xF3;
12static const uint8_t HTU21D_REGISTER_HUMIDITY = 0xF5;
13static const uint8_t HTU21D_WRITERHT_REG_CMD = 0xE6;
14static const uint8_t HTU21D_REGISTER_STATUS = 0xE7;
15static const uint8_t HTU21D_WRITEHEATER_REG_CMD = 0x51;
16static const uint8_t HTU21D_READHEATER_REG_CMD = 0x11;
17static const uint8_t HTU21D_REG_HTRE_BIT = 0x02;
20 if (!this->write_bytes(HTU21D_REGISTER_RESET, nullptr, 0)) {
21 this->mark_failed();
22 return;
23 }
24
25 // Wait for software reset to complete
26 delay(15);
27}
29 ESP_LOGCONFIG(TAG, "HTU21D:");
30 LOG_I2C_DEVICE(this);
31 if (this->is_failed()) {
32 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
33 }
34 LOG_UPDATE_INTERVAL(this);
35 LOG_SENSOR(" ", "Temperature", this->temperature_);
36 LOG_SENSOR(" ", "Humidity", this->humidity_);
37}
39 if (this->write(&HTU21D_REGISTER_TEMPERATURE, 1) != i2c::ERROR_OK) {
40 this->status_set_warning();
41 return;
42 }
43
44 // According to the datasheet sht21 temperature readings can take up to 85ms
45 this->set_timeout(85, [this]() {
46 uint16_t raw_temperature;
47 if (this->read(reinterpret_cast<uint8_t *>(&raw_temperature), 2) != i2c::ERROR_OK) {
48 this->status_set_warning();
49 return;
50 }
51 raw_temperature = i2c::i2ctohs(raw_temperature);
52
53 float temperature = (float(raw_temperature & 0xFFFC)) * 175.72f / 65536.0f - 46.85f;
54
55 ESP_LOGD(TAG, "Got Temperature=%.1f°C", temperature);
56
57 if (this->temperature_ != nullptr)
58 this->temperature_->publish_state(temperature);
59
60 if (this->write(&HTU21D_REGISTER_HUMIDITY, 1) != i2c::ERROR_OK) {
61 this->status_set_warning();
62 return;
63 }
64
65 this->set_timeout(50, [this]() {
66 uint16_t raw_humidity;
67 if (this->read(reinterpret_cast<uint8_t *>(&raw_humidity), 2) != i2c::ERROR_OK) {
68 this->status_set_warning();
69 return;
70 }
71 raw_humidity = i2c::i2ctohs(raw_humidity);
72
73 float humidity = (float(raw_humidity & 0xFFFC)) * 125.0f / 65536.0f - 6.0f;
74
75 ESP_LOGD(TAG, "Got Humidity=%.1f%%", humidity);
76
77 if (this->humidity_ != nullptr)
78 this->humidity_->publish_state(humidity);
79
81
82 // HTU21D does have a heater module but does not have heater level
83 // Setting heater level to 1 in case the heater is ON
84 uint8_t heater_level = 0;
86 if (this->is_heater_enabled()) {
87 heater_level = 1;
88 } else {
89 heater_level = 0;
90 }
91 } else {
92 heater_level = this->get_heater_level();
93 }
94
95 ESP_LOGD(TAG, "Heater Level=%d", heater_level);
96
97 if (this->heater_ != nullptr)
98 this->heater_->publish_state(heater_level);
99 });
100 });
101}
102
104 uint8_t raw_heater;
105 if (this->read_register(HTU21D_REGISTER_STATUS, &raw_heater, 1) != i2c::ERROR_OK) {
106 this->status_set_warning();
107 return false;
108 }
109 return (bool) ((raw_heater >> HTU21D_REG_HTRE_BIT) & 0x01);
110}
111
113 uint8_t raw_heater;
114 if (this->read_register(HTU21D_REGISTER_STATUS, &raw_heater, 1) != i2c::ERROR_OK) {
115 this->status_set_warning();
116 return;
117 }
118 if (status) {
119 raw_heater |= (1 << HTU21D_REG_HTRE_BIT);
120 } else {
121 raw_heater &= ~(1 << HTU21D_REG_HTRE_BIT);
122 }
123 if (this->write_register(HTU21D_WRITERHT_REG_CMD, &raw_heater, 1) != i2c::ERROR_OK) {
124 this->status_set_warning();
125 return;
126 }
127}
128
130 if (this->write_register(HTU21D_WRITEHEATER_REG_CMD, &level, 1) != i2c::ERROR_OK) {
131 this->status_set_warning();
132 return;
133 }
134}
135
137 uint8_t raw_heater;
138 if (this->read_register(HTU21D_READHEATER_REG_CMD, &raw_heater, 1) != i2c::ERROR_OK) {
139 this->status_set_warning();
140 return 0;
141 }
142 return raw_heater & 0xF;
143}
144
145} // namespace esphome::htu21d
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:493
void status_clear_warning()
Definition component.h:289
sensor::Sensor * humidity_
Definition htu21d.h:32
sensor::Sensor * temperature_
Definition htu21d.h:31
void set_heater(sensor::Sensor *heater)
Definition htu21d.h:16
void update() override
Update the sensor values (temperature+humidity).
Definition htu21d.cpp:38
HTU21DSensorModels sensor_model_
Definition htu21d.h:34
sensor::Sensor * heater_
Definition htu21d.h:33
void setup() override
Setup (reset) the sensor and check connection.
Definition htu21d.cpp:19
void set_heater_level(uint8_t level)
Definition htu21d.cpp:129
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len) const
writes an array of bytes to a specific register in the I²C device
Definition i2c.cpp:34
ErrorCode write(const uint8_t *data, size_t len) const
writes an array of bytes to a device using an I2CBus
Definition i2c.h:183
ErrorCode read(uint8_t *data, size_t len) const
reads an array of bytes from the device using an I2CBus
Definition i2c.h:163
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:25
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len) const
Definition i2c.h:251
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
@ HTU21D_SENSOR_MODEL_HTU21D
Definition htu21d.h:10
uint16_t i2ctohs(uint16_t i2cshort)
Definition i2c.h:127
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:14
void HOT delay(uint32_t ms)
Definition hal.cpp:85
uint16_t temperature
Definition sun_gtil2.cpp:12