HomeAssiatant ESPHome 使用ESP8266控制晾衣架升降

ESPHome 是一款专为简化 ESP 板管理而设计的工具,借助它,无需复杂编程,仅通过简洁且功能强大的配置文件,就能轻松掌控 ESP8266/ESP32 系统,还能利用 Home Assistant 实现远程操控。ESPHome 兼容性出色,支持 ESP8266、ESP32、RP2040 等多种开发平台,并且与上百种传感器和控制组件无缝适配,助力用户快速搭建 DIY 智能家居系统。
工作原理:ESPHome 会读取 YAML 配置文件,据此生成自定义固件,然后将其安装到 ESP 设备上。只要在 ESPHome 配置中添加设备或传感器,这些内容便会自动同步显示在 Home Assistant 的操作界面里,极大地简化了智能家居设备的配置与管理流程。

零.项目背景

家人买了个电动晾衣架,遥控的,按理来说是能直接接入米家的,没想到是阉割版的,遥控模具有配对按钮,但是电路板没有对应原件,每次都要拿遥控按不方便,于是打算加一个语音控制。

一. 硬件准备

1. ESP8266

在这里插入图片描述
我这个是带OLED版的,SPI引脚看商家,不过屏幕非刚需

2. LD3320语音识别模块

在这里插入图片描述
有SPI版和串口版,串口版就是多了个主控,直接和8266串口通信就可以了,比较省事

3. 射频发射和接收模块

在这里插入图片描述
如果不知道自家用的是315还是433就都买吧,反正几块钱,不过便宜的射频距离就比较短,要么自己焊天线

4.逻辑分析仪

在这里插入图片描述
用于分析射频信号

二. 软件准备

1.esp8266接入esphome

以DHT11、ESP8266为例介绍ESPHome在Home Assistant中的应用

用homeassistant的su或者os版本才有加载项,在docker版没有,不能编译

2.逻辑分析仪的使用

参考 [应用ESP8266控制433M无线遥控电动幕布]
(https://blog.csdn.net/qq_31400983/article/details/131710721)
在这里插入图片描述

3.esp8266代码

esphome:
  name: esp80266
  friendly_name: esp80266

esp8266:
  board: esp01_1m

external_components:
  - source:
      type: git
      url: https://github.com/esphome/esphome.git
      ref: main
    components: [uart]

# Enable logging
logger:
  baud_rate: 0  # 将串口日志波特率设置为 0,禁用串口日志输出
  #level: INFO  # 设置日志级别,可根据需要调整
# Enable Home Assistant API
api:
  encryption:
    key: "t0Gm/4xUrwPvx36RUgT3Xh8YkXP81YLY9LDwLg0kd0k="

ota:
  - platform: esphome
    password: "123456"

wifi:
  ssid: "XXX"
  password: "12345678"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp80266 Fallback Hotspot"
    password: "88888888"




      
uart:
  tx_pin: 5  # 根据实际连接修改TX引脚
  rx_pin: 4  # 根据实际连接修改RX引脚
  baud_rate: 9600  # 波特率,需与单片机设置一致
  debug:
    direction: RX
    dummy_receiver: true
    after:
      delimiter: "\r\n"
    sequence:
      - lambda: |-
          // 将接收到的字节数据转换为字符串
          std::string str(bytes.begin(), bytes.end());
          if (str.compare("A1\r\n") == 0) {
              id(oled_display).fill(COLOR_OFF);
              id(display_text).publish_state("打开 L5");
              id(switch_l3).turn_on();
              id(switch_l3l2).execute();
          } else if (str.compare("A2\r\n") == 0) {
              id(oled_display).fill(COLOR_OFF);
              id(display_text).publish_state("关闭 L1");
              id(switch_l1).turn_on();
          } else if (str.compare("A3\r\n") == 0) {
              id(oled_display).fill(COLOR_OFF);
              id(display_text).publish_state("照明 L4");
              id(switch_l4).turn_on();
          } else if (str.compare("A4\r\n") == 0) {
              id(oled_display).fill(COLOR_OFF);
              id(display_text).publish_state("收衣服 A4");
              id(switch_l4).turn_on();
              id(switch_l4r4l3r3l2r2).execute();
          } else if (str.compare("A5\r\n") == 0) {
              id(oled_display).fill(COLOR_OFF);
              id(display_text).publish_state("收起来 A5");
              id(switch_l1).turn_on();
              id(switch_l1r1l4r4).execute();
          } else if (str.compare("A6\r\n") == 0) {
              id(oled_display).fill(COLOR_OFF);
              id(display_text).publish_state("照明 L4a");
              id(switch_l4).turn_on();
          }
    
# if (str.compare("L1\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("上升 L1");
#             id(switch_l1).turn_on();
#           } else if (str.compare("L2\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("停止 L2");
#             id(switch_l2).turn_on();
#           } else if (str.compare("L3\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("调试 L3");
#             id(switch_l3).turn_on();
#           } else if (str.compare("L4\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("照明 L4");
#             id(switch_l4).turn_on();
#           } else if (str.compare("R1\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("上升 R1");
#             id(switch_r1).turn_on();
#           } else if (str.compare("R2\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("停止 R2");
#             id(switch_r2).turn_on();
#           } else if (str.compare("R3\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("调试 R3");
#             id(switch_r3).turn_on();
#           } else if (str.compare("R4\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("照明 R4");
#             id(switch_r4).turn_on();
#           }else if (str.compare("A1\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("上升 A1");
#             id(switch_l1).turn_on();
#             id(switch_l1r1).execute();
#           }else if (str.compare("A2\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("停止 A2");
#             id(switch_l2).turn_on();
#             id(switch_l2r2).execute();
#           }else if (str.compare("A3\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("调试 A3");
#             id(switch_l3).turn_on();
#             id(switch_l3r3).execute();
#           }else if (str.compare("A4\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("照明 A4");
#             id(switch_l4).turn_on();
#             id(switch_l4r4).execute();
#           }else if (str.compare("A5\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("下降 A5");
#             id(switch_l3).turn_on();
#             id(switch_l3r3l2r2).execute();
#           }else if (str.compare("L5\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("下降 L5");
#             id(switch_l3).turn_on();
#             id(switch_l3l2).execute();
#           }else if (str.compare("R5\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("下降 R5");
#             id(switch_r3).turn_on();
#             id(switch_r3r2).execute();
#           }else if (str.compare("A6\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("关掉");
#             id(switch_l1).turn_on();
#             id(switch_l1r1l4r4).execute();
#           }else if (str.compare("A7\r\n") == 0) {
#             id(oled_display).fill(COLOR_OFF);
#             id(display_text).publish_state("收衣服");
#             id(switch_l4).turn_on();
#             id(switch_l4r4l3r3l2r2).execute();
#           }


remote_transmitter:
  pin: 2
  carrier_duty_percent: 100%
 

# 配置 I2C 总线,用于连接 OLED 屏幕
i2c:
  sda: 14
  scl: 12
  scan: true

# 配置 OLED 显示
display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    id: oled_display
    #update_interval: 10ms  # 缩短更新间隔,提高实时性
    lambda: |-
      it.fill(COLOR_OFF);
      it.print(15, 15, id(my_font), id(display_text).state.c_str());

# 配置字体
font:
  - file: "SIMHEI.TTF" # 用SSH访问esphome 可以直接把电脑的字体拖进去用
    id: my_font
    size: 25
    glyphs: [打开关闭晾衣服收起来上升停止下降照明调试1234567890LRA,"\u0020"]

text_sensor:
  - platform: template
    name: "Display Text"
    id: display_text
    
script:
  - id: switch_l1r1
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r1).turn_on();
  - id: switch_l2r2
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r2).turn_on();
  - id: switch_l3r3
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r3).turn_on();
  - id: switch_l4r4
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r4).turn_on();

  - id: switch_l3l2
    then:
      - delay: 13000ms
      - lambda: |-
          id(switch_l2).turn_on();
  - id: switch_r3r2
    then:
      - delay: 13000ms
      - lambda: |-
          id(switch_r2).turn_on();

  - id: switch_l3r3l2r2
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r3).turn_on();
      - delay: 13000ms  
      - lambda: |-
          id(switch_l2).turn_on();
      - delay: 500ms
      - lambda: |-
          id(switch_r2).turn_on();

  - id: switch_l4r4l3r3l2r2
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r4).turn_on();
      - delay: 500ms
      - lambda: |-
          id(switch_l3).turn_on();
      - delay: 500ms  
      - lambda: |-
          id(switch_r3).turn_on();
      - delay: 13000ms  
      - lambda: |-
          id(switch_l2).turn_on();
      - delay: 500ms
      - lambda: |-
          id(switch_r2).turn_on();

  - id: switch_l1r1l4r4
    then:
      - delay: 500ms
      - lambda: |-
          id(switch_r1).turn_on();
      - delay: 500ms
      - lambda: |-
          id(switch_l4).turn_on();
      - delay: 500ms
      - lambda: |-
          id(switch_r4).turn_on();

switch:
  - platform: template
    name: "Send Data"
    id: send_data
    turn_on_action:
      - uart.write: "Hello, Serial Device!\n"

  - platform: template
    name: Right Pole up
    id: switch_r1
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '0100111000100110001100000000000000010001'
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Right Pole Stop
    id: switch_r2
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '0100111000100110001100000000000001010101'
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Right Pole down
    id: switch_r3
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '0100111000100110001100000000000000110011'
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Right Light
    id: switch_r4
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '0100111000100110001100000000000000001111'   
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Left Pole up
    id: switch_l1
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '1101110110001110000100100000000000010001'
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Left Pole Stop
    id: switch_l2
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '1101110110001110000100100000000001010101'
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Left Pole down
    id: switch_l3
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '1101110110001110000100100000000000110011'
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us
  - platform: template
    name: Left Light
    id: switch_l4
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '1101110110001110000100100000000000001111'   
          protocol:
            pulse_length: 350
            sync: [14, 4]
            zero: [1, 2]
            one: [2, 1]
          repeat:
            times: 5
            wait_time: 7500us

4.单片机部分代码

// 处理函数
void User_handle(uint8 dat) 
{
    if (dat >= BTN_1_CODE && dat <= BTN_6_CODE) 
    {
        // 根据 dat 的值直接输出对应的字符串
        switch (dat) 
        {
            case BTN_1_CODE:
                PrintCom("A1\r\n");
                break;
            case BTN_2_CODE:
                PrintCom("A2\r\n");
                break;
            case BTN_3_CODE:
                PrintCom("A3\r\n");
                break;
            case BTN_4_CODE:
                PrintCom("A4\r\n");
                break;
            case BTN_5_CODE:
                PrintCom("A5\r\n");
                break;
            case BTN_6_CODE:
                PrintCom("A6\r\n");
                break;
        }
    } 
    else 
    {
        // 其他无效指令的处理
        // PrintCom("无效指令\r\n");
    }
}
uint8 code sRecog[DATE_A][DATE_B] = {
									"da kai",\
									"guan bi",\
									"zhao ming",\
									"shou yi fu",\
									"shou qi lai",\
									"kai deng"
									};	
									//打开
									//关闭
									//照明
									//收衣服
									//收起来
									//开灯
uint8 code pCode[DATE_A] = {
							BTN_1_CODE,\
							BTN_2_CODE,\
							BTN_3_CODE,\
							BTN_4_CODE,\
							BTN_5_CODE,\
							BTN_6_CODE};	
							/*添加识别码,用户修改*/	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值