🧩 一、目标功能

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

在这里插入图片描述


🔍 六、运行逻辑

  1. F103 定时输出温湿度
  2. Python脚本读串口 → 发布 MQTT → HA显示
  3. HA面板控制开关 → 发MQTT命令 → Python转发串口 → F103执行

⚡ 七、拓展方向

  • 可加 CRC 校验,防止串口误码;
  • 使用 JetLinks / EMQX 替代 Mosquitto 可实现多设备接入;
  • 若后续升级为网络 MCU(如ESP32),可直接跑 MQTT 免桥接。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐