esp32c3开发板通过micropython的mqtt库连MQTT物联网消息服务器

MQTT介绍

MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息协议,旨在设备之间进行通信,尤其是在网络条件较差的情况下。MQTT v3.1.1 和 MQTT v5 是该协议的两个主要版本。

MQTT v3.1.1:

  • 优点:
    • 成熟和广泛支持:作为较早的版本,v3.1.1 得到了广泛的实现和支持,包括各种客户端库和服务器(代理)。
    • 稳定性:由于长时间的使用,v3.1.1 版本的稳定性和可靠性得到了验证。
    • 资源消耗低:设计上考虑了低带宽和低功耗设备,因此非常适合物联网(IoT)应用。
  • 缺点:
    • 功能限制:与 v5 相比,v3.1.1 缺少一些高级功能,如消息的精确一次性传递(Exactly-Once Delivery)和用户属性(User Properties)。
    • 可扩展性:v3.1.1 的一些限制可能使得在某些高级场景下的使用受到限制。

MQTT v5:

  • 优点:
    • 增强的功能:v5 引入了许多新特性,包括消息的精确一次性传递、用户属性、共享订阅(Shared Subscriptions)、动态消息过滤(Dynamic Message Filters)等,这些特性提高了协议的灵活性和可扩展性。
    • 更好的错误处理:v5 提供了更详细的错误代码,有助于客户端更好地理解和处理错误情况。
    • 改进的会话恢复:v5 改进了会话恢复机制,使得客户端可以在断开连接后更快地恢复状态。
  • 缺点:
    • 兼容性问题:由于是较新的版本,v5 的支持可能不如 v3.1.1 广泛,这可能导致与旧系统或客户端的不兼容问题。
    • 实现复杂性:新特性的引入可能增加了实现的复杂性,对于资源受限的设备来说,这可能是一个挑战。

总的来说,MQTT v3.1.1 由于其成熟度和广泛支持,仍然是许多应用的首选。而 MQTT v5 提供了更多的高级功能和更好的错误处理,适合需要这些特性的新应用。选择哪个版本取决于具体的应用需求、资源限制以及对新特性的需求。随着时间的推移,v5 的支持和采用可能会增加,从而减少兼容性问题。

mqtt服务器软件Mosquitto

当前比较流行的mqtt服务器是:Mosquitto、EMQTT、HiveMQ等,经过短暂的了解,最终决定使用Mosquitto。

FreeBSD下安装

pkg install mosquitto

安装好后提示:

Message from mosquitto-2.0.18:

The mosquitto MQTT Python driver is now provided by net/py-paho-mqtt

FreeBSD下启动服务,若没有写入rc.conf文件,则启动时需要加上onestart

sudo service mosquitto start
sudo service mosquitto onestart

Ubuntu下安装

安装服务器

sudo apt install mosquitto

安装客户端

sudo apt install mosquitto-clients

启动并配置服务

以Ubuntu下为例。

启动服务

可以使用service启动服务:

​sudo service mosquitto start

当然一开始不知道,直接使用运行mosquitto命令启动了服务: 

mosquitto

1731855204: Warning: Unable to drop privileges to 'mosquitto' because this user does not exist. Trying 'nobody' instead.

1731855204: mosquitto version 2.0.18 starting

1731855204: Using default config.

1731855204: Starting in local only mode. Connections will only be possible from clients running on this machine.

1731855204: Create a configuration file which defines a listener to allow remote access.

1731855204: For more details see https://mosquitto.org/documentation/authentication-methods/

1731855204: Opening ipv4 listen socket on port 1883.

1731855204: Opening ipv6 listen socket on port 1883.

1731855204: mosquitto version 2.0.18 running

后来才知道可以用service启动和停止服务

后来发现端口只绑定了本地ip,要绑定0.0.0.0,则需要修改配置。

客户端测试:

首先在服务器本机测试

执行mosquitto_sub客户端侦听服务:

mosquitto_sub -t "mytopic"

执行mosquitto_pub发布信息

另一个终端执行:

mosquitto_pub -t "mytopic" -m "Hello, MQTT!!"
1731855866: New connection from 127.0.0.1:29987 on port 1883.
1731855866: New client connected from 127.0.0.1:29987 as auto-E0721C4C-5B09-EF6C-E3B3-892DBEDC9C05 (p2, c1, k60).
1731855866: Client auto-E0721C4C-5B09-EF6C-E3B3-892DBEDC9C05 disconnected.

 就会发现刚才的信息Hello, MQTT!!被侦听端收到了:

mosquitto_sub -t "mytopic"
Hello, MQTT!!

发送消息的详细命令:

mosquitto_pub -t "mytopic" -m "Hello, MQTTexitlast1" -h "192.168.0.13"

设置了用户验证后,就需要带用户名和口令参数,比如

mosquitto_pub -t "mytopic" -m "Hello, MQTT!!" -h 192.168.0.13 -u ral -P ral

修改mosquitto配置

添加用户

在/etc/mosquitto目录下修改配置文件,修改mosquitto.conf文件,加入这样两句:

allow_anonymous false
password_file /etc/mosquitto/passwd

执行mosquitto_passwd创建用户ral并写入/etc/mosquitto/passwd文件:

sudo mosquitto_passwd -c /etc/mosquitto/passwd ral
Password: 
Reenter password: 

这样发送和接收信息都需要用户验证。

修改绑定服务到0.0.0.0 

在/etc/mosquitto/conf.d目录里创建bindip.conf文件,加入这一句:

bind_address 0.0.0.0

这样服务就能监听0.0.0.0 ,也就是其它非本机也可以连它。

 如果原来ufw防火墙没有放开,那么需要放开1883端口:

sudo ufw allow 1883

 这时候再测试一下信息:

mosquitto_pub -t 'mytopic' -m 'ehllo' -u 'ral' -P 'ral'

客户端应该能接收到信息:

mosquitto_sub -t "mytopic"
Hello, MQTT!!

重启mosquitto服务

每次修改mosquitto配置后,都要重启服务

sudo service mosquitto restart

带用户验证的测试

消息接收:

# 带上用户验证
mosquitto_sub -t "mytopic" -u 'ral' -P 'ral'
# 或是带上地址
mosquitto_sub -t "mytopic" -u 'ral' -P 'ral'  -h '192.168.0.13'

消息发送:

# 带用户验证的消息发送
mosquitto_pub -t 'mytopic' -m 'hello world' -u 'ral' -P 'ral'
# 带上服务器ip地址
mosquitto_pub -t 'mytopic' -m 'hello world2' -u 'ral' -P 'ral' -h '192.168.0.13'

接收端接收到信息:

mosquitto_sub -t "mytopic" -u 'ral' -P 'ral'  -h '192.168.0.13'
hello world

证明配置设置的正确,服务器一切正常! 

esp32c3开发板配置

esp32c3开发板烧录micropython 交互环境,参见:esp32c3安装micropython环境-CSDN博客

烧录好固件,启动开发板,进入micropython交互环境。参见:esp32-c3开发板开箱第一步:连上usb口看log信息-CSDN博客

开发板启动wifi连上网

交互界面里执行下面代码连wifi,注意wifi的名字和密码需要根据实际情况修改:

import network
import time
nic = network.WLAN(network.STA_IF)
nic.active(True)
# nic.scan()
if not nic.isconnected():nic.connect("wifi名字", "wifi密码")print("Waiting for connection...")while not nic.isconnected():time.sleep(1)print(nic.ipconfig("addr4"))

 如果能输出网络信息,那么就证明连上了wifi

>>> print(nic.ipconfig("addr4"))
('192.168.0.104', '255.255.255.0')

开发板接收mqtt消息代码

 继续执行esp32c3开发板里的micropython代码:

from umqtt.simple import MQTTClient# 定义 MQTT 代理的地址和端口
SERVER = "192.168.0.13"
PORT = 1883# 定义客户端 ID、用户名和密码
CLIENT_ID = "my_client_id"
USERNAME = "ral"
PASSWORD = "ral"# 定义要订阅的主题
TOPIC = b"mytopic"# 创建 MQTTClient 实例,并传递用户名和密码参数
client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD)# 连接到 MQTT 代理
client.connect()# 订阅主题
client.subscribe(TOPIC)# 定义消息回调函数
def sub_cb(topic, msg):print("Received message: ", msg)# 设置消息回调函数
client.set_callback(sub_cb)# 进入消息循环
while True:client.wait_msg()

 中文会占用输入缓冲区大小,有点干扰输入,所以可以黏贴下面去掉中文注释的代码:

from umqtt.simple import MQTTClientSERVER = "192.168.0.13"
PORT = 1883CLIENT_ID = "my_client_id"
USERNAME = "ral"
PASSWORD = "ral"TOPIC = b"mytopic"client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD)client.connect()def sub_cb(topic, msg):print("Received message: ", msg)client.set_callback(sub_cb)client.subscribe(TOPIC)while True:client.wait_msg()

不要一次黏贴一大段,可以2-3句黏贴,比如像这句:client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD) 比较长,就单独黏贴。

开发板运行后,用一个客户端发送消息 

# 本机
mosquitto_pub -t 'mytopic' -m 'hello world' -u 'ral' -P 'ral'
# 非本机
mosquitto_pub -t 'mytopic' -m 'hello world2' -u 'ral' -P 'ral' -h '192.168.0.13'

这时候开发板交互界面里就能接收到发送的信息了!

>>> while True:
...     client.wait_msg()
... 
Received message:  b'hello'
48

这样我们这次实践就完成了!

总结

总体是一次非常愉快的esp32c3开发板与mqtt服务器通信的实践操作。但是由于是第一次使用mosquitto,对它的配置不熟悉,同时也是第一次使用micropython里的mqtt模块(umqtt)进行通信,对它也不熟悉,所以这次实践中箭走了很多弯路,碰到很多问题,幸运的是都解决了。

mqtt服务器,用了半天时间选型为mosquitto,大约这就是眼缘吧,毕竟它是eclicps旗下的,而且FreeBSD还有它的pkg包。安装mosquitto后,需要修改其配置,比如添加用户和密码到指定的文件,修改绑定ip到0.0.0.0,在Ubuntu服务器ufw防火墙中放开1883端口。

esp32c3开发板这块,首先需要烧micropython交互环境的固件,然后usb串口登录到micropython的交互界面,输入python代码。先要配置好WiFi启动tcp/ip网络,然后就是调用umqtt模块进行侦听mqtt消息。micropython的缓冲区较小,不能像普通python里面那样一下子可以黏贴太长的代码段,这也需要注意。

调试

esp32c3上mqtt连接失败

其实这是一个大问题,后来是分解成几个小问题一一解决的。

>>> mqtt_client = connect_mqtt()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "<stdin>", line 3, in connect_mqtt

  File "umqtt/simple.py", line 66, in connect

OSError: [Errno 104] ECONNRESET

想起来了,原来是mqtt服务器跨了网段,为了简化测试,后来就用了linux客户端mosquitto_pub和mosquitto_sub -t "mytopic" 先进行测试。(其实esp32的网络模块是可以联网、跨网段通信的)

在同一网段开服务器,还是不行

原来是ufw防火墙没有放开,放开1883端口

sudo ufw allow 1883

发现没有绑定0.0.0.0,修改配置文件/etc/mosquitto/conf.d/bindip.conf,加入这句:

bind_address 0.0.0.0

然后重启服务

sudo service mosquitto restart

用客户端mosquitto_pub再测试有如下报错: 

发送信息报错Connection Refused: not authorised.

mosquitto_pub -t "mytopic" -m "Hello, MQTTexitlast1" -h "192.168.0.13"

Connection error: Connection Refused: not authorised.

添加用户:

sudo mosquitto_passwd -c /etc/mosquitto/passwd ral
Password: 
Reenter password: 

在/etc/mosquitto目录下的mosquitto.conf文件中加入信息:

allow_anonymous false
password_file /etc/mosquitto/passwd

重启服务后测试: 

mosquitto_pub -t "mytopic" -m "Hello, MQTT!!" -h 192.168.0.13 -u ral -P ral

终于不报用户验证错了,现在报错:

esp32连mosquitto报错 Subscribe callback is not set

>>> client.subscribe(TOPIC)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "umqtt/simple.py", line 152, in subscribe

AssertionError: Subscribe callback is not set

是那段代码又问题,换代码:

from umqtt.simple import MQTTClientSERVER = "mqtt.eclipse.org"
PORT = 1883CLIENT_ID = "my_client_id"
USERNAME = "my_username"
PASSWORD = "my_password"TOPIC = b"test/topic"SERVER = "192.168.0.13"
PORT = 1883CLIENT_ID = "my_client_id"
USERNAME = "ral"
PASSWORD = "ral"TOPIC = b"mytopic"client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD)client.connect()def sub_cb(topic, msg):print("Received message: ", msg)client.set_callback(sub_cb)client.subscribe(TOPIC)while True:client.wait_msg()

这个代码就ok了!

esp32 micropython里黏贴python代码有时候会出错

发现黏贴代码到后面就乱了,估计是黏贴长度超限导致的,减少黏贴长度,问题解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/61169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx配置端口重定向及协议重定向

需求来源 我在搭建博客初期是将博客部署在了家里的软路由上&#xff0c;由于家庭宽带的80以及443端口被宽带服务商屏蔽了&#xff0c;所以最开始是通过8443端口对外提供服务&#xff0c;地址为&#xff1a;https://blog.chengpei.top:8443&#xff0c;后来上了阿里云并且经过备…

stm32启动过程解析startup启动文件

1.STM32的启动过程模式 1.1 根据boot引脚决定三种启动模式 复位后&#xff0c;在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚&#xff0c;而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样&#xff0c;相应 GPIO 引脚即进入空闲状态&#xff0c;可用于…

SQL字段来源表的解析

测试例子&#xff1a; SELECT e.NAME, d.DEPT_NAME,d.DEPT_ID,EMP_ID,100EMP_ID100 FROM EMP e JOIN DEPT d ON e.DEPT_ID d.DEPT_ID WHERE e.EMP_ID IN (SELECT EMP_ID FROM EMP WHERE DEPT_ID 10) 代码示例&#xff1a; package com.test; import org.apache.calcite.jd…

【第三课】Rust变量与数据类型(二)

目录 前言 Vector HashMap 其他 前言 上一课介绍了rust的变量和常见的数据类型&#xff0c;走马观花的看了一下rust常见的变量和数据类型&#xff0c;这些都是rust的基本语法&#xff0c;整理出来只是起一个引子的效果&#xff0c;基本语法多练习才可以熟练。这一课继续介绍…

操作iframe dom元素;监听子节点的变化

1、 不能跨域&#xff0c;如果跨域请配置代理或nginx,必须同源 /restcloud: {target: http://10.1.17.210:8080,changeOrigin: true,pathRewrite: {^/restcloud: /restcloud, // 这里可以省略&#xff0c;因为路径是一样的}} 或者 server {listen 8090;server_name l…

【AI日记】24.11.17 看 GraphRAG 论文,了解月之暗面

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 核心工作 内容&#xff1a;看 GraphRAG 论文时间&#xff1a;4 小时评估&#xff1a;不错&#xff0c;继续 非核心工作 内容&#xff1a;了解国内大模型方向&#xff0c;重点了解了创业独角兽-月之暗面&…

数据结构查找-哈希表(开发地址法+线性探测法)+(创建+查找+删除代码)+(C语言代码)

#include<stdlib.h> #include<stdio.h> #include<stdbool.h> #define NULLKEY -1//单元为空 #define DELKEY -2//单元内容被删除 #define M 20 typedef struct {int key;//关键字int count;//统计哈希冲突探测次数 }HashTable; //插入到哈希表 void InsertHT…

vue el-date-picker 日期选择器禁用失效问题

当value-format"yyyy-MM-dd"的格式不要改为"yyyyMMdd"&#xff0c;否则会导致日期选择器禁用失效问题&#xff0c;因为该组件默认的格式就是yyyy-MM-dd。 <el-col v-for"(item, index) in formData" :key"index" ><el-date-…

〔 MySQL 〕数据类型

目录 1.数据类型分类 2 数值类型 2.1 tinyint类型 2.2 bit类型 2.3 小数类型 2.3.1 float 2.3.2 decimal 3 字符串类型 3.1 char 3.2 varchar 3.3 char和varchar比较 4 日期和时间类型 5 enum和set mysql表中建立属性列&#xff1a; 列名称&#xff0c;类型在后 n…

数据库审计工具--Yearning 3.1.9普民的使用指南

1 页面登录 登录地址:18000 &#xff08;不要勾选LDAP&#xff09; 2 修改用户密码 3 DML/DDL工单申请及审批 工单申请 根据需要选择【DML/DDL/查询】中的一种进行工单申请 填写工单信息提交SQL检测报错修改sql语句重新进行SQL检测&#xff0c;如检测失败可以进行SQL美化后…

Flutter网络通信-封装Dio

前言 dio 是一个强大的 Dart HTTP 请求库&#xff0c;支持全局配置、Restful API、FormData、拦截器、 请求取消、Cookie 管理、文件上传/下载、超时以及自定义适配器等。 Dio的pub地址为&#xff1a;dio | Dart package 封装要求 能够使用get、post、put、patch、delete、…

tcp 超时计时器

在 TCP&#xff08;传输控制协议&#xff09;中有以下四种重要的计时器&#xff1a; 重传计时器&#xff08;Retransmission Timer&#xff09; 作用&#xff1a;用于处理数据包丢失的情况。当发送方发送一个数据段后&#xff0c;就会启动重传计时器。如果在计时器超时之前没有…

[前端面试]HTML AND CSS

HTML html语义化标签的理解 是什么: 在布局页面的时候&#xff0c;根据内容的结构与含义&#xff0c;选择合适的带语义的html标签 如header&#xff0c;footer&#xff0c;nav&#xff0c;article&#xff0c;main&#xff0c;aside&#xff0c;h标签等 好处&#xff1a; 增…

前端(4)——demo分享

这两天需要用HTML、CSS和js简单组合一个html网页用于展示一些数据内容&#xff0c;这是我简单组合别人的一些文件形成的简单demo&#xff0c;大家也可以拿过去使用。 登录界面&#xff1a; 场景选择界面&#xff0c;有五个场景&#xff0c;每个场景中都需要展示一些特定的数据…

【企业级分布式系统】 Kafka集群

文章目录 KafkaKafka 概述使用消息队列的好处 Kafka 的特性Kafka 系统架构Kafka 的应用场景Kafka 的优缺点 Kafka 集群部署下载安装包安装 KafkaKafka 命令行操作Kafka 架构深入 FilebeatKafkaELK 部署指南~部署 ZookeeperKafka 集群部署 Filebeat部署 ELK&#xff08;Logstash…

高级java每日一道面试题-2024年11月07日-Redis篇-Redis有哪些功能?

如果有遗漏,评论区告诉我进行补充 面试官: Redis有哪些功能? 我回答: Redis 是一个开源的、基于键值对的 NoSQL 数据库&#xff0c;以其高性能、丰富的数据结构和多种功能而闻名。在高级 Java 面试中&#xff0c;了解 Redis 的核心功能和高级特性是非常重要的。以下是 Redi…

14天Java基础学习——第9天:异常处理机制

第9天 Java基础学习&#xff1a;异常处理机制 学习目标 在本日的学习中&#xff0c;我们将深入研究Java中的异常处理机制&#xff0c;包括以下几个方面&#xff1a; 异常与错误分类try-catch-finally语句throw与throws关键字自定义异常 一、异常与错误分类 Java中的异常主…

Java-空链处理

什么是 null 在 Java 中&#xff0c;null 是一个非常常见的关键字&#xff0c;用于表示“没有值”或“空”。然而&#xff0c;对于初学者来说&#xff0c;null 的本质可能会感到有些困惑。在本文中&#xff0c;我们将详细探讨 null 在 Java 中的含义和使用。 在 Java 中&…

PyTorch使用教程-深度学习框架

PyTorch使用教程-深度学习框架 1. PyTorch简介 1.1-什么是PyTorch ​ PyTorch是一个广泛使用的开源机器学习框架&#xff0c;特别适合深度学习的应用。它以其动态计算图而闻名&#xff0c;允许在运行时修改模型&#xff0c;使得实验和调试更加灵活。PyTorch提供了强大的GPU加…

网络爬虫 Python 第二课

BeautifulSoup 高级用法&#xff1a; 标签查找与筛选&#xff1a;除了简单地通过标签名查找&#xff08;如 soup.find(div) 查找第一个 div 标签&#xff09;&#xff0c;还可以利用属性来更精准地查找。例如&#xff0c;如果要查找所有 class 属性为 article 的 div 标签&…