16 static const char *
const TAG =
"ens210";
19 static const uint8_t ENS210_BOOTING_MS = 2;
20 static const uint8_t ENS210_SINGLE_MEASURMENT_CONVERSION_TIME_MS =
22 static const uint16_t ENS210_PART_ID = 0x0210;
25 static const uint8_t ENS210_REGISTER_PART_ID = 0x00;
26 static const uint8_t ENS210_REGISTER_UID = 0x04;
27 static const uint8_t ENS210_REGISTER_SYS_CTRL = 0x10;
28 static const uint8_t ENS210_REGISTER_SYS_STAT = 0x11;
29 static const uint8_t ENS210_REGISTER_SENS_RUN = 0x21;
30 static const uint8_t ENS210_REGISTER_SENS_START = 0x22;
31 static const uint8_t ENS210_REGISTER_SENS_STOP = 0x23;
32 static const uint8_t ENS210_REGISTER_SENS_STAT = 0x24;
33 static const uint8_t ENS210_REGISTER_T_VAL = 0x30;
34 static const uint8_t ENS210_REGISTER_H_VAL = 0x33;
37 static const uint8_t CRC7_WIDTH = 7;
38 static const uint8_t CRC7_POLY = 0x89;
39 static const uint8_t CRC7_IVEC = 0x7F;
42 static const uint8_t DATA7_WIDTH = 17;
43 static const uint32_t DATA7_MASK = ((1UL << DATA7_WIDTH) - 1);
44 static const uint32_t DATA7_MSB = (1UL << (DATA7_WIDTH - 1));
47 static const LogString *ens210_status_to_human(
int status) {
50 return LOG_STR(
"I2C error - communication with ENS210 failed!");
52 return LOG_STR(
"CRC error");
54 return LOG_STR(
"Invalid data");
56 return LOG_STR(
"Status OK");
58 return LOG_STR(
"ENS210 has wrong chip ID! Is it a ENS210?");
60 return LOG_STR(
"Unknown");
66 static uint32_t crc7(uint32_t value) {
68 uint32_t polynomial = CRC7_POLY;
70 polynomial = polynomial << (DATA7_WIDTH - CRC7_WIDTH - 1);
72 uint32_t bit = DATA7_MSB;
74 value = value << CRC7_WIDTH;
75 bit = bit << CRC7_WIDTH;
76 polynomial = polynomial << CRC7_WIDTH;
80 while (bit & (DATA7_MASK << CRC7_WIDTH)) {
90 ESP_LOGCONFIG(TAG,
"Setting up ENS210...");
94 if (!this->
write_byte(ENS210_REGISTER_SYS_CTRL, 0x80)) {
95 this->
write_byte(ENS210_REGISTER_SYS_CTRL, 0x80);
101 delay(ENS210_BOOTING_MS);
111 if (!this->
read_bytes(ENS210_REGISTER_PART_ID, data, 2)) {
119 part_id = data[1] * 256U + data[0] * 1U;
121 if (part_id != ENS210_PART_ID) {
130 ESP_LOGCONFIG(TAG,
"ENS210:");
131 LOG_I2C_DEVICE(
this);
133 ESP_LOGE(TAG,
"%s", LOG_STR_ARG(ens210_status_to_human(this->error_code_)));
135 LOG_UPDATE_INTERVAL(
this);
144 if (!this->
write_byte(ENS210_REGISTER_SENS_RUN, 0x00)) {
145 ESP_LOGE(TAG,
"Starting single measurement failed!");
150 if (!this->
write_byte(ENS210_REGISTER_SENS_START, 0x03)) {
151 ESP_LOGE(TAG,
"Trigger of measurement failed!");
156 this->
set_timeout(
"data", uint32_t(ENS210_SINGLE_MEASURMENT_CONVERSION_TIME_MS), [
this]() {
157 int temperature_data, temperature_status, humidity_data, humidity_status;
159 uint32_t h_val_data, t_val_data;
165 if (!this->
read_bytes(ENS210_REGISTER_T_VAL, data, 6)) {
166 ESP_LOGE(TAG,
"Communication with ENS210 failed!");
171 h_val_data = (uint32_t) ((uint32_t) data[5] << 16 | (uint32_t) data[4] << 8 | (uint32_t) data[3]);
177 float humidity = (humidity_data & 0xFFFF) / 512.0;
181 ESP_LOGW(TAG,
"Humidity status failure: %s", LOG_STR_ARG(ens210_status_to_human(humidity_status)));
186 t_val_data = (uint32_t) ((uint32_t) data[2] << 16 | (uint32_t) data[1] << 8 | (uint32_t) data[0]);
193 float temperature = (temperature_data & 0xFFFF) / 64.0 - 27315L / 100.0;
197 ESP_LOGW(TAG,
"Temperature status failure: %s", LOG_STR_ARG(ens210_status_to_human(temperature_status)));
204 *data = (val >> 0) & 0xffff;
205 int valid = (val >> 16) & 0x1;
206 uint32_t
crc = (val >> 17) & 0x7f;
207 uint32_t payload = (val >> 0) & 0x1ffff;
209 uint8_t crc_ok = crc7(payload) ==
crc;
222 uint8_t low_power_cmd = enable ? 0x01 : 0x00;
223 ESP_LOGD(TAG,
"Enable low power: %s", enable ?
"true" :
"false");
224 bool result = this->
write_byte(ENS210_REGISTER_SYS_CTRL, low_power_cmd);
225 delay(ENS210_BOOTING_MS);
const float DATA
For components that import data from directly connected sensors like DHT.
void status_set_warning(const char *message="unspecified")
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
float get_setup_priority() const override
void publish_state(float state)
Publish a new state to the front-end.
sensor::Sensor * humidity_sensor_
sensor::Sensor * temperature_sensor_
bool set_low_power_(bool enable)
enum esphome::ens210::ENS210Component::ErrorCode ENS210_STATUS_OK
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
virtual void mark_failed()
Mark this component as failed.
Implementation of SPI Controller mode.
void extract_measurement_(uint32_t val, int *data, int *status)
void IRAM_ATTR HOT delay(uint32_t ms)
void dump_config() override