ESP-01S+STM32连接home assistant
1. 概述
-
首先在ESP-01S中烧录AT指令集
-
配置HA系统,添加MQTT服务器(内核版)
-
向HA系统添加一个LED实体
-
HA系统订阅消息,对LED进行操作
-
ESP-01S连接STM32的串口,STM32发送AT指令集中的MQTT指令,使用MQTTX进行检测
-
本次文档目标是实现HA中的开关控制连接STM32引脚的一个LED亮灭
-
完成本次项目需要:VM虚拟机安装HA系统,STM32开发板,ESP-01S,杜邦线,USB-TTL串口下载器,LED,100Ω电阻
2. ESP-01S烧录AT指令集
-
上位机下载烧录软件–ESPFlashDownloadTool_v3.6.4.exe
找到官网下载:
-
连接ESP-01S与烧录器,连接烧录器和上位机(电脑)
此处使用专用烧录器,若没有可使用USB-TTL,连线自行网络搜索
EN注意也需接3V3
-
下载指令集,选中AT-MQTT指令集对应的bin文件烧录
至安信可官方下载,选择1471固件,这个估件较小只需1M即可
AT固件汇总 | 安信可科技 (ai-thinker.com)
接着打开flash软件(ESPFlashDownloadTool_v3.6.4.exe),选择ESP8266,选择下载好的bin文件,完成下图设置,点击START完成烧录
-
使用putty验证烧录成功
- 选择serial, 填入COM编号, 例如COM3, 波特率设为115200, 直接连接.
- 发送命令的操作: 输入命令
AT
, 然后回车
, 然后按Ctrl+J
发送. - 若回复OK则表明烧录成功
3. HA集成MQTT服务器
-
step1:配置MQTT集成
- 此处使用公共MQTT服务器免费的公共 MQTT 服务器 | EMQ (emqx.com)
- 配置集成方法:homeassistant配置MQTT集成以及传感器实体(STM32连接进入homeassistant)_homeassistant mqtt-CSDN博客
设置时IP设置为下面查询到的IP
- 使用下列网址获取公共服务器的IP:broker.emqx.io服务器iP broker.emqx.io域名解析 broker.emqx.ioiP查询 broker.emqx.io域名iP查询 (ip138.com)
-
step2:下载可视化MQTT客户端工具MQTTX,验证服务器搭载完成:免费下载、试用 EMQ 产品 (emqx.com)
-
step3:测试连接
说明:使用公共服务器时发现HA发出消息会堵塞,可能由于公共服务器接入过多设备的原因,由于十分影响使用体验所以在EMQX官网购买了一个服务器,前14天可有免费使用,后续可换成按流量计费的服务器,1.5元/GB,价格不算贵。
4. HA安装插件——samba
该插件可用于在Win或Mac系统上共享HA系统文件,从而去修改configuration.yaml文件
-
step1:安装插件
-
step2:修改配置(设置密码,ip)
-
step3:保存并启动
-
step4:本机win+r,输入 \ \ +ip进入共享文件夹,进入即可找到文件
熟悉Linux系统:此处也可下载插件Terminal,在HA系统进入系统中端使用Linux指令访问配置文件
5. 修改configuration.yaml文件增加MQTT设备
-
常见格式
mqtt: switch: #设备类型 - unique_id: led_1 #设备ID name: "led_1" #设备名称 state_topic: "LED" #订阅端口 command_topic: "LED" #同上 payload_on: "1ON" #开灯的指令 payload_off: "1OFF" #关灯的指令 - unique_id: led_2 #设备ID name: "led_2" #设备名称 state_topic: "LED" #订阅端口 command_topic: "LED" #同上 payload_on: "2ON" #开灯的指令 payload_off: "2OFF" #关灯的指令
相关说明:
mqtt仅出现一次,switch等属于卡片类型,添加设备通过-unique_id属性
-
增加卡片
-
步骤:概览——添加卡片,找到添加的实体
-
-
测试添加是否成功
-
连续点击卡片开关
-
使用MQTTX连接(见上)
-
修改为其他主题也可以:
6. ESP8266基于AT指令MQTT服务器通信——使用MQTTX进行测试
-
常用AT指令
-
PuTTY发送AT指令(ESP-01S连接电脑)
-
配置WIFI(仅需配置1次)
#恢复出厂设置 AT+RESTORE #设置WIFI模式,=1对应上电自动连接存储在FLASH的WIFI AT+CWMODE=1 #扫描当前可用WIFI的信息 AT+CWLAP #连接WIFI,分别是WIFI名称,密码 AT+CWJAP="SSID","PWD" #查询当前连接WIFI信息 AT+CWSTATE?
-
配置MQTT连接信息
AT+MQTTUSERCFG=0,1,"MQTTID","admin","root",0,0,"" #对于项目使用的公共服务器,此处可随便填写“”内参数
-
连接MQTT服务器
#IP填写以前所找到域名的对应IP at+mqttconn=0,"54.146.113.169",1883,0 #连接内核服务器 at+mqttconn=0,"8.137.51.61",1883,0
-
发布和订阅消息
#发布LED主题消息 AT+MQTTPUB=0,"LED","LED ON",1,0 #订阅LED主题消息,可以同时订阅多个主题 AT+MQTTSUB=0,"LED",1 AT+MQTTSUB=0,"STM",1 #取消连接 AT+MQTTCLEAN=0
-
-
-
测试连接结果
7. STM32连接ESP8266,发送消息测试
电路连线
将ESP-01S的RXD、TXD分别与STM32的TXD和RXD相接,再连接两个模块的VCC与GND
以STM32F103C8T6为例,连接其串口2,接线如下图
-
此处修改为使用STM32的串口3(网上找到的示例代码为串口3,懒得修改所以换了下)
USART3–TXD USART3–RXD PB10 PB11
ESP8266驱动代码
参考:
核心函数
- ESP8266初始化——void ESP8266_Init(void),用于连接服务器
- ESP8266重复发送AT指令直至成功——_Bool ESP8266_SendCmd(char *cmd, char *res)
STM32发送MQTT消息——主要为传感器使用
//注意""需要加上转移符号\
ESP8266_SendCmd("AT+MQTTSUB=0,\"LED\",\"1\",1,0","OK");
HAL_Delay(100);//堵塞
STM32接收MQTT消息——HA控制核心
//main.c加入中断回调函数,用于接收消息
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart3)//esp8266接收云平台数据
{
if(esp8266_cnt >= sizeof(esp8266_buf))
{
esp8266_cnt = 0; //防止串口被刷爆
}
esp8266_buf[esp8266_cnt++] = Uart3_RxData;
HAL_UART_Receive_IT(&huart3,(uint8_t *)&Uart3_RxData, 1); //&取地址
}
}
//==========================================================
// 函数名称: Get_MQTTMessage_Topic
//
// 函数功能: MQTT主题检测函数
//
// 入口参数: uchar*
//
// 返回参数: 主题标志--LED=1,STM=2,
//
// 使用举例: int topicNum = Get_MQTTMessage_Topic(esp8266_buf);
//==========================================================
int Get_MQTTMessage_Topic(unsigned char *message)
{
if(strstr((char *)message, "LED")){return 1;}
else if(strstr((char *)message, "STM")){return 2;}
else {return 0;}
}
//==========================================================
// 函数名称: Get_MQTTMessage_Topic
//
// 函数功能: MQTT父主题下子设备检测函数
//
// 入口参数: message--消息
// key--设备响应关键字
//
// 返回参数: 关键字存在:1,不存在:0
//
// 使用举例: if(MQTTMesssage_Exsit_Key(esp8266_buf, "1ON")){...}
//==========================================================
_Bool MQTTMesssage_Exsit_Key(unsigned char *message, unsigned char *key)
{
if(strstr((char *)message, (char *)key)){return 1;}
else{return 0;}
}
//main()调用
...
while(1){
uint8_t topic = Get_MQTTMessage_Topic(esp8266_buf);
if (topic==1)//LED Topic
{
if(MQTTMesssage_Exsit_Key(esp8266_buf, "1ON")){//LED1 ON
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
printf("\r\n");//发送任意指令!!!
HAL_Delay(100);
}
else if(MQTTMesssage_Exsit_Key(esp8266_buf, "1OFF")){//LED2 OFF
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
printf("\r\n");
HAL_Delay(100);
}
}
}
...
-
踩坑1:解析收到的消息
- 说明:一开始使用strlen()函数求取消息长度,调试结果如下:
> 该字符串长度理应为24,但使用串口进行调试打印length却是19。
>
> 思考后发现19对应的是"LED"结束处长度,说明strlen函数匹配字符串结束使用的是\0标志。因此子字符串也会影响结果,所以求取的length结果不正确
>
> 最后,索引固定格式(后续进行说明),将上位机发送的消息**规定格式**,即可确定key的位置是23,修改代码返回[length+4]处字符
>
> 但经过测试还是不行,最终修改配置文件,变为使用strstr()检测诸如”1ON“关键词
-
踩坑2:每次使用前注意清除连接MQTT服务器信息——插上电脑使用Putty发送
AT+MQTTCLEAN=0
,或使用USB-TTL复位键清除连接信息 -
踩坑3:调用命令后需要向串口发任意信息,这点具体原因不清楚,可能是while(1)扫描过快,接收MQTT服务器信息被堵塞了,导致LED无法响应指令
uint8_t topic = Get_MQTTMessage_Topic(esp8266_buf); if (topic==1)//LED Topic { if(MQTTMesssage_Exsit_Key(esp8266_buf, "1ON")){//LED1 ON HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); printf("\r\n");//发送任意指令!!! HAL_Delay(100); } else if(MQTTMesssage_Exsit_Key(esp8266_buf, "1OFF")){//LED2 OFF HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); printf("\r\n"); HAL_Delay(100); } }
-
调试建议:
- ESP-01插入USB-TTL连接电脑,杜邦线连接USB-TTL和STM32
- 文件中添加串口重定向函数,使用printf打印变量
- 打开Putty连接对应COM
这样既可以显示输出的指令,也可以显示收到的消息
-
HA配置发送消息格式(此种检测较为稳定且简单)
- 例如某个设备1开启对应的指令设置为”1ON“,结合"LED"主题检测即可实现LED1的控制信息检测
8. STM32连接HA系统点亮LED流程
- STM32配置注意事项:串口3异步开启中断、时钟72MHz、GPIO推挽接LED
- STM32通过串口向ESP8266发送AT指令连接服务器,订阅LED主题消息,STM32同时处理订阅消息,通过MQTTX验证(完成双向通信)
- HA系统通过配置文件增加LED设备,并引入卡片至仪表盘,点击仪表盘卡片,使用MQTTX订阅验证成功
- STM32的PB12引脚接上LED,经过漫长的准备终于成为了点灯大师/(ㄒoㄒ)/~~
9.总结
- 本次项目解决智能家居的难点所在,及打通HA系统与STM32,实现双向通信点亮连接STM32引脚的LED。
- 以此作为基础,其实借助HA平台可以实现许多物联网项目。不仅仅局限于智能家居,HA系统提供了一个十分优秀的联网功能以及前端页面展示,包括WEB、小程序、语音助手等等多种方式,大大降低物联网项目开发所需的时间及精力。而前端UI编写与网络配置等是嵌入式开发人员通常不具备的技能栈,通过home assistant这样的平台使得灵感更加容易实现。只是EMQX提供的公共服务器资源优先,其IP时而变化,不过这个可以通过购买其官网的按流量付费的MQTT服务器解决。
- 此外home assistant可使用插件ESP home、树莓派等接入其他类型的嵌入式设备,同时也可接入小米华为等设公司开发的智能家居生态。不过上述设备均有大量详细教程,且使用插件操作容易,唯独STM32等单片机需要通过WIFI模块+串口AT指令+MQTT协议及服务器从而接入HA系统,本次项目算是将网上各种资源整合最终实现了一个完整的教程~
- 在过程中lz真的踩坑无数,最终找到了这样一个无需租界服务器、配置简单的方案,总而言之,希望这个教程可以帮助想通过HA系统实现DIY创意的朋友少走弯路喵~
10.下一步
- 以杜邦线连接不是特别方便,同时也不牢靠。下一步首先绘制个PCB,以插槽连接STM32和ESP-01S,加个ESP-01S复位按钮以及PCB的上电接口,同时把STM32最小系统板IO口连出方便连线智能家居所需模块。
- 完成后,开始向系统中添加其他所需模块,封装函数替代即可。
- 至此,该项目最大的难点已经解决,剩下的部分网上教程都很多,可复用的模块也很多,就不再赘述了。
,且使用插件操作容易,唯独STM32等单片机需要通过WIFI模块+串口AT指令+MQTT协议及服务器从而接入HA系统,本次项目算是将网上各种资源整合最终实现了一个完整的教程~ - 在过程中lz真的踩坑无数,最终找到了这样一个无需租界服务器、配置简单的方案,总而言之,希望这个教程可以帮助想通过HA系统实现DIY创意的朋友少走弯路喵~
10.下一步
- 以杜邦线连接不是特别方便,同时也不牢靠。下一步首先绘制个PCB,以插槽连接STM32和ESP-01S,加个ESP-01S复位按钮以及PCB的上电接口,同时把STM32最小系统板IO口连出方便连线智能家居所需模块。
- 完成后,开始向系统中添加其他所需模块,封装函数替代即可。
- 至此,该项目最大的难点已经解决,剩下的部分网上教程都很多,可复用的模块也很多,就不再赘述了。