Xiao ESP32C3 ESPHome Smart ThermoStat
Este wiki te guiará paso a paso sobre cómo hacer un Xiao ESP32C3 ESPHome Smart ThermoStat. ¡Ahora comencemos!
Preparación del Hardware
Si quieres seguir este tutorial completamente, necesitarás preparar lo siguiente.
Seeed Studio XIAO ESP32C3 | Seeed Studio Expansion Board | Dispositivos Home Assistant ej. Seeed Studio Home assistant Yellow |
---|---|---|
![]() | ![]() | ![]() |
Sensores Grove
Grove - Sensor de Temperatura y Humedad Pro (DHT22/AM2302) | Grove - Relé SPDT de 2 Canales | Grove - Relé de Alta Corriente 5V/10A | Grove - Pantalla OLED 0.96" (SSD1315) | Botones momentáneos (Cualquier tipo servirá) |
---|---|---|---|---|
Preparación del Software
Instalar Home Assistant
Asegúrate de que ya tienes Home Assistant funcionando. Hay múltiples wikis que introducen cómo flashear Home Assistant en los productos aquí. Estoy usando Home assistant Yellow que está alimentado por Raspberry Pi CM4, así que puedo usar directamente el oficial para flashear el OS en el Home assistant Yellow.
Instalar ESPHome en Home Assistant
ESPHome está disponible como un Complemento de Home Assistant y puede instalarse simplemente a través de la tienda de complementos.
- Paso 1. Haz clic en INSTALAR

- Paso 2. Habilita todas las opciones y haz clic en INICIAR

Verás la siguiente ventana si ESPHome se carga exitosamente

Comenzando
Una vez que todo el software y el hardware estén listos, podemos comenzar.
1. Agregar Seeed Studio XIAO ESP32C3 a ESPHome
- Paso 1. Haz clic en + NEW DEVICE

- Paso 2. Haz clic en CONTINUE

- Paso 3. Ingresa un Nombre para el dispositivo e ingresa las credenciales WiFi como Nombre de red y Contraseña. Luego haz clic en NEXT

- Paso 4. Selecciona ESP32-C3 y haz clic

- Paso 5. Haz clic en SKIP porque configuraremos esta placa manualmente

2. Crear y Subir Configuración YAML
- Paso 1. Haz clic en EDIT bajo la placa recién creada

-
Paso 7. Crear y Subir Configuración YAML
Explicación del código a continuación:
-
Nombre: "thermostat"
-
Configuración de la Placa:
Modo flash configurado en DIO.
Placa especificada como "seeed_xiao_esp32c3" con el framework Arduino. -
Acciones al Arrancar:
Muestra un mensaje de registro: "Booting thermostat."
Apaga tres relés: calefacción, refrigeración y ventilador.
Retrasa por 500 milisegundos.
Ejecuta un script llamado "boot_beep." -
Configuración de Script:
Script de Pitido de Arranque:
Enciende un zumbador, establece su frecuencia para producir un pitido, y lo apaga después de 300 milisegundos. -
Configuración de API y OTA:
API:
Clave de cifrado especificada.
OTA:
Contraseña establecida en "13371337" para actualizaciones por aire. -
Salida del Zumbador:
Configurada usando la plataforma LEDC con el pin 5. -
Configuración WiFi:
Especifica SSID y contraseña para conectarse a Wi-Fi.
Punto de acceso de respaldo (portal cautivo) configurado con SSID "Xiao-Esp32C3" y contraseña "13371337." -
Configuración I2C:
Configura la comunicación I2C con pin SDA 6 y pin SCL 7. -
Configuración de Fuente:
Define dos fuentes para la pantalla con diferentes tamaños. -
Configuración de Pantalla:
Utiliza una pantalla SSD1315 I2C con una función lambda para formatear y mostrar información.
Muestra temperatura en Fahrenheit, humedad, intensidad de señal Wi-Fi y dirección IP. -
Configuración de Sensor:
Utiliza un sensor DHT22 para lecturas de temperatura y humedad con un intervalo de actualización de 10 segundos.
Incluye un sensor de señal Wi-Fi con un intervalo de actualización de 20 segundos. -
Configuración de Sensor de Texto:
Muestra la dirección IP del termostato y la versión de ESPHome. -
Configuración de Interruptor:
Configura tres interruptores GPIO para relay_heat, relay_cooling y relay_fan. -
Configuración de Sensor Binario:
Configura un sensor binario para la pulsación del botón del ventilador de circulación.
Cuando se presiona, controla el modo de ventilador del sistema de climatización. -
Configuración de Clima:
Implementa un control de termostato usando el sensor de temperatura especificado.
Define acciones para calefacción, refrigeración, modo ventilador e inactivo.
Establece límites de temperatura, tamaños de paso y preajustes predeterminados.
Pega esto en tu archivo yaml de Configuración de Dispositivo ESPHome. También puedes descargar el archivo .yaml completo aquí
-
esphome:
name: ecostat
platformio_options:
board_build.flash_mode: dio
on_boot:
priority: 750
then:
- logger.log: "Booting EcoStat"
- delay: 500ms
- lambda: |-
id(relay_heat).turn_off();
id(relay_cooling).turn_off();
id(relay_fan).turn_off();
id(ecostat_control_heat).mode = CLIMATE_MODE_OFF;
id(ecostat_control_cooling).mode = CLIMATE_MODE_OFF;
- script.execute: boot_beep
esp32:
board: seeed_xiao_esp32c3
variant: esp32c3
framework:
type: arduino
platform_version: 5.4.0
#logger:
# level: VERY_VERBOSE
api:
encryption:
key: "YOURKEYHERE"
ota:
password: "13371337"
script:
- id: boot_beep
then:
# First ^E
- output.turn_on: buzzer
- output.ledc.set_frequency:
id: buzzer
frequency: 659.25Hz # E
- output.set_level:
id: buzzer
level: "50%"
- delay: 150ms
- output.turn_off: buzzer
- output.turn_on: buzzer
- output.ledc.set_frequency:
id: buzzer
frequency: 1000Hz
- output.set_level:
id: buzzer
level: "50%"
- delay: 150ms
- output.turn_off: buzzer
output:
- platform: ledc
pin: 5
id: buzzer
wifi:
ssid: YOURWIFINAME
password: YOURWIFIPASS
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Xiao-Esp32C3 Fallback Hotspot"
password: "13371337"
i2c:
sda: 6
scl: 7
scan: False
font:
# gfonts://family[@weight]
- file: "gfonts://Roboto"
id: roboto
size: 20
- file: "gfonts://Poppins@700"
id: inter
size: 10
display:
- platform: SSD1315_i2c
id: oled
model: "SSD1315 128x64"
address: 0x3C
lambda: |-
float temp_celsius = id(temp).state;
float temp_fahrenheit = (temp_celsius * 9.0 / 5.0) + 32.0;
char temp_str[6]; // Buffer for temperature string
dtostrf(temp_celsius, 4, 1, temp_str); // Convert Celsius to string with 1 decimal place
it.print(28, 0, id(inter), id(ip_address).state.c_str());
it.printf(0, 18, id(roboto), "T: %.1f ", temp_fahrenheit);
it.printf(70, 18, id(roboto), "H: %d", int(id(humidity).state));
it.printf(31, 45, id(inter), "RSSI: %d", int(id(rssi).state));
climate:
- platform: thermostat
name: "EcoStat Heating"
id: ecostat_control_heat
sensor: temp
heat_deadband: 2 °F
heat_overrun: 0
min_heating_run_time: 60s
min_heating_off_time: 120s
min_idle_time: 3min
visual:
min_temperature: 60 °F
max_temperature: 80 °F
temperature_step:
current_temperature: 0.1
target_temperature: 1.0
target_temperature_low: 65 °F
heat_action:
- switch.turn_on: relay_heat
idle_action:
- switch.turn_off: relay_heat
default_preset: Normal
preset:
- name: Normal
default_target_temperature_low: 65 °F
- platform: thermostat
name: "EcoStat Cooling"
id: ecostat_control_cooling
sensor: temp
cool_deadband: 2 °F
cool_overrun: 0
min_cooling_off_time: 20s
min_cooling_run_time: 60s
min_idle_time: 3min
visual:
min_temperature: 60 °F
max_temperature: 80 °F
temperature_step:
current_temperature: 0.1
target_temperature: 1.0
target_temperature_low: 70 °F
cool_action:
- switch.turn_on: relay_cooling
idle_action:
- switch.turn_off: relay_cooling
min_fan_mode_switching_time: 20s
fan_mode_on_action:
- switch.turn_on: relay_fan
fan_mode_off_action:
- switch.turn_off: relay_fan
default_preset: Normal
preset:
- name: Normal
default_target_temperature_high: 70 °F
sensor:
- platform: dht
pin: 20
model: DHT22
update_interval: 10s
temperature:
name: "EcoStat Temperature"
id: temp
humidity:
name: "EcoStat Humidity"
id: humidity
- platform: wifi_signal
name: "Wi-Fi Signal Strength"
id: rssi
update_interval: 20s
text_sensor:
- platform: wifi_info
ip_address:
name: "EcoStat IP Address"
id: ip_address
- platform: version
name: "EcoStat ESPHome Version"
switch:
- platform: gpio
id: relay_heat
pin:
number: 10
mode: OUTPUT
- platform: gpio
id: relay_cooling
pin:
number: 9
mode: OUTPUT
- platform: gpio
id: relay_fan
pin:
number: 21
mode: OUTPUT
binary_sensor:
- platform: gpio
id: tempup
pin:
number: 8
mode: INPUT_PULLUP
filters:
- delayed_on: 50ms
- delayed_off: 50ms
on_press:
then:
- lambda: |-
if (id(ecostat_control_heat).mode == esphome::climate::CLIMATE_MODE_HEAT) {
auto current_target_temp = id(ecostat_control_heat).target_temperature_low;
id(ecostat_control_heat).target_temperature_low = current_target_temp + 0.56;
auto current_target_temp_high = id(ecostat_control_heat).target_temperature_high;
id(ecostat_control_heat).target_temperature_high = current_target_temp_high + 0.56;
} else if (id(ecostat_control_cooling).mode == esphome::climate::CLIMATE_MODE_COOL) {
auto current_target_temp = id(ecostat_control_cooling).target_temperature_low;
id(ecostat_control_cooling).target_temperature_low = current_target_temp + 0.56;
auto current_target_temp_high = id(ecostat_control_cooling).target_temperature_high;
id(ecostat_control_cooling).target_temperature_high = current_target_temp_high + 0.56;
}
- platform: gpio
id: tempdown
pin:
number: 2
mode: INPUT_PULLUP
filters:
- delayed_on: 50ms
- delayed_off: 50ms
on_press:
then:
- lambda: |-
if (id(ecostat_control_heat).mode == esphome::climate::CLIMATE_MODE_HEAT) {
auto current_target_temp = id(ecostat_control_heat).target_temperature_low;
id(ecostat_control_heat).target_temperature_low = current_target_temp - 0.56;
auto current_target_temp_high = id(ecostat_control_heat).target_temperature_high;
id(ecostat_control_heat).target_temperature_high = current_target_temp_high - 0.56;
} else if (id(ecostat_control_cooling).mode == esphome::climate::CLIMATE_MODE_COOL) {
auto current_target_temp = id(ecostat_control_cooling).target_temperature_low;
id(ecostat_control_cooling).target_temperature_low = current_target_temp - 0.56;
auto current_target_temp_high = id(ecostat_control_cooling).target_temperature_high;
id(ecostat_control_cooling).target_temperature_high = current_target_temp_high - 0.56;
}
- platform: gpio
id: modeswitch
pin:
number: 3
mode: INPUT_PULLUP
filters:
- delayed_on: 50ms
- delayed_off: 50ms
on_press:
then:
- lambda: |-
auto current_mode = id(ecostat_control_heat).mode;
if (current_mode == esphome::climate::CLIMATE_MODE_OFF) {
id(ecostat_control_heat).mode = esphome::climate::CLIMATE_MODE_HEAT;
} else if (current_mode == esphome::climate::CLIMATE_MODE_HEAT) {
id(ecostat_control_heat).mode = esphome::climate::CLIMATE_MODE_COOL;
} else if (current_mode == esphome::climate::CLIMATE_MODE_COOL) {
id(ecostat_control_heat).mode = esphome::climate::CLIMATE_MODE_OFF;
}
- platform: gpio
id: momentaryswitch0
pin:
number: 4
mode: INPUT_PULLUP
filters:
- delayed_on: 50ms
- delayed_off: 50ms
on_press:
then:
- if:
condition:
switch.is_off: relay_fan
then:
- climate.control:
id: ecostat_control_cooling
fan_mode: "on"
else:
- climate.control:
id: ecostat_control_cooling
fan_mode: "off"
3. Ensamblar carcasa de elección (Opcional)
Aquí están los archivos STL para la carcasa que utilicé para este proyecto.
Siéntete libre de usarlos o modificarlos como gustes. Si no tienes personalmente una impresora 3D, hay muchos servicios en línea que imprimirán estos archivos en cualquier material que desees.
4. Instalar Componentes
Paso 1 Instalar todos los componentes listados en la carcasa
Usando tornillos M2x4 y M2x6, instala todos los componentes previamente listados en sus lugares correspondientes dentro de la carcasa.
(El Sensor DHT22 simplemente se ajusta a presión en su lugar).
Paso 2. Conectar todos los sensores y periféricos a sus pines correspondientes dentro del YAML mencionado anteriormente
Aquí está el método que utilicé durante el proceso de conexión:
- DHT22/SSD1315 - usar conector JST: Desoldar y voltear los conectores para el DHT22 y SSD1315 al otro lado de sus PCBs para un ajuste adecuado.
-
Dos Tipos de Relé - usar conector JST/DuPont: Para los relés, utilicé JST en un lado y para el otro lado utilicé conectores DuPont para los headers de breakout GPIO en la placa de expansión.
-
Conexión de Batería: También tengo una celda de Litio de 3.7V conectada a la conexión de batería de la placa de expansión para usar como batería de respaldo en caso de pérdida de energía del suministro principal.
Paso 3. Conectar el estilo deseado de botones momentáneos al interior frontal de la carcasa
Logré esto fijando los botones con un poco de pegamento termofusible. Luego soldé cables a los pines diagonalmente opuestos de los botones momentáneos, y coloqué conectores DuPont en el otro extremo de los cables para conectar a los headers de breakout GPIO correctos en la placa de expansión.
Paso 4. Ensamblar la pantalla en la parte trasera de la cubierta frontal
Ensamblar la pantalla en la parte trasera de la cubierta frontal (Asegurar en su lugar con una pequeña cantidad de pegamento termofusible). Luego asegurar la cubierta frontal a la carcasa con 3 tornillos M4x6 como se muestra a continuación.
5. Conectar Cables a los Relés Correspondientes en EcoStat
¡Termostato Inteligente Completo! ¡Simplemente retira el termostato existente de tu hogar y usa la imagen de abajo para conectar los cables correctos, a los relés correspondientes en EcoStat!

✨ Proyecto de Colaboradores
- Este proyecto está respaldado por el Proyecto de Colaboradores de Seeed Studio.
- Gracias a los esfuerzos de Chris y tu trabajo será exhibido.
Soporte Técnico y Discusión de Productos
¡Gracias por elegir nuestros productos! Estamos aquí para brindarte diferentes tipos de soporte para asegurar que tu experiencia con nuestros productos sea lo más fluida posible. Ofrecemos varios canales de comunicación para satisfacer diferentes preferencias y necesidades.