【免费开源】STM32 MQTT远程继电器网关4路智能开关物联网控制完整工程项目分享

【免费开源】STM32 MQTT远程继电器网关4路智能开关物联网控制完整工程项目分享 【免费开源】STM32 MQTT远程继电器网关4路智能开关物联网控制完整工程项目分享一、项目背景物联网时代越来越多的家电、工业设备需要远程一键开关功能。本项目基于 STM32 的 MQTT 远程继电器网关使用 STM32F103 W5500或 ESP8266 4 路继电器构建一个标准的 MQTT 客户端可以连接公开 Broker如 EMQX、阿里云、OneNET、自建 Mosquitto订阅控制主题、发布状态主题将物理继电器纳入 MQTT 总线秒级响应远端指令。主要特性标准 MQTT 3.1.1 客户端支持 QoS0/1支持 4 路继电器、4 路输入检测支持遗嘱消息LWT离线立即被云端感知通过 Web 端 / 微信小程序 / Home Assistant 都可以控制配置参数WiFi、Broker、Topic通过串口动态写入 Flash 保存。二、系统流程图否是否是是否是否STM32 上电读取 Flash 配置:WiFi/Broker/ClientID/TopicESP8266 启动 连接 WiFiWiFi 已连接?红灯闪烁 重试发送 MQTT CONNECT 报文包含 LWTCONNACK 成功?订阅 cmd/relay/发布 online 状态进入主循环收到 PUBLISH?解析 Topic 与 Payloadrelay 编号有效?忽略控制 GPIO 翻转继电器发布状态到 stat/relay/N每 30s 发送 PINGREQ三、硬件方案设备STM32 引脚W5500/ESPSPI1 / UART2RELAY1~4PB0~PB3INPUT1~4PA4~PA7状态 LEDPC13配置按键PA0四、核心代码4.1 简化版 MQTT 报文打包#includemqtt.h#includestring.hstaticintencode_remaining(uint8_t*p,intrl){inti0;do{uint8_tbrl0x7F;rl7;if(rl)b|0x80;p[i]b;}while(rl);returni;}intMQTT_BuildConnect(uint8_t*out,constchar*cid,constchar*user,constchar*pwd,uint16_tkeep){uint8_t*pout;*p0x10;uint8_tvar[256];intvi0;/* protocol name */var[vi]0;var[vi]4;memcpy(varvi,MQTT,4);vi4;var[vi]4;/* version 3.1.1 */uint8_tflags0xC2;/* userpwdcleanSession */var[vi]flags;var[vi]keep8;var[vi]keep0xFF;/* payload */intclstrlen(cid),ulstrlen(user),plstrlen(pwd);var[vi]cl8;var[vi]cl0xFF;memcpy(varvi,cid,cl);vicl;var[vi]ul8;var[vi]ul0xFF;memcpy(varvi,user,ul);viul;var[vi]pl8;var[vi]pl0xFF;memcpy(varvi,pwd,pl);vipl;pencode_remaining(p,vi);memcpy(p,var,vi);pvi;returnp-out;}intMQTT_BuildPublish(uint8_t*out,constchar*topic,constchar*payload){uint8_t*pout;*p0x30;inttlstrlen(topic),plstrlen(payload);intrl2tlpl;pencode_remaining(p,rl);*ptl8;*ptl0xFF;memcpy(p,topic,tl);ptl;memcpy(p,payload,pl);ppl;returnp-out;}intMQTT_BuildSubscribe(uint8_t*out,uint16_tpid,constchar*topic,uint8_tqos){uint8_t*pout;*p0x82;inttlstrlen(topic);intrl22tl1;pencode_remaining(p,rl);*ppid8;*ppid0xFF;*ptl8;*ptl0xFF;memcpy(p,topic,tl);ptl;*pqos;returnp-out;}4.2 主循环基于 ESP8266 透传#includemain.h#includemqtt.h#includestdio.hexternUART_HandleTypeDef huart2;/* to ESP */staticvoiduart_send(constuint8_t*b,intn){HAL_UART_Transmit(huart2,(uint8_t*)b,n,200);}staticvoidat_cmd(constchar*c){uart_send((uint8_t*)c,strlen(c));HAL_Delay(800);}voidRelay_Set(inti,inton){GPIO_TypeDef*pGPIOB;uint16_tpinGPIO_PIN_0i;HAL_GPIO_WritePin(p,pin,on?GPIO_PIN_SET:GPIO_PIN_RESET);}intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();/* ESP 进入透传 */at_cmd(ATCWMODE1\r\n);at_cmd(ATCWJAP\my-wifi\,\12345678\\r\n);HAL_Delay(3000);at_cmd(ATCIPSTART\TCP\,\broker.emqx.io\,1883\r\n);at_cmd(ATCIPMODE1\r\n);at_cmd(ATCIPSEND\r\n);/* 发送 MQTT CONNECT */uint8_tbuf[128];intnMQTT_BuildConnect(buf,stm32gw01,user,pwd,60);uart_send(buf,n);HAL_Delay(500);/* SUBSCRIBE */nMQTT_BuildSubscribe(buf,1,cmd/relay/,0);uart_send(buf,n);while(1){/* 在 UART2 接收中断里解析 PUBLISH 包解析后调用 Relay_Set */HAL_Delay(100);/* 周期心跳 */staticuint32_tping0;if(HAL_GetTick()-ping20000){uint8_tpingreq[2]{0xC0,0x00};uart_send(pingreq,2);pingHAL_GetTick();}}}五、关键技术解析5.1 LWT 遗嘱消息CONNECT 报文 flags 中设置 will flag可以让 Broker 在客户端异常掉线时主动发布stat/onlineoffline从而实现秒级离线感知是工业网关必备能力。5.2 主题设计cmd/relay/{n}下行控制payload:ON/OFF/TOGGLEstat/relay/{n}上行状态stat/online在线/离线这种命令-状态分离的主题设计是 Home Assistant 的标准做法便于自动发现集成。5.3 配置存储WiFi、Broker、ClientID 保存在 Flash 最后一页STM32F103 一页 1KB。结构体 CRC16 校验避免上电读出垃圾数据。5.4 抖动消抖物理输入信号要做 30ms 防抖避免按一次按钮上报多次。六、应用场景工厂车间设备远程开关、定时启停智能家居灯光、风扇、热水器联动自助洗车、共享充电柜的远程控制配合 Home Assistant 让家里的哑设备接入 HomeKit/小爱同学。七、调试经验ESP8266 透传模式之前必须建立 TCPMQTT Keepalive 设小一点30~60s避免 NAT 超时payload 要避免使用换行符防止 ESP 把它解析成 AT 终止推荐使用 EMQX 公网测试 Brokerbroker.emqx.io:1883免账号密码。八、总结本项目以最小代价构建了一个产品级 MQTT 智能继电器网关源码简洁、协议规范是嵌入式工程师入门 IoT 的最佳样板。配套的开源代码、原理图、上位机示例 APK 都打包在项目源码包中开箱即用。