[stts22h] Add support for STTS22H temperature sensor (#11778)

Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
B48D81EFCC
2025-11-20 04:58:39 +01:00
committed by GitHub
parent da25951f6e
commit 83307684a3
10 changed files with 177 additions and 0 deletions

View File

@@ -460,6 +460,7 @@ esphome/components/st7735/* @SenexCrenshaw
esphome/components/st7789v/* @kbx81
esphome/components/st7920/* @marsjan155
esphome/components/statsd/* @Links2004
esphome/components/stts22h/* @B48D81EFCC
esphome/components/substitutions/* @esphome/core
esphome/components/sun/* @OttoWinter
esphome/components/sun_gtil2/* @Mat931

View File

@@ -0,0 +1 @@
CODEOWNERS = ["@B48D81EFCC"]

View File

@@ -0,0 +1,33 @@
import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
)
DEPENDENCIES = ["i2c"]
sensor_ns = cg.esphome_ns.namespace("stts22h")
stts22h = sensor_ns.class_(
"STTS22HComponent", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
)
CONFIG_SCHEMA = (
sensor.sensor_schema(
stts22h,
accuracy_decimals=2,
unit_of_measurement=UNIT_CELSIUS,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(cv.polling_component_schema("60s"))
.extend(i2c.i2c_device_schema(0x3C))
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)

View File

@@ -0,0 +1,101 @@
#include "esphome/core/log.h"
#include "stts22h.h"
namespace esphome::stts22h {
static const char *const TAG = "stts22h";
static const uint8_t WHOAMI_REG = 0x01;
static const uint8_t CTRL_REG = 0x04;
static const uint8_t TEMPERATURE_REG = 0x06;
// CTRL_REG flags
static const uint8_t LOW_ODR_CTRL_ENABLE_FLAG = 0x80; // Flag to enable low ODR mode in CTRL_REG
static const uint8_t FREERUN_CTRL_ENABLE_FLAG = 0x04; // Flag to enable FREERUN mode in CTRL_REG
static const uint8_t ADD_INC_ENABLE_FLAG = 0x08; // Flag to enable ADD_INC (IF_ADD_INC) mode in CTRL_REG
static const uint8_t WHOAMI_STTS22H_IDENTIFICATION = 0xA0; // ID value of STTS22H in WHOAMI_REG
static const float SENSOR_SCALE = 0.01f; // Sensor resolution in degrees Celsius
void STTS22HComponent::setup() {
// Check if device is a STTS22H
if (!this->is_stts22h_sensor_()) {
this->mark_failed("Device is not a STTS22H sensor");
return;
}
this->initialize_sensor_();
}
void STTS22HComponent::update() {
if (this->is_failed()) {
return;
}
this->publish_state(this->read_temperature_());
}
void STTS22HComponent::dump_config() {
LOG_SENSOR("", "STTS22H", this);
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
}
}
float STTS22HComponent::read_temperature_() {
uint8_t temp_reg_value[2];
if (this->read_register(TEMPERATURE_REG, temp_reg_value, 2) != i2c::NO_ERROR) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
return NAN;
}
// Combine the two bytes into a single 16-bit signed integer
// The STTS22H temperature data is in two's complement format
int16_t temp_raw_value = static_cast<int16_t>(encode_uint16(temp_reg_value[1], temp_reg_value[0]));
return temp_raw_value * SENSOR_SCALE; // Apply sensor resolution
}
bool STTS22HComponent::is_stts22h_sensor_() {
uint8_t whoami_value;
if (this->read_register(WHOAMI_REG, &whoami_value, 1) != i2c::NO_ERROR) {
this->mark_failed(ESP_LOG_MSG_COMM_FAIL);
return false;
}
if (whoami_value != WHOAMI_STTS22H_IDENTIFICATION) {
this->mark_failed("Unexpected WHOAMI identifier. Sensor is not a STTS22H");
return false;
}
return true;
}
void STTS22HComponent::initialize_sensor_() {
// Read current CTRL_REG configuration
uint8_t ctrl_value;
if (this->read_register(CTRL_REG, &ctrl_value, 1) != i2c::NO_ERROR) {
this->mark_failed(ESP_LOG_MSG_COMM_FAIL);
return;
}
// Enable low ODR mode and enable ADD_INC
// Before low ODR mode can be used,
// FREERUN bit must be cleared (see sensor documentation)
ctrl_value &= ~FREERUN_CTRL_ENABLE_FLAG; // Clear FREERUN bit
if (this->write_register(CTRL_REG, &ctrl_value, 1) != i2c::NO_ERROR) {
this->mark_failed(ESP_LOG_MSG_COMM_FAIL);
return;
}
// Enable LOW ODR mode and ADD_INC
ctrl_value |= LOW_ODR_CTRL_ENABLE_FLAG | ADD_INC_ENABLE_FLAG; // Set LOW ODR bit and ADD_INC bit
if (this->write_register(CTRL_REG, &ctrl_value, 1) != i2c::NO_ERROR) {
this->mark_failed(ESP_LOG_MSG_COMM_FAIL);
return;
}
}
} // namespace esphome::stts22h

View File

@@ -0,0 +1,21 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome::stts22h {
class STTS22HComponent : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice {
public:
void setup() override;
void update() override;
void dump_config() override;
protected:
void initialize_sensor_();
bool is_stts22h_sensor_();
float read_temperature_();
};
} // namespace esphome::stts22h

View File

@@ -0,0 +1,4 @@
sensor:
- platform: stts22h
name: Temperature
update_interval: 15s

View File

@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
<<: !include common.yaml

View File

@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp8266-ard.yaml
<<: !include common.yaml

View File

@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/nrf52.yaml
<<: !include common.yaml

View File

@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/rp2040-ard.yaml
<<: !include common.yaml