
"HTML → MQTT(EMQX) → ESP8266 → STM32F103"通信链路,正是当前物联网开发中一种非常经典的四层架构 。实现它的核心思路是:Web前端作为控制端,通过 MQTT 协议 与云端 Broker(如 EMQX)交互;ESP8266 作为 Wi-Fi 网关,负责网络数据与 STM32 之间的串口透传;而 STM32F103 则作为主控,解析指令并驱动 GPIO 执行具体操作。
🏗️ 系统架构与硬件选型
-
Web 前端(控制层):负责提供可视化的操作界面,通过 WebSocket 或 MQTT.js 库连接 EMQX Broker,实现指令的发布与设备状态的订阅。
-
ESP8266(网络层):作为 Wi-Fi 模块,通过 UART(通用异步收发传输器)与 STM32 连接。它负责将 STM32 的串口数据转换为 MQTT 报文发送至 EMQX,并将接收到的云端指令通过串口透传给 STM32。
-
STM32F103(执行层):作为主控 MCU,解析串口收到的 JSON 或字符串指令,驱动 GPIO 输出高低电平,控制 LED 或继电器的开关。
🔌 硬件接线参考
ESP8266 通常与 STM32 的特定 UART 引脚连接,以下是常见的接线方式(以 STM32F103C8T6 为例):
| STM32F103 | ESP8266 (ESP-01S) | 说明 |
|---|---|---|
| PA2 (USART2_TX) | RX | STM32 发送数据给 ESP8266 |
| PA3 (USART2_RX) | TX | STM32 接收 ESP8266 的数据 |
| 3.3V | VCC & CH_PD | 供电(注意 ESP8266 需 3.3V 供电) |
| GND | GND | 共地 |
💻 嵌入式端(STM32)核心代码实现
在 STM32 端,你需要编写代码驱动 ESP8266 连接 Wi-Fi 并接入 EMQX,同时解析接收到的控制指令。
1. 关键 AT 指令序列
在 STM32 的初始化代码中,需要通过串口发送一系列 AT 指令来配置 ESP8266:
c
// 1. 配置为 Station 模式
UART_SendString("AT+CWMODE=1\r\n");
// 2. 连接 Wi-Fi
UART_SendString("AT+CWJAP=\"Your_WiFi_SSID\",\"Your_WiFi_Password\"\r\n");
// 3. 建立 TCP 连接到 EMQX 服务器
UART_SendString("AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n");
// 4. 启用透传模式(可选,也可手动封装 MQTT 报文)
UART_SendString("AT+CIPMODE=1\r\n");
UART_SendString("AT+CIPSEND\r\n");
2. 控制指令解析逻辑
当 ESP8266 收到云端下发的指令(如 {"LED1":"ON"})并通过串口传给 STM32 时,STM32 需要解析并执行:
c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
// 将接收到的字符存入缓冲区
rx_buffer[rx_index++] = rx_byte;
// 简单判断指令(实际项目中建议使用 cJSON 库解析)
if (strstr((char*)rx_buffer, "LED1:ON") != NULL) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET); // 点亮 PB5 的 LED1
rx_index = 0; // 清空缓冲区
} else if (strstr((char*)rx_buffer, "LED1:OFF") != NULL) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); // 熄灭 PB5 的 LED1
rx_index = 0;
}
HAL_UART_Receive_IT(huart, &rx_byte, 1); // 重新开启接收中断
}
🌐 Web 前端(HTML)实现
Web 界面通过 MQTT.js 库直接连接 EMQX 的 WebSocket 端口,无需额外的后端服务器。
html
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
// 1. 连接 EMQX Broker(WebSocket 端口通常为 8083 或 8084)
const client = mqtt.connect('ws://localhost:8083/mqtt');
client.on('connect', () => {
console.log('已连接到 EMQX Broker');
// 2. 订阅设备状态主题(用于接收 STM32 上报的数据)
client.subscribe('stm32/status');
});
// 3. 发送控制指令
function controlLED(ledId, action) {
const topic = `stm32/cmd/led${ledId}`;
const message = JSON.stringify({ command: action });
client.publish(topic, message);
}
</script>
<!-- 4. 界面按钮绑定 -->
<button οnclick="controlLED(1, 'ON')">点亮 LED1</button>
<button οnclick="controlLED(1, 'OFF')">熄灭 LED1</button>
📡 EMQX Broker 配置
-
安装与启动 :在服务器或本地电脑安装 EMQX,默认 MQTT 端口为
1883,WebSocket 端口为8083。 -
主题设计:建议为控制指令和状态上报设计不同的主题(Topic),例如:
-
控制指令:
stm32/cmd/led1 -
状态上报:
stm32/status
-
💡 调试与注意事项
-
网络稳定性:ESP8266 对电源和信号干扰比较敏感,建议使用稳定的 3.3V 电源,并确保 Wi-Fi 信号良好。
-
心跳保活 :为维持 MQTT 长连接,需在 STM32 代码中定时发送
PINGREQ报文。 -
数据格式 :建议使用 JSON 格式传输指令,STM32 端可使用
cJSON库进行解析,确保格式的规范性。 -
QoS 等级:对于 LED 控制这类指令,建议使用 QoS 1(至少送达一次),以确保指令不会丢失。
按照这个架构,你可以很容易地复刻出截图中的远程控制台。如果你在具体的代码实现或配置中遇到问题,可以告诉我,我再帮你分析。
课程地址
物联网https://edu.csdn.net/course/detail/40887课程 物联网https://edu.csdn.net/course/detail/40887
代码下载https://download.csdn.net/download/suny8/93681318?spm=1001.2014.3001.5501