侧边栏壁纸
  • 累计撰写 33 篇文章
  • 累计收到 2 条评论

用Python接收ESP32 MQTT数据的常见问题排查

2026-9-19 / 0 评论 / 150 阅读

用Python接收ESP32 MQTT数据的常见问题排查

上周在创客交流群蹲了一晚上,见着三个刚玩物联网的朋友卡在用Python读ESP32上传的MQTT数据上,报错都不带重样的,把问得最多的几个问题整理出来,省得大家挨个搜旧教程踩坑。

大家问得最集中的三个问题是:

  1. 明明用MQTT.fx客户端能正常连上MQTT服务器,换成Python脚本就一直报连接超时
  2. 脚本打印了连接成功,但等很久都收不到ESP32发上来的消息
  3. 偶尔能蹦出来一两条消息,但是内容全是乱码,根本读不出来传感器数值

脚本连不上服务器的排查步骤

说白了这个问题八成是paho-mqtt版本闹的,现在直接pip安装默认拉的是2.x版本,和网上1.x版本的老教程写法不兼容,剩下两成是端口填错、开了系统代理截了流量。排查按这个顺序走就行:

  • 先在终端跑命令确认安装的版本:
    pip show paho-mqtt
    如果版本在2.0.0以上,初始化客户端的时候必须显式指定回调API版本,不然连接逻辑会出莫名问题,正确初始化写法:
    import paho.mqtt.client as mqtt
    # 2.x版本必填VERSION2参数,缺省容易出现连接异常
    client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="py_test_client_001")
    # 注意端口别混,TCP默认1883,WebSocket端口一般是8083
    client.connect("你的MQTT服务器地址", 1883, keepalive=60)
  • 跑脚本的时候暂时关一下系统全局代理,不少代理规则默认会拦截1883端口的TCP流量,表现就是第三方客户端能连,Python脚本连不上。

连接成功但收不到消息怎么查

这个问题我自己刚接触的时候也卡过,大部分时候是订阅代码写的位置不对,或者主题名匹配不上。

  • 别把订阅主题的代码写在connect()方法后面,一定要放在on_connect连接成功的回调函数里,这样断线重连之后也会自动重新订阅,不会出现刚连上还没来得及订阅就错过消息的情况,参考写法:
    def on_connect(client, userdata, flags, reason_code, properties):
        print(f"连接返回码:{reason_code}")
        # 连接成功第一时间订阅主题
        client.subscribe("esp32/sensor/data")
    
    def on_message(client, userdata, msg):
        print(f"收到{msg.topic}的消息")
    
    client.on_connect = on_connect
    client.on_message = on_message
    # 启动后台监听循环
    client.loop_start()
  • 先做个对照测试:用MQTT.fx往"test/debug"主题发个简单字符串,Python脚本也订阅这个主题,如果能收到,就逐字符核对ESP32端写的主题名,大小写、斜杠、无意中多打的空格都会导致匹配不上,别嫌麻烦。

收到乱码的处理方法

这个基本都是编码没对上的问题,别一上来就硬转字符串。

  • 先在on_message回调里打印msg.payload的原始字节内容,看看是不是有多余的BOM头,或者根本不是UTF-8编码的文本,正常文本转码的时候加个错误忽略参数就行:
    payload_text = msg.payload.decode('utf-8', errors='ignore')
  • 如果ESP32端发的是二进制格式的传感器原始值,就别硬转字符串,用struct模块对应字节长度解析成数值就行。
小提示:要是用的是公共免费MQTT服务器,自己的主题前面最好加个唯一标识,比如你的昵称缩写,不然很容易收到其他陌生人发的无关消息,调试的时候能少走不少弯路。

反正我当初因为主题名多写了一个末尾的斜杠,硬生生卡了快一节课的时间,说出来也不丢啥人。

评论一下?

OωO
取消