Home Assistant(HA)与传统嵌入式实验仪(普中玄武F103)对接的最简通信方案(一)
🧩 一、目标功能
HA ←→ 普中玄武F103 开发板,实现:
- 📊 采集温湿度(上传到HA)
- 💡 控制开关灯
- ⚙️ 控制电机(如正反转、启停)
🧠 二、关键原则
Home Assistant 本质是“家庭物联网中枢”,它不直接操作硬件,而通过网络协议(MQTT、Modbus、HTTP、ESPHome等)与设备通信。
F103 属于裸机 / RTOS 微控制器,不带网络栈或操作系统,因此要加个通信桥接层。
🚦 三、几种可行通信方式对比
| 通信方式 | 说明 | 优点 | 缺点 | 推荐程度 |
|---|---|---|---|---|
| ① 串口→MQTT桥接 | 用 USB 串口线把 F103 连到树莓派/主机,由一个小程序(Python/Node)转发到 MQTT Broker(Mosquitto) | 最容易实现;F103 无需改太多代码 | 要在主机上运行桥接程序 | ✅✅✅ 推荐(最简单稳定) |
| ② F103 搭配 ESP8266/ESP32 模块,通过 MQTT 通讯 | MCU 通过 UART 向 ESP8266 发命令,由 ESP8266 连接 Wi-Fi 与 HA 通讯 | 无需主机桥接 | 稍复杂,要写 ESP8266 固件 | ✅✅ 推荐 |
| ③ Modbus RTU / TCP | F103 当 Modbus 从站,HA 当主站 | HA 原生支持 Modbus | 要自己实现 Modbus 协议栈 | ✅ 推荐(工业风格) |
| ④ 直接HTTP POST / REST API | F103(带ESP8266)直接发HTTP到HA | 简单直观 | HA要开放API Token;延迟略高 | ✅ 一般 |
| ⑤ ESPHome | F103 替换成 ESP32/ESP8266 | 原生接入,配置超简单 | 不适用于玄武F103 | ❌ 不推荐 |
🏆 四、我采用的方案:串口→MQTT桥接(最简单稳定)
🧩 硬件连接
[普中玄武F103开发板] --USB线--> [运行HA的主机/树莓派]
🧩 软件结构
F103 ─(UART)─> Python程序 ─(MQTT)─> HA
↑
Mosquitto Broker
🧰 五、实现
方便测试 先搞个虚拟端口:

可以直接使用的工具:
| 工具名 | 开发语言 | 优点 | 安装难度 | 备注 |
|---|---|---|---|---|
| ser2net + Node-RED | C / NodeJS | 工业级稳定,Home Assistant 官方推荐 | ⭐⭐ | 通用、可靠 |
| Serial2MQTT | NodeJS | 开箱即用,一条命令安装 | ⭐ | ⭐⭐⭐推荐 |
| mqtt-serial-bridge (Python) | Python | 简洁轻量,代码清晰 | ⭐⭐ | 教学场景很合适 |
| ncd-red-serial-mqtt | Node-RED 模块 | 图形化配置,无需写代码 | ⭐⭐ | 实训用很方便 |
| 自写Python脚本 | Python | 灵活、可加逻辑 | ⭐⭐⭐ | 适合教学、实验室 |
名词解释:
| 区块 | 含义 |
|---|---|
"mqtt" |
MQTT 服务器地址(HA 内建或外部 Mosquitto) |
"serial" |
串口参数 |
"publish" |
串口 → MQTT(上行) |
"subscribe" |
MQTT → 串口(下行) |
"template" |
可用 Mustache 模板,如 "LIGHT_{{payload}}\n" 会变成 "LIGHT_ON" |
例子:
上行(发到串口)
printf("{\"temperature\":%.2f,\"humidity\":%.2f}\n", temp, hum);
**```
下行(解析控制)**
if (strncmp(rxbuf, "LIGHT_ON", 8) == 0) {
// 打开灯
} else if (strncmp(rxbuf, "LIGHT_OFF", 9) == 0) {
// 关灯
} else if (strncmp(rxbuf, "MOTOR_ON", 8) == 0) {
// 启动电机
} else if (strncmp(rxbuf, "MOTOR_OFF", 9) == 0) {
// 停止电机
}
// F103侧(C代码)
//发送数据格式(建议JSON):
```c
printf("{\"temperature\":25.3,\"humidity\":60.1}\r\n");
接收控制命令:
if(strstr(rxbuf, "LIGHT_ON")) {
// 点亮LED
}
if(strstr(rxbuf, "MOTOR_START")) {
// 启动电机
}
运行:
┌────────────┐ UART(JSON) ┌────────────────┐ MQTT ┌────────────────────────┐
│ F103 Board │ ─────────────────→ │ Serial2MQTT │ ─────────────→ │ Home Assistant (HA) │
│ (sensor) │ │ bridge tool │ │ sensor dashboard │
│ │ ←────────────────── │ bidirectional │ ←───────────── │ light/motor control │
└────────────┘ UART(cmds) └────────────────┘ └────────────────────────┘
import serial
import json
import paho.mqtt.client as mqtt
ser = serial.Serial("COM5", 115200, timeout=1) # 修改为实际串口号
mqttc = mqtt.Client()
mqttc.connect("localhost", 1883)
topic_in = "xw103/home/sensor_data"
topic_light = "xw103/home/light/set"
topic_motor = "xw103/home/motor/set"
def on_message(client, userdata, msg):
topic = msg.topic
payload = msg.payload.decode()
cmd = ""
if topic == topic_light:
cmd = "LIGHT_ON" if payload == "ON" else "LIGHT_OFF"
elif topic == topic_motor:
cmd = "MOTOR_ON" if payload == "ON" else "MOTOR_OFF"
if cmd:
ser.write((cmd + "\n").encode())
mqttc.subscribe(topic_light)
mqttc.subscribe(topic_motor)
mqttc.on_message = on_message
mqttc.loop_start()
while True:
line = ser.readline().decode().strip()
if not line:
continue
try:
obj = json.loads(line)
mqttc.publish(topic_in, json.dumps(obj))
print("Serial → MQTT:", obj)
except:
print("无效行:", line)
运行 测试:
以下是基于你提供代码的完整运行实例,包含环境准备、运行步骤和预期效果:
确保已安装所需Python库:
pip install pyserial paho-mqtt
确保本地MQTT服务器(如Mosquitto)已启动,默认端口1883。
启动命令(以Mosquitto为例):
mosquitto -v # verbose模式,可查看消息日志
确保设备已连接到COM5(或修改代码中的串口号为实际端口),波特率115200。
将代码保存为serial2mqtt.py,确认串口号和MQTT主题正确:
# 代码中的关键配置(已确认)
ser = serial.Serial("COM5", 115200, timeout=1) # 串口配置
mqttc.connect("localhost", 1883) # MQTT服务器地址
topic_in = "xw103/home/sensor_data" # 传感器数据发送到该主题
topic_light = "xw103/home/light/set" # 灯光控制命令主题
topic_motor = "xw103/home/motor/set" # 电机控制命令主题
运行Python脚本:
python serial2mqtt.py
案例1:串口发送JSON数据(正常解析)
-
设备行为:串口发送JSON格式数据(如传感器读数):
{"temperature": 25.5, "humidity": 60.2, "light": true} -
程序输出:
Serial → MQTT: {'temperature': 25.5, 'humidity': 60.2, 'light': True} -
MQTT消息:
用MQTT客户端(如MQTTX)订阅xw103/home/sensor_data,会收到:{"temperature": 25.5, "humidity": 60.2, "light": true}
案例2:串口发送非JSON数据(无效行处理)
-
设备行为:串口发送普通文本(如调试信息):
Sensor init success ADC value: 1234 -
程序输出:
无效行: Sensor init success 无效行: ADC value: 1234
案例3:MQTT发送控制命令(转发到串口)
-
操作:用MQTT客户端向
xw103/home/light/set发送消息ON。 -
程序行为:
接收到MQTT消息后,通过串口发送命令LIGHT_ON\n。 -
设备行为:
串口收到LIGHT_ON命令,执行开灯操作(取决于设备固件逻辑)。 -
类似测试:
向xw103/home/motor/set发送OFF,程序会通过串口发送MOTOR_OFF\n。

🔍 六、运行逻辑
- F103 定时输出温湿度
- Python脚本读串口 → 发布 MQTT → HA显示
- HA面板控制开关 → 发MQTT命令 → Python转发串口 → F103执行
⚡ 七、拓展方向
- 可加 CRC 校验,防止串口误码;
- 使用 JetLinks / EMQX 替代 Mosquitto 可实现多设备接入;
- 若后续升级为网络 MCU(如ESP32),可直接跑 MQTT 免桥接。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)