[hdc2080] Add support for HDC2080 sensor (#9331)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Big Mike <mikelawrence@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
This commit is contained in:
Gonçalo Pereira
2026-04-01 17:09:22 +01:00
committed by GitHub
parent cc88896280
commit f33fd047ee
9 changed files with 173 additions and 0 deletions
+1
View File
@@ -217,6 +217,7 @@ esphome/components/hbridge/light/* @DotNetDann
esphome/components/hbridge/switch/* @dwmw2
esphome/components/hc8/* @omartijn
esphome/components/hdc2010/* @optimusprimespace @ssieb
esphome/components/hdc2080/* @G-Pereira @jesserockz
esphome/components/hdc302x/* @joshuasing
esphome/components/he60r/* @clydebarrow
esphome/components/heatpumpir/* @rob-deutsch
+1
View File
@@ -0,0 +1 @@
CODEOWNERS = ["@G-Pereira", "@jesserockz"]
+71
View File
@@ -0,0 +1,71 @@
#include "hdc2080.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
namespace esphome::hdc2080 {
static const char *const TAG = "hdc2080";
// Register map (Table 8-6)
static constexpr uint8_t REG_TEMPERATURE_LOW = 0x00; // Temperature [7:0]
static constexpr uint8_t REG_TEMPERATURE_HIGH = 0x01; // Temperature [15:8]
static constexpr uint8_t REG_HUMIDITY_LOW = 0x02; // Humidity [7:0]
static constexpr uint8_t REG_HUMIDITY_HIGH = 0x03; // Humidity [15:8]
static constexpr uint8_t REG_RESET_DRDY_INT_CONF = 0x0E; // Soft Reset and Interrupt Configuration
static constexpr uint8_t REG_MEASUREMENT_CONFIGURATION = 0x0F;
// Measurement register (0x0F) bit fields
static constexpr uint8_t MEAS_TRIG = 0x01; // Bit 0: start measurement
static constexpr uint8_t MEAS_CONF_TEMP = 0x02; // Bits 2:1 = 01: temperature only
static constexpr uint8_t MEAS_CONF_HUM = 0x04; // Bits 2:1 = 10: humidity only
void HDC2080Component::setup() {
const uint8_t data = 0x00; // automatic measurement mode disabled, heater off
if (this->write_register(REG_RESET_DRDY_INT_CONF, &data, 1) != i2c::ERROR_OK) {
this->mark_failed(ESP_LOG_MSG_COMM_FAIL);
return;
}
}
void HDC2080Component::dump_config() {
ESP_LOGCONFIG(TAG, "HDC2080:");
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
}
}
void HDC2080Component::update() {
uint8_t data = MEAS_TRIG; // 14-bit resolution, measure both, start
if (this->temperature_sensor_ != nullptr && this->humidity_sensor_ == nullptr) {
data = MEAS_TRIG | MEAS_CONF_TEMP;
} else if (this->temperature_sensor_ == nullptr && this->humidity_sensor_ != nullptr) {
data = MEAS_TRIG | MEAS_CONF_HUM;
}
if (this->write_register(REG_MEASUREMENT_CONFIGURATION, &data, 1) != i2c::ERROR_OK) {
this->status_set_warning(ESP_LOG_MSG_COMM_FAIL);
return;
}
// wait for conversion to complete 2ms should be enough, more is fine
this->set_timeout(5, [this]() {
uint8_t raw_data[4];
if (this->read_register(REG_TEMPERATURE_LOW, raw_data, 4) != i2c::ERROR_OK) {
this->status_set_warning(ESP_LOG_MSG_COMM_FAIL);
return;
}
this->status_clear_warning();
if (this->temperature_sensor_ != nullptr) {
float temp = encode_uint16(raw_data[1], raw_data[0]) * (165.0f / 65536.0f) - 40.5f;
this->temperature_sensor_->publish_state(temp);
}
if (this->humidity_sensor_ != nullptr) {
float humidity = encode_uint16(raw_data[3], raw_data[2]) * (100.0f / 65536.0f);
this->humidity_sensor_->publish_state(humidity);
}
});
}
} // namespace esphome::hdc2080
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
namespace esphome::hdc2080 {
class HDC2080Component : public PollingComponent, public i2c::I2CDevice {
public:
void set_temperature(sensor::Sensor *temperature) { this->temperature_sensor_ = temperature; }
void set_humidity(sensor::Sensor *humidity) { this->humidity_sensor_ = humidity; }
/// Setup the sensor and check for connection.
void setup() override;
void dump_config() override;
void update() override;
protected:
sensor::Sensor *temperature_sensor_{nullptr};
sensor::Sensor *humidity_sensor_{nullptr};
};
} // namespace esphome::hdc2080
+57
View File
@@ -0,0 +1,57 @@
import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_HUMIDITY,
CONF_ID,
CONF_TEMPERATURE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
UNIT_PERCENT,
)
DEPENDENCIES = ["i2c"]
hdc2080_ns = cg.esphome_ns.namespace("hdc2080")
HDC2080Component = hdc2080_ns.class_(
"HDC2080Component", cg.PollingComponent, i2c.I2CDevice
)
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(HDC2080Component),
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
accuracy_decimals=1,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
accuracy_decimals=0,
device_class=DEVICE_CLASS_HUMIDITY,
state_class=STATE_CLASS_MEASUREMENT,
),
}
)
.extend(cv.polling_component_schema("60s"))
.extend(i2c.i2c_device_schema(0x40))
.add_extra(cv.has_at_least_one_key(CONF_TEMPERATURE, CONF_HUMIDITY))
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
if temperature_config := config.get(CONF_TEMPERATURE):
sens = await sensor.new_sensor(temperature_config)
cg.add(var.set_temperature(sens))
if humidity_config := config.get(CONF_HUMIDITY):
sens = await sensor.new_sensor(humidity_config)
cg.add(var.set_humidity(sens))
+7
View File
@@ -0,0 +1,7 @@
sensor:
- platform: hdc2080
temperature:
name: Temperature
humidity:
name: Humidity
update_interval: 15s
@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
<<: !include common.yaml
@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp8266-ard.yaml
<<: !include common.yaml
@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/rp2040-ard.yaml
<<: !include common.yaml