
简介这是面向STM32与物联网开发者的项目实战代码基于STM32F103与ESP8266通过MQTT协议接入腾讯云物联网平台并支持腾讯连连小程序覆盖设备上云、数据主动上报与远程控制下发。压缩包共187个文件、6.36MB以45个h头文件、43个c源文件为主辅以目标文件、编译配置及hex固件包含STM32标准外设库、ESP8266驱动、MQTT协议层等关键模块便于二次开发与学习。代码基于KEIL开发当前适配STM32F103C8T6也可通过修改芯片型号和FLASH容量用于其他F103型号实现了多路继电器状态上报及平台指令下发动作逻辑并在工程中给出J-Link/S-T-Link下载器选型提醒。资源已有2603人学习适合正在从事STM32物联网项目、希望快速接入云平台并借鉴数据交互与控制流程的开发者参考。 做物联网项目实战被问得最多的问题就是怎么把手里的单片机连上云用手机随时随地看数据。这篇文章就围绕一套最典型的组合方案展开——STM32作为主控ESP8266负责WIFI联网数据传输走MQTT协议云平台选腾讯云物联网云平台最终在腾讯连连小程序里完成设备绑定、数据查看和指令下发。整条链路覆盖硬件接线、云平台配置、代码编写和联调四个环节适合做课程设计、毕业设计、或者单纯想给个人DIY项目加上远程监控能力的读者。下面所有内容都是我自己反复跑通过的项目记录照着做基本能一次走通。1. 整体方案为什么是STM32ESP8266MQTT腾讯云1.1 硬件组合的取舍逻辑主控选择STM32F103C8T6理由很直接价格便宜、资料铺天盖地、库函数和HAL库都成熟读几个传感器、跑一个数据上报任务绰绰有余。ESP8266则负责WIFI这一层模块十几块钱AT指令交互简单既能当透传通道也能承载MQTT报文的收发。有朋友问我为什么不直接用带WIFI的ESP32甚至干脆让ESP8266自己跑逻辑我的看法是STM32管业务ESP8266只管联网两者各司其职后面要换平台、换网络模块主控代码几乎不用动。比如我把网络层从ESP8266换成4G模块或者改成以太网只需要替换驱动部分的实现传感器采集、数据处理、本地控制逻辑完全复用。对于毕设和产品原型来说这种分层结构维护成本低排查问题时也能按层切分。还有个容易踩的坑是电平。STM32串口输出是3.3V TTLESP8266串口也是3.3V TTL两者之间能直接连不需要转换。我见过不少新手习惯性用5V去拉一上电模块就冒烟了。尤其是从Arduino转到STM32的朋友这个习惯必须改。1.2 协议与平台的选型逻辑MQTT是物联网领域的事实标准协议核心是发布/订阅模型。设备往主题发布消息云端、App订阅主题接收消息设备也可以订阅另一个主题来接收指令。这种解耦方式特别适合“远程看数据、远程控制设备”这种需求。选腾讯云物联网平台IoT Explorer一个关键原因是有腾讯连连小程序。它省去了我从零开发App的工作量小程序里搜索添加设备直接能看到属性数据、下发控制指令。对于项目验收、现场演示来说这种“打开微信就能用”的体验很加分。如果自建EMQX加网页客户端还得处理域名、证书、鉴权设备端联调成本高不少。在开始写代码前我建议先花半小时把MQTT的CONNECT、CONNACK、PUBLISH、SUBSCRIBE这几个核心报文概念过一遍。腾讯云连接参数里的ClientID、用户名、密码本质上就对应CONNECT报文里的字段。理解了这个后面配置参数就不是玄学而是有逻辑可循的操作。2. 环境准备与硬件接线动手前的必修课2.1 开发工具链搭建STM32这边用Keil MDK最成熟。装完Keil后要装STM32F1系列的芯片支持包否则编译器不认识F103C8T6。烧录工具我习惯用ST-Link配合STM32CubeProgrammer或者ST-Link Utility都行。如果只写简单串口程序用串口ISP方式也能烧但调试体验差很多建议直接上ST-Link。ESP8266这边大部分模块出厂就预刷了AT固件电脑上装个串口助手XCOM、正点原子串口助手都行就能直接调试。如果固件版本太老或者没有MQTT指令就用乐鑫的Flash Download Tools重新烧写。烧录时把GPIO0拉低进入下载模式固件写到0x00000地址波特率设为115200点击START就行。刷完后重新上电串口发AT返回OK就代表固件正常。如果是用Arduino IDE开发ESP8266需要先在开发板管理器里添加esp8266支持包这个网上教程很多。不过我这套方案里ESP8266只跑AT固件STM32通过串口发AT指令来控制它不在ESP8266上写业务代码。优势是代码量少、调试直观也最贴近很多学校课程里教的AT指令操作方式。2.2 硬件清单与接线硬件部分我常用的清单如下STM32F103C8T6最小系统板 ESP8266模块ESP-01S、ESP-12F、NodeMCU均可 USB转TTL模块CH340芯片即可 ST-Link V2下载器 杜邦线若干接线是整个项目最容易出问题的一步不是接线本身难而是电源和共地经常被忽略。正确接法是STM32的USART1_TXPA9连接ESP8266的RXDSTM32的USART1_RXPA10连接ESP8266的TXDGND两端必须连在一起。供电这里我多提醒一句ESP8266在连接WIFI的瞬间电流峰值能达到300mA以上。如果直接用STM32板上的3.3V给它供电电压容易被瞬间拉低导致模块反复重启或者连接失败。我最早跑实验时就是贪方便直接从最小系统板取电结果连WIFI十次有八次失败排查了半天才发现是供电不足。现在我的做法是给ESP8266单独用AMS1117-3.3稳压模块供电或者至少并联一个大容量的电解电容稳住电压。2.3 AT固件版本与联网预验证ESP8266的固件版本直接决定后面代码能不能跑通。我推荐用安信可官方较新的AT固件因为老版本固件只支持TCP/UDP透传不支持MQTT指令。新固件多了ATMQTTUSERCFG、ATMQTTCONN这些指令通过串口就能完成MQTT连接、订阅、发布省去在STM32里手动拼MQTT报文的麻烦。在接入STM32之前强烈建议先把ESP8266单独接到电脑上用串口助手验证一遍联网能力。操作是这样ATCWMODE1 // 设置为Station模式 ATCWJAPYourSSID,YourPassword // 连接路由器正常情况下会返回WIFI CONNECTED接着返回WIFI GOT IP说明模块已经拿到IP地址。这一步提前验证能把“WIFI问题”和“MQTT问题”分开后面联调时如果连接云端失败至少能确定WIFI这层是通的不用从头排查。3. 腾讯云物联网平台配置拿三元组和连接参数3.1 创建产品与数据模板腾讯云物联网开发平台的入口叫IoT Explorer登录后先创建产品。产品类型选“普通产品”节点类型选“设备”联网方式选“WIFI”数据协议建议选“数据模板”模式。数据模板的好处是平台会帮你生成一套标准化的Topic和JSON数据格式腾讯连连小程序能直接识别。数据模板的定义是整个平台配置的基石。举个例子做温湿度采集就在数据模板里定义两个属性temp浮点型、humidity浮点型。字段名、数据类型、读写权限都要认真填因为后面设备上报的JSON字段名必须和模板完全一致平台才会接收否则数据会被丢弃。模板保存后记得在产品层面发布一次不发布的话腾讯连连添加设备时会找不到该产品。3.2 创建设备并保存三元组在产品下创建设备平台会自动分配三元组信息ProductID产品ID、DeviceName设备名称、DeviceSecret设备密钥。这三个值就是设备端接入云端的“身份证”后面写AT指令或用MQTT客户端测试时全都要用到。这里有个细节设备创建后控制台里设备状态显示是“未激活”这不代表有问题只要设备第一次成功接入云平台状态就会自动变成“上线”。另外我习惯把三元组单独存到一个文本文件里写代码、配参数都从里面复制避免手动输入时打错字符。尤其ProductID是数字和字母混合的长字符串手输很容易出错。3.3 MQTT连接参数计算与验证腾讯云物联网平台的MQTT接入地址格式是{ProductID}.iotcloud.tencentdevices.com调试阶段用1883端口明文正式生产再考虑8883端口的TLS加密。连接时需要三个参数ClientID、UserName、PassWord。以我实际项目用到的规则来说格式大致如下ClientID {ProductID}.{DeviceName} UserName {ProductID}.{DeviceName};12010126;{时间戳};{signature} PassWord {signature}其中signature是用DeviceSecret对{ProductID}{DeviceName}做HMAC-SHA256再转成小写十六进制字符串。不同时期的平台文档对签名原文的说明可能略有差异所以我的习惯是先去控制台的“设备调试”页面看它给出的连接参数示例再照着算。计算我用Python脚本import hmac, hashlib, time ProductID 你的产品ID DeviceName 你的设备名 DeviceSecret 你的设备密钥 timestamp str(int(time.time())) sign_content (ProductID DeviceName).encode() signature hmac.new(DeviceSecret.encode(), sign_content, hashlib.sha256).hexdigest() print(timestamp:, timestamp) print(signature:, signature)把算出的ClientID、UserName、PassWord填进MQTT客户端测试工具比如MQTTX能连上并且设备状态变成“上线”说明参数没问题。很多连接失败的案例最后查出来都是签名规则里的字符串多了空格、换行或者时间戳不是服务器当前时间用脚本算一次再去和代码里的结果对比效率会高很多。4. 代码实现STM32ESP8266打通MQTT全链路4.1 STM32串口驱动与数据处理STM32侧的核心工作可以拆成三块读传感器数据、格式化数据、通过串口控制ESP8266收发AT指令。我用STM32CubeMX初始化USART1波特率1152008位数据位、1位停止位、无校验然后开启接收中断。ESP8266的AT指令都是以\r\n结尾应答也是以\r\n结尾。如果串口驱动一收到字节就立刻处理很容易把一条完整的MQTTCONNED: 0拆成好几段导致解析失败。我的做法是在驱动层做一个简单的环形缓冲区串口中断只负责把数据塞进缓冲区主循环里按行读取收到\r\n才做一次完整的指令匹配。这样判断“是否收到OK”“是否收到WIFI GOT IP”都非常方便。4.2 AT指令流程与数据上云程序启动后STM32按下面这个顺序下发AT指令ATCWMODE1 ATCWJAPYourSSID,YourPassword # 等待返回 WIFI GOT IP ATMQTTUSERCFG0,0,clientID,userName,password,0,0, ATMQTTCONN0,yourProductID.iotcloud.tencentdevices.com,1883,1 # 等待返回 MQTTCONNED: 0 ATMQTTSUB0,$thing/down/property/{ProductID}/{DeviceName},1 ATMQTTPUB0,$thing/up/property/{ProductID}/{DeviceName},{\type\:\report\,\clientToken\:\123\,\data\:{\temp\:25.5,\humidity\:60}},0,0这套流程是基于带MQTT功能的AT固件写的不同固件指令集有差异但整体思路一致配网、配置MQTT参数、连接云端、订阅主题、发布数据。其中需要重点理解的是Topic。$thing/up/property/{ProductID}/{DeviceName}是属性上报的Topic传感器数据封装成JSON后通过PUBLISH报上去$thing/down/property/{ProductID}/{DeviceName}是属性下发Topic小程序下发指令时STTM32订阅该主题后能收到云端推过来的JSON。Payload的格式可以直接从腾讯云控制台的“设备调试”里复制示例把字段值替换成自己的数据即可。4.3 腾讯连连小程序绑定与验证设备端跑起来后在微信里搜索“腾讯连连”小程序登录同一个腾讯云账号点击添加设备按产品ID和设备名称填写绑定信息。这里有个关键点腾讯连连绑定设备时填的是产品ID、设备名称不是扫标签上的二维码。如果设备还没激活或者产品没有发布小程序会一直提示“添加失败”。我的验证顺序是先在PC控制台看到设备状态是“上线”再去小程序添加设备这样能快速定位问题出在设备端还是小程序端。如果小程序提示“设备已被绑定”说明这个DeviceName之前被添加过了。处理方法就是在控制台删除该设备重建一个或者在小程序里解绑旧设备。实际演示时遇到这类问题不用慌多半是重复绑定造成的。5. 实测踩坑记录与排查速查表5.1 ESP8266连不上WIFI怎么办ATCWJAP返回ERROR或一直FAIL最常见的原因有三个SSID密码填错、路由器是5G频段、信号太弱。ESP8266只支持2.4G频段很多双频路由器默认开了5G手机能连上但模块扫不到。排查顺序我一般是这样先用手机确认路由器是2.4G还是5G频段5G频段直接换个热点测试确认WIFI密码末尾没有多余空格复制粘贴时极容易带上换行符把模块靠近路由器再测试排除信号强度问题反复失败时重启模块和路由器重新发送ATCWJAP。另一个容易被忽略的是路由器开启了AP隔离设备之间无法互相通信。在校企网络、办公室网络里特别常见。我吃过一次亏排查半天最后换了手机热点才解决。所以在实验室或办公环境测试直接用手机开热点是最省心的方案。5.2 MQTT连接超时或返回ERRORATMQTTCONN返回ERROR或者一直没响应大概率是三个参数之一填错了ClientID格式不对、签名算法算错、端口不匹配。排查思路确认当前没有其他MQTT客户端在占用同一个设备连接腾讯云一个设备一般只允许一个在线连接重复连接会把前面的踢下线确认时间戳是服务器当前时间如果开发板本地时间不准用了旧的固定时间戳平台会拒绝鉴权用MQTTX这类PC客户端先手动填一次参数如果能连上说明参数正确问题出在ESP8266固件或AT指令拼写上。另外网上很多教程的签名规则来自其他云平台比如OneNET或阿里云各平台的算法和参数分隔符不一样不能直接套用。照着本文最后的Python脚本算一遍再去对照控制台给出的连接参数示例是最靠谱的。5.3 数据上报到平台后看不到或刷新不及时数据上报成功但控制台没显示先检查PUBLISH的Topic和Payload格式。JSON字段名必须与数据模板里的定义完全一致多一个下划线、大小写不对平台都会当成无效数据丢弃。腾讯连连小程序刷新延迟通常和订阅Topic有关。设备端要确保已经成功订阅了$thing/down/property/...这个下行Topic因为腾讯连连的数据展示和指令下发都依赖这个通道。如果订阅失败设备能上报数据但小程序里的指令发不下去表现为“只能看不能控”。我联调时的一个习惯是把STM32串口1的AT交互原样打印到调试串口相当于给项目装了“黑匣子日志”。哪条指令没成功、哪个应答超时直接看日志一目了然不用靠猜。这个习惯在整个项目调试阶段能节省大量时间尤其是现场排查问题时日志就是最直接的证据。最后再说个经验这个项目的技术点不复杂但链路长、节点多从硬件供电到云平台鉴权每一层都可能出问题。按“底层到上层”的顺序排查——先看供电稳不稳再看WIFI通不通然后验证MQTT参数对不对最后检查数据模板匹不匹配——能最快定位问题。这组方案我后来复用了好多次做过温湿度监控、远程开关、报警通知几个变体整体稳定性和开发效率都很满意。如果你也在折腾类似的东西先按这条最小链路跑通再往上加你的业务逻辑后面会轻松很多。本文还有配套的精品资源点击获取