mirror of
https://github.com/esphome/esphome.git
synced 2024-11-16 10:45:48 +01:00
Fix AHT10 / AHT20 communication (#5198)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
259a6d52e1
commit
03baaa94a8
@ -21,36 +21,49 @@ namespace esphome {
|
||||
namespace aht10 {
|
||||
|
||||
static const char *const TAG = "aht10";
|
||||
static const uint8_t AHT10_CALIBRATE_CMD[] = {0xE1};
|
||||
static const size_t SIZE_CALIBRATE_CMD = 3;
|
||||
static const uint8_t AHT10_CALIBRATE_CMD[] = {0xE1, 0x08, 0x00};
|
||||
static const uint8_t AHT20_CALIBRATE_CMD[] = {0xBE, 0x08, 0x00};
|
||||
static const uint8_t AHT10_MEASURE_CMD[] = {0xAC, 0x33, 0x00};
|
||||
static const uint8_t AHT10_DEFAULT_DELAY = 5; // ms, for calibration and temperature measurement
|
||||
static const uint8_t AHT10_HUMIDITY_DELAY = 30; // ms
|
||||
static const uint8_t AHT10_ATTEMPTS = 3; // safety margin, normally 3 attempts are enough: 3*30=90ms
|
||||
static const uint8_t AHT10_CAL_ATTEMPTS = 10;
|
||||
static const uint8_t AHT10_STATUS_BUSY = 0x80;
|
||||
|
||||
void AHT10Component::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up AHT10...");
|
||||
const uint8_t *calibrate_cmd;
|
||||
switch (this->variant_) {
|
||||
case AHT10Variant::AHT20:
|
||||
calibrate_cmd = AHT20_CALIBRATE_CMD;
|
||||
ESP_LOGCONFIG(TAG, "Setting up AHT20");
|
||||
break;
|
||||
case AHT10Variant::AHT10:
|
||||
default:
|
||||
calibrate_cmd = AHT10_CALIBRATE_CMD;
|
||||
ESP_LOGCONFIG(TAG, "Setting up AHT10");
|
||||
}
|
||||
|
||||
if (!this->write_bytes(0, AHT10_CALIBRATE_CMD, sizeof(AHT10_CALIBRATE_CMD))) {
|
||||
if (this->write(calibrate_cmd, SIZE_CALIBRATE_CMD) != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "Communication with AHT10 failed!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
uint8_t data = 0;
|
||||
if (this->write(&data, 1) != i2c::ERROR_OK) {
|
||||
ESP_LOGD(TAG, "Communication with AHT10 failed!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
delay(AHT10_DEFAULT_DELAY);
|
||||
if (this->read(&data, 1) != i2c::ERROR_OK) {
|
||||
ESP_LOGD(TAG, "Communication with AHT10 failed!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
if (this->read(&data, 1) != i2c::ERROR_OK) {
|
||||
ESP_LOGD(TAG, "Communication with AHT10 failed!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
uint8_t data = AHT10_STATUS_BUSY;
|
||||
int cal_attempts = 0;
|
||||
while (data & AHT10_STATUS_BUSY) {
|
||||
delay(AHT10_DEFAULT_DELAY);
|
||||
if (this->read(&data, 1) != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "Communication with AHT10 failed!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
++cal_attempts;
|
||||
if (cal_attempts > AHT10_CAL_ATTEMPTS) {
|
||||
ESP_LOGE(TAG, "AHT10 calibration timed out!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((data & 0x68) != 0x08) { // Bit[6:5] = 0b00, NORMAL mode and Bit[3] = 0b1, CALIBRATED
|
||||
ESP_LOGE(TAG, "AHT10 calibration failed!");
|
||||
@ -62,7 +75,7 @@ void AHT10Component::setup() {
|
||||
}
|
||||
|
||||
void AHT10Component::update() {
|
||||
if (!this->write_bytes(0, AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD))) {
|
||||
if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "Communication with AHT10 failed!");
|
||||
this->status_set_warning();
|
||||
return;
|
||||
@ -89,7 +102,7 @@ void AHT10Component::update() {
|
||||
break;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "ATH10 Unrealistic humidity (0x0), retrying...");
|
||||
if (!this->write_bytes(0, AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD))) {
|
||||
if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "Communication with AHT10 failed!");
|
||||
this->status_set_warning();
|
||||
return;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
@ -7,12 +9,15 @@
|
||||
namespace esphome {
|
||||
namespace aht10 {
|
||||
|
||||
enum AHT10Variant { AHT10, AHT20 };
|
||||
|
||||
class AHT10Component : public PollingComponent, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
float get_setup_priority() const override;
|
||||
void set_variant(AHT10Variant variant) { this->variant_ = variant; }
|
||||
|
||||
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; }
|
||||
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { humidity_sensor_ = humidity_sensor; }
|
||||
@ -20,6 +25,7 @@ class AHT10Component : public PollingComponent, public i2c::I2CDevice {
|
||||
protected:
|
||||
sensor::Sensor *temperature_sensor_{nullptr};
|
||||
sensor::Sensor *humidity_sensor_{nullptr};
|
||||
AHT10Variant variant_{};
|
||||
};
|
||||
|
||||
} // namespace aht10
|
||||
|
@ -10,6 +10,7 @@ from esphome.const import (
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
CONF_VARIANT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
@ -17,6 +18,12 @@ DEPENDENCIES = ["i2c"]
|
||||
aht10_ns = cg.esphome_ns.namespace("aht10")
|
||||
AHT10Component = aht10_ns.class_("AHT10Component", cg.PollingComponent, i2c.I2CDevice)
|
||||
|
||||
AHT10Variant = aht10_ns.enum("AHT10Variant")
|
||||
AHT10_VARIANTS = {
|
||||
"AHT10": AHT10Variant.AHT10,
|
||||
"AHT20": AHT10Variant.AHT20,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
@ -33,6 +40,9 @@ CONFIG_SCHEMA = (
|
||||
device_class=DEVICE_CLASS_HUMIDITY,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_VARIANT, default="AHT10"): cv.enum(
|
||||
AHT10_VARIANTS, upper=True
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
@ -44,6 +54,7 @@ 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)
|
||||
cg.add(var.set_variant(config[CONF_VARIANT]))
|
||||
|
||||
if temperature := config.get(CONF_TEMPERATURE):
|
||||
sens = await sensor.new_sensor(temperature)
|
||||
|
Loading…
Reference in New Issue
Block a user