本篇是智能家居折腾系列的第三期,完稿于第5期之后,内容有穿插请跳转查看。
本篇主要介绍ESP8266单片机和ESPHome的开发使用,以及将开发版接入Home Assistant的方法。项目均为测试上手之用,完成度不高,仅做尝试。
这一期围绕使用支持Wi-Fi的单片机制作可使用Home Assistant控制的能远程开关灯的物联网设备,主要介绍使用ESP8266 Node MCU结合舵机制作的简易关灯装置、使用ESP01-S配合继电器模块设计的简易单火线墙壁开关、ESP32-CAM作为IP摄像头。
本文完成时间距内容创造时间较长,详细过程和实物图片就不全展示了,可以找相关教程和文档。
一、ESPHome开发智能开关
ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.
ESP8266和Node MCU开发板这里就不详细介绍了,可以查阅相关页面:
ESP8266-NodeMCU介绍. 太极创客:http://www.taichi-maker.com/homepage/reference-index/arduino-hardware-refrence/nodemcu/
1. Mac(类Unix)上 ESPHome安装
根据官方文档引导,使用 pip
安装 ESPHome(此步骤可以不加user):
pip3 install --user esphome
注意ESPHome --user 安装位置:/Users/gakki/Library/Python/3.9/bin
,使用时需要添加环境变量:
export PATH="$PATH:/Users/gakki/Library/Python/3.9/bin"
看自己安装的方式,我的需要加 sudo
启动:
sudo esphome esphome_config/ dashboard
访问Web localhost:6052
:
对于nodeMCU,板载CH340的USB转TTL芯片,在mac上可以免驱直连;对于ESP01等小板,需要搭配烧录器连接至电脑。
连接后,在编辑页面输入配置文件,检查成功后可直接编译烧录至单片机。
ESPHome的优点就是无需编写代码,使用高度集成的配置文件式编程。更多细节请参阅相关文档。
2. ESP8266控制舵机
ESP8266有部分引脚可以输出PWM信号,进而可以操控舵机,
我使用的是SG90舵机,旋转角度仅为90度,供电和GND接开发版,数据线接D4引脚。
硬件输出PWM控制舵机
案例:接入ESPHome用ESP8266控制舵机喂狗:https://bbs.hassbian.com/thread-8741-1-1.html
ESPHOME 舵机项目1
官方文档中所给出的ESPHome中关于舵机的配置,使用 esp8266_pwm
输出PWM至指定引脚,并创建舵机实体。
# Example configuration entry
servo:
- id: my_servo
output: pwm_output
# Example output platform
# On ESP32, use ledc output
output:
- platform: esp8266_pwm
id: pwm_output
pin: D1
frequency: 50 Hz
用舵机控制墙壁开关
我尝试将舵机贴近墙壁开关粘贴放置,使得舵机旋转半周后刚好能将开关关闭(由于已拆除,已无现场图片),单片机开发板则从插座取电。
我烧录的yaml:
esphome:
name: node_mcu
platform: ESP8266
board: nodemcuv2
wifi:
ssid: "blue_sky"
password: "720805zzy"
power_save_mode: light
# Enable fallback hotspot (captive portal) in case wifi connection fails
#ap:
#ssid: "Servos Fallback Hotspot"
#password: "VYTOwxqxxlOT"
#captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
services:
- service: control_servo
variables:
level: float
then:
- servo.write:
id: my_servo
level: !lambda 'return level / 100.0;'
ota:
password: "123"
servo:
- id: my_servo
output: pwm_output
# Example output platform
# On ESP32, use ledc output
output:
- platform: esp8266_pwm
id: pwm_output
pin: D4
frequency: 50 Hz
light:
- platform: monochromatic
name: "LED On Board"
output: pwm_output
D4管脚刚好对应开发板上的LED灯,实际的效果依然没有视频,不过可以参考B站上同类型的展示:
3. ESP01S控制继电器
ESP01S是简化的ESP8266,仅引出两个GPIO,GPIO0
和 GPIO2
。
淘宝上搜索ESP01+继电器,有搭配ESP01的继电器模块,继电器模块通过5V供电,内部IDO转为3.3V给ESP01供电,因此整个模块需要5V供电,可以从墙壁插座使用变压器供电,若86盒中预留零线的,可以购买220V转5V的模块供电。
我的想法是:ESP01通过ESPHome接入HA,作为一个远程开关;继电器控制电灯火线的开闭;还要兼顾原来物理开关的功能,而且物理开关和HA中的状态可以实时更新同步。
可以参考下面的实例。
CSDN实例2
通过ESPHome接入HA,实现与之前相近的功能,即使用Wi-Fi和实体开关控制继电器。
大体的原理是:一个gpio虚拟成二进制传感器,一个gpio来控制继电器。当这个二进制传感器触发的时候,开关的开与闭合也发生变化。
GPIO0控制继电器的吸和,GPIO2与GND之间焊上原来的物理开关(使用杜邦线相连),并在GPIO和VCC间焊上10K的上拉电阻。(取决于继电器模块的工作模式,此方案是低电平触发,若为高电平触发,则开关要与VCC相连,对应焊接下拉电阻)
具体接线图已无处寻,可以参考CSDN实例2 中的接线方式。
ESPHome 配置
与CSDN例子中不同的是,他的是自动回弹式开关,使用的二进制传感器工作模式为 on_press
,即每次按下时开/关灯。
我使用的是传统的墙壁开关,每次扳动时开/关灯,因此使用的模式是 on_state
.
烧录文件:
esphome:
name: esp01s-1
platform: ESP8266
board: esp01_1m
wifi:
networks:
ssid: "blue_sky" #改成你的wifi名称
password: "720805zzy" #改成你的wifi密码
power_save_mode: light
#manual_ip:
#static_ip: 192.168.50.189
#gateway: 192.168.50.1
#subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp01S-1 Fallback Hotspot" #当esp01s连不上网的时候,它会自动发出热点。
password: "12345678"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
# password: "1"
ota:
password: "123"
web_server:
port: 80
switch:
- platform: gpio
pin: GPIO0
name: "书房灯1"
id: relay2
inverted: True
binary_sensor:
- platform: gpio
pin: GPIO2
name: "press_switch_lib1"
device_class: opening
filters:
- delayed_on_off: 100ms #这里一定要加这个这个起到滤波的作用。
on_state: #当这个二进制传感器状态改变的时候,触发gpio0
then:
- switch.toggle: relay2
ESPHome Wi-Fi 使用省电模式:
wifi:
# ...
power_save_mode: light
深度睡眠请参考:https://www.esphome.io/components/deep_sleep
具体效果请参考我发在B站上的视频(此账号目前已寄):https://www.bilibili.com/video/BV1Ri4y117Kk
4. HA端集成
在Home Assistant中添加ESPHome集成,自动发现设备,将实体添加至HA。
舵机对应的单色光灯和继电器开关对应的开关实体可以桥接至HomeKit。
二、Arduino开发智能开关
可以使用Arduino为ESP8266编程,使用高度封装的C或C++,详细的编程这里不介绍,可以参考: 太极创客-ESP8266-NodeMCU通过C/C++开发使用物联网
由于ESPHome与HA关系密切,使用更为简单,所以我最后的成品没有使用Arduino编程,以下引用自网络,仅供参考。
软件模拟PWM
案例:ESP8266/ESP01 软件输出PWM二极管调光(Arduino):https://www.cnblogs.com/cuianbing/p/14409053.html
B站的实例3
将普通开关接到GPIO2
与Vcc
之间。
定义了几个系统变量:
- 继电器状态标识
YYXBC_HIGH
和YYXBC_LOW
(以后可用LED_ON
和LED_OFF
代替) - 外部IO位置,物理开关与继电器
- 物理开关工作模式
/*1,继电器高电平触发时,YYXBC_HIGH = 1,YYXBC_LOW = 0
继电器低电平触发时,YYXBC_HIGH = 0,YYXBC_LOW = 1 */
const int YYXBC_HIGH = 0 ; //继电器是低电平触发
const int YYXBC_LOW = 1 ;
//2,用esp-01时,物理开关接在vcc 和gpio2上,继电器接在gpio0上
//NodeMCU 继电器接D3 GPIO0,物理开关接D4 GPIO2
#define LED_BUILTIN_LIGHT 0
#define LED_BUILTIN_K2 2
/*3,物理开关点动模式1,自锁模式0*/
const int YYXBC_BUTTON_TYPE = 1;
开关响应:
//点动模式按钮,监听按钮状态,执行相应处理
void btnHandler1()
{
static bool oButtonState = false;
int state1 = digitalRead(LED_BUILTIN_K2); //按钮状态
int state2 = digitalRead(LED_BUILTIN_LIGHT); //灯的状态
if(state1 == HIGH )
{
if(oButtonState ){
if(state2 == YYXBC_HIGH )
{
button1_callback(BLINKER_CMD_OFF);
Serial.println("按钮对灯已执行关闭");
}else{
button1_callback(BLINKER_CMD_ON);
Serial.println("按钮对灯已执行打开");
}
oButtonState = false;
}
}else{
oButtonState = true;
}
}
//自锁模式按钮,监听按钮状态,执行相应处理
void btnHandler2()
{
static bool is_btn = false;//按钮的标志位,用来逻辑处理对比,判断按钮有没有改变状态
bool is = digitalRead(LED_BUILTIN_K2); //按钮状态
if ( is != is_btn)
{
bool is_led = digitalRead(LED_BUILTIN_LIGHT);
digitalWrite(LED_BUILTIN_LIGHT, !is_led);
if (is_led == YYXBC_HIGH)
{
button1_callback(BLINKER_CMD_OFF);
Serial.println("按钮对灯已执行关闭");
}
else
{
button1_callback(BLINKER_CMD_ON);
Serial.println("按钮对灯已执行打开");
}
is_btn = digitalRead(LED_BUILTIN_K2); //更新按钮状态
}
三、ESP32-CAM使用
安信可的ESP32-CAM对应的ESPHome默认配置如下所示4
Configuration for Ai-Thinker Camera
# Example configuration entry
esp32_camera:
external_clock:
pin: GPIO0
frequency: 20MHz
i2c_pins:
sda: GPIO26
scl: GPIO27
data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
vsync_pin: GPIO25
href_pin: GPIO23
pixel_clock_pin: GPIO22
power_down_pin: GPIO32
# Image settings
name: My Camera
# ...
我烧录的配置文件为:
esphome:
name: esp32-cam
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
reboot_timeout: 0s
ota:
password: "1"
wifi:
ssid: "blue_sky"
password: "720805zzy"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp32-Cam Fallback Hotspot"
password: "12345678"
captive_portal:
# Example configuration entry
esp32_camera:
external_clock:
pin: GPIO0
frequency: 20MHz
i2c_pins:
sda: GPIO26
scl: GPIO27
data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
vsync_pin: GPIO25
href_pin: GPIO23
pixel_clock_pin: GPIO22
power_down_pin: GPIO32
# Image settings
name: My Camera
# ...
# Flashlight
output:
- platform: gpio
pin: GPIO4
id: gpio_4
light:
- platform: binary
output: gpio_4
name: torch_light
# Binary Sensor
binary_sensor:
- platform: gpio
pin: GPIO13
name: "次卧"
device_class: motion
在Home Assistant上直接添加ESPHome设备即可。
通过ESPHome添加的摄像头有如下问题:
- 无声音,HA上可查看串流
- 桥接至HomeKit无法查看串流,只可查看10s更新一次的缩略图
- 运动传感器可用,但貌似只有在光线变化剧烈时才会动作
参考资料
- Servo Component. ESPHome. https://esphome.io/components/servo ↩
- 树莓派智能家居homeassistant之用esphome制作零火智能开关篇. https://blog.csdn.net/zuobianfy/article/details/118432775 ↩
- ESP-01+继电器,自己动手制作智能开关,添加物理开关控制. https://www.bilibili.com/video/av501928405/ ↩
- ESP32-CAM. ESPHome. https://esphome.io/components/esp32_camera.html ↩