Skip to main content

Xiao ESP32C3 ESPHome 智能恒温器

note

本文档由 AI 翻译。如您发现内容有误或有改进建议,欢迎通过页面下方的评论区,或在以下 Issue 页面中告诉我们:https://github.com/Seeed-Studio/wiki-documents/issues

pir

本教程将逐步指导您如何制作一个 Xiao ESP32C3 ESPHome 智能恒温器。现在让我们开始吧!

硬件准备

如果您想完整地跟随本教程,您需要准备以下物品。

Seeed Studio XIAO ESP32C3Seeed Studio 扩展板Home Assistant 设备
例如 Seeed Studio Home Assistant Yellow

Grove 传感器

Grove - 温湿度传感器 Pro (DHT22/AM2302)Grove - 双通道 SPDT 继电器Grove - 高电流继电器 5V/10AGrove - OLED 显示屏 0.96" (SSD1315)瞬时按钮 (任何类型均可)

pir

pir

pir

pir

pir

Grove 单通道继电器

pir

Grove SSD1315 模块

pir

(可选)Seeed Studio 扩展板

pir

(可选)Seeed Studio Home Assistant Yellow 或其他设备

pir

按钮(任何类型的按钮均可)

pir


软件准备

安装 Home Assistant

确保您已经安装并运行了 Home Assistant。这里有多个 Wiki 介绍如何将 Home Assistant 刷入 相关产品。我使用的是由 Raspberry Pi CM4 驱动的 Home Assistant Yellow,因此我可以直接使用官方方法将操作系统刷入 Home Assistant Yellow

在 Home Assistant 上安装 ESPHome

ESPHome 可作为 Home Assistant 插件,可以通过插件商店轻松安装。

pir

  • 步骤 1. 点击 INSTALL
  • 步骤 2. 启用所有选项,然后点击 START

如果 ESPHome 成功加载,您将看到以下窗口:


入门

当所有的软件和硬件都准备好后,我们就可以开始了。

1. 将 Seeed Studio XIAO ESP32C3 添加到 ESPHome

  • 步骤 1. 点击 + NEW DEVICE
  • 步骤 2. 点击 CONTINUE
  • 步骤 3. 输入设备的 Name,以及 WiFi 的 Network namePassword,然后点击 NEXT
  • 步骤 4. 选择 ESP32-C3 并点击
  • 步骤 5. 点击 SKIP,因为我们将手动配置此板

2. 创建并上传 YAML 配置

  • 步骤 1. 点击新创建板下的 EDIT

创建并上传 YAML 配置

以下代码的解释:

  • 名称: "thermostat"

  • 板配置:
    Flash 模式设置为 DIO。
    板指定为 "seeed_xiao_esp32c3",使用 Arduino 框架。

  • 启动时的操作:
    显示日志消息:"Booting thermostat."
    关闭三个继电器:加热、冷却和风扇。
    延迟 500 毫秒。
    执行名为 "boot_beep" 的脚本。

  • 脚本配置:
    启动蜂鸣脚本:
    打开蜂鸣器,设置频率以产生蜂鸣声,并在 300 毫秒后关闭。

  • API 和 OTA 配置:
    API:
    指定加密密钥。
    OTA:
    设置密码为 "13371337" 以进行 OTA 更新。

  • 蜂鸣器输出:
    使用 LEDC 平台配置,使用引脚 5。

  • WiFi 配置:
    指定用于连接 Wi-Fi 的 SSID 和密码。
    配置备用热点(捕获门户),SSID 为 "Xiao-Esp32C3",密码为 "13371337"。

  • I2C 配置:
    配置 I2C 通信,使用 SDA 引脚 6 和 SCL 引脚 7。

  • 字体配置:
    为显示屏定义两种不同大小的字体。

  • 显示配置:
    使用 SSD1315 I2C 显示屏,并通过 lambda 函数格式化和显示信息。
    显示华氏温度、湿度、Wi-Fi 信号强度和 IP 地址。

  • 传感器配置:
    使用 DHT22 传感器进行温度和湿度读取,更新间隔为 10 秒。
    包括一个 Wi-Fi 信号传感器,更新间隔为 20 秒。

  • 文本传感器配置:
    显示恒温器的 IP 地址和 ESPHome 版本。

  • 开关配置:
    配置三个 GPIO 开关,分别用于 relay_heat、relay_cooling 和 relay_fan。

  • 二进制传感器配置:
    配置一个二进制传感器,用于检测循环风扇按钮按下。
    按下时控制气候系统的风扇模式。

  • 气候配置:
    使用指定的温度传感器实现恒温器控制。
    定义加热、制冷、风扇模式和空闲的操作。
    设置温度限制、步长和默认预设。

将此内容粘贴到您的 ESPHome 设备配置 yaml 文件中。您也可以在 这里 下载完整的 .yaml 文件。

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. 选择组装外壳(可选)

以下是我为本项目使用的外壳的 STL 文件。

EcoStatV2 ecostatcase

EcoStatV2 ecostatlid

您可以随意使用或修改这些文件。如果您没有 3D 打印机,可以使用许多在线服务,这些服务可以根据您的需求打印这些文件,并选择任何材料。

pir

4. 安装组件

步骤 1 将所有列出的组件安装到外壳中

使用 M2x4 和 M2x6 螺丝,将之前列出的所有组件安装到外壳中的对应位置。
(DHT22 传感器可以直接按压固定到位)。

pir

步骤 2 将所有传感器和外设连接到 YAML 文件中指定的对应引脚

以下是我在连接过程中使用的方法:

  • DHT22/SSD1315 - 使用 JST 连接器: 将 DHT22 和 SSD1315 的连接器从其 PCB 上焊接并翻转到另一侧,以确保正确安装。
  • 两种类型的继电器 - 使用 JST/杜邦连接器: 对于继电器,我在一侧使用 JST,另一侧使用杜邦连接器连接到扩展板上的 GPIO 引脚。

  • 电池连接: 我还将一个 3.7V 锂电池插入扩展板的电池连接器,以便在主电源丢失时作为备用电池使用。

pir

步骤 3 将所需样式的瞬时按钮连接到外壳的内部前部

我通过使用少量热胶将按钮固定到位来完成此步骤。然后,我将电线焊接到瞬时按钮的对角引脚上,并在电线的另一端安装杜邦连接器,以连接到扩展板上的正确 GPIO 引脚。

pir

步骤 4 将屏幕组装到前盖的后部

将屏幕组装到前盖的后部(用少量热胶固定)。然后使用 3 个 M4x6 螺丝将前盖固定到外壳上,如下图所示。

pir

5. 将线缆连接到 EcoStat 上的对应继电器

智能恒温器完成!只需拆下您家现有的恒温器,并使用下图将正确的线缆连接到 EcoStat 上的对应继电器!

pir

✨ 贡献者项目

技术支持与产品讨论

感谢您选择我们的产品!我们为您提供不同的支持渠道,以确保您使用我们的产品时体验顺畅。我们提供多个沟通渠道,以满足不同的偏好和需求。

Loading Comments...