Xiao ESP32C3 ESPHome Smart ThermoStat

Este wiki irá guiá-lo passo a passo sobre como fazer um Xiao ESP32C3 ESPHome Smart ThermoStat. Vamos começar!
Preparação de Hardware
Se você quiser seguir este tutorial do início ao fim, precisará preparar o seguinte.
| Seeed Studio XIAO ESP32C3 | Placa de Expansão Seeed Studio | Dispositivos Home Assistant ex.: Seeed Studio Home Assistant Yellow |
|---|---|---|
![]() | ![]() | ![]() |
Sensores Grove
| Grove - Sensor de Temperatura e Umidade Pro (DHT22/AM2302) | Grove - Relé SPDT de 2 Canais | Grove - Relé de Alta Corrente 5V/10A | Grove - Display OLED 0.96" (SSD1315) | Botões momentâneos (qualquer tipo serve) |
|---|---|---|---|---|
|
|
|
|
|
Preparação de Software
Instalar o Home Assistant
Certifique-se de que o Home Assistant já está em funcionamento. Existem vários wikis explicando como instalar o Home Assistant nos produtos disponíveis aqui. Estou usando o Home Assistant Yellow, que é alimentado pelo Raspberry Pi CM4, então posso usar diretamente o oficial para instalar o sistema operacional no Home Assistant Yellow.
Instalar o ESPHome no Home Assistant
O ESPHome está disponível como um Add-On do Home Assistant e pode ser instalado facilmente pela loja de complementos.

- Passo 1. Clique em INSTALL

- Passo 2. Ative todas as opções e clique em START

Você verá a seguinte janela se o ESPHome for carregado com sucesso

Primeiros Passos
Assim que todo o software e hardware estiverem prontos, podemos começar.
1. Adicionar o Seeed Studio XIAO ESP32C3 ao ESPHome
- Passo 1. Clique em + NEW DEVICE

- Passo 2. Clique em CONTINUE

- Passo 3. Insira um Nome para o dispositivo e as credenciais WiFi, como Nome da rede e Senha. Em seguida, clique em NEXT

- Passo 4. Selecione ESP32-C3 e clique

- Passo 5. Clique em SKIP porque configuraremos esta placa manualmente

2. Criar e Enviar Configuração YAML
- Passo 1. Clique em EDIT na placa recém-criada

-
Passo 7. Criar e Enviar Configuração YAML
Explicação do código abaixo:
-
Nome: "thermostat"
-
Configuração da Placa:
Modo flash definido como DIO.
Placa especificada como "seeed_xiao_esp32c3" com o framework Arduino. -
Ações na Inicialização:
Exibe uma mensagem de log: "Booting thermostat."
Desliga três relés: aquecimento, resfriamento e ventilador.
Aguarda 500 milissegundos.
Executa um script chamado "boot_beep." -
Configuração de Script:
Script de Bipe na Inicialização:
Liga um buzzer, define sua frequência para produzir um bipe e o desliga após 300 milissegundos. -
Configuração de API e OTA:
API:
Chave de criptografia especificada.
OTA:
Senha definida como "13371337" para atualizações over-the-air. -
Saída do Buzzer:
Configurado usando a plataforma LEDC com o pino 5. -
Configuração de WiFi:
Especifica SSID e senha para conexão ao Wi-Fi.
Hotspot de fallback (portal cativo) configurado com SSID "Xiao-Esp32C3" e senha "13371337." -
Configuração I2C:
Configura a comunicação I2C com o pino SDA 6 e o pino SCL 7. -
Configuração de Fonte:
Define duas fontes para o display com tamanhos diferentes. -
Configuração do Display:
Utiliza um display I2C SSD1315 com uma função lambda para formatar e exibir informações.
Exibe temperatura em Fahrenheit, umidade, intensidade do sinal Wi-Fi e endereço IP. -
Configuração de Sensor:
Utiliza um sensor DHT22 para leituras de temperatura e umidade com intervalo de atualização de 10 segundos.
Inclui um sensor de sinal Wi-Fi com intervalo de atualização de 20 segundos. -
Configuração de Sensor de Texto:
Exibe o endereço IP do termostato e a versão do ESPHome. -
Configuração de Chave:
Configura três chaves GPIO para relay_heat, relay_cooling e relay_fan. -
Configuração de Sensor Binário:
Configura um sensor binário para o pressionamento do botão do ventilador circulante.
Quando pressionado, controla o modo de ventilador do sistema de climatização. -
Configuração de Climatização:
Implementa um controle de termostato usando o sensor de temperatura especificado.
Define ações para aquecimento, resfriamento, modo ventilador e inativo.
Define limites de temperatura, tamanhos de passo e predefinições padrão.
Cole isso no arquivo yaml de Configuração do Dispositivo ESPHome. Você também pode baixar o arquivo .yaml completo aqui
-
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. Monte o case de sua escolha (Opcional)
Aqui estão os arquivos STL do case que usei neste projeto.
Sinta-se à vontade para usá-los ou modificá-los como quiser. Se você não tiver uma impressora 3D, há muitos serviços online que imprimirão esses arquivos em qualquer material que você desejar.

4. Instale os Componentes
Passo 1: Instale todos os componentes listados no case
Usando parafusos M2x4 e M2x6, instale todos os componentes listados anteriormente em seus lugares correspondentes dentro do case.
(O sensor DHT22 simplesmente se encaixa no lugar por pressão).

Passo 2. Conecte todos os sensores e periféricos aos seus pinos correspondentes no YAML mencionado anteriormente
Aqui está o método que usei durante o processo de conexão:
- DHT22/SSD1315 - use conector JST: Dessole e vire os conectores do DHT22 e do SSD1315 para o outro lado de suas PCBs para encaixe adequado.
-
Dois Tipos de Relé - use conector JST/DuPont: Para os relés, usei JST em um lado e no outro lado usei conectores DuPont para os cabeçalhos de breakout GPIO na placa de expansão.
-
Conexão de Bateria: Também tenho uma célula de lítio de 3,7V conectada à entrada de bateria da placa de expansão para uso como bateria de backup em caso de perda de energia da fonte principal.

Passo 3. Conecte o estilo desejado de botões momentâneos na parte interna frontal do case
Realizei isso fixando os botões com um pouco de cola quente. Em seguida, soldei fios nos pinos diagonalmente opostos dos botões momentâneos e coloquei conectores DuPont na outra extremidade dos fios para conectar aos cabeçalhos de breakout GPIO corretos na placa de expansão.

Passo 4. Monte a tela na parte traseira da tampa frontal
Monte a tela na parte traseira da tampa frontal (fixe no lugar com uma pequena quantidade de cola quente). Em seguida, fixe a tampa frontal ao case com 3 parafusos M4x6 conforme mostrado abaixo.

5. Conecte os Fios aos Relés Correspondentes no EcoStat
Termostato Inteligente Concluído! Simplesmente remova o termostato existente da sua casa e use a imagem abaixo para conectar os fios corretos aos relés correspondentes no EcoStat!
✨ Projeto do Colaborador
- Este projeto é apoiado pelo Projeto de Colaboradores da Seeed Studio.
- Obrigado pelo esforço do Chris e seu trabalho será exibido.
Suporte Técnico e Discussão de Produtos
Obrigado por escolher nossos produtos! Estamos aqui para fornecer diferentes tipos de suporte para garantir que sua experiência com nossos produtos seja a mais tranquila possível. Oferecemos vários canais de comunicação para atender a diferentes preferências e necessidades.







