当前位置: 首页 > news >正文

CAT1+mqtt

文章目录

      • MQTT知识点
        • mqtt数据
          • 固定报头
          • 可变报头(连接请求)
          • 有效载荷
      • 阿里云MQTT测试
        • 订阅Topic
        • 下发数据给MQTT.fx
        • MQTT.fx 发布消息给服务器
      • 下载mqtt(C-嵌入式版)
      • 我的W5500项目路径
      • 使用Cat1连接阿里云平台
        • AT指令串口连接
          • 1. 开机联网
          • 2. 激活内置SIM卡(贴片卡)
          • 3. 我这里使用连接的是阿里云的物联网平台
          • 4. (非必要)关闭MQTT连接
          • 5. 总结:AT全部指令(简便式)
        • STM32单片机连接Cat1实现用MQTT连接阿里云

MQTT知识点

请添加图片描述

MQTT协议是通过TCP/IP协议做的

  • 连接与响应(主要, 带的数据会比较多复杂些)
  • 订阅主题
  • 发布与响应
  • PING(心跳)
  • 关闭
mqtt数据

在这里插入图片描述

  • 因为MQTT协议是通过TCP/IP协议做的所以第一部分是TCP的报头
  • 固定报头限制字节,但没限制长度。不同的消息类型会传不同的信息; 会影响后面的可变报头,有效载荷
  • 可变报头(可以像PingPong一样没有可变报头)
固定报头

在这里插入图片描述

  • 报文类型(可以组成1~15bit)
    在这里插入图片描述
    不同的消息类型会传不同的信息; 会影响后面的可变报头,有效载荷

  • 3bit-重复: 只有在QOS>1时,才有可能用到。当第一次发布消息时,
    置0,如果是重复发布的要置1。(标志位;发生信息后没有响应,就再发一次后此时QOS从0到1)

  • [1~2bit]:

QOS=0时,“最多一次”,尽操作
环境所能提供的最大努力分发消息。消息
可能会丢失。例如,这个等级可用于环境
传感器数据,单次的数据丢失没关系,因
为不久之后会再次发送,
Q0S=1时,“至少一次”
保证消
息可以到达,但是可能会重复。
Q0S=2时,”仅一次”,保证消息
只到达一次。例如,这个等级可用在一个
计费系统中,这里如果消息重复或丢失会
导致不正确的收费,

  • [0bit] :flag

当置1时,服务端将(发布者的信息)保留此条应用消息,分发给未来的订阅者。如果载荷为空(消息是空的,当前flag数据还置为1),相当于清空消息。

在这里插入图片描述

固定报头长度最高5个字节

[0~6bit] : 最大值是128,若超过128就用最后一位(7bit)来表示: 最后一位是0的话没有第三字节,最后一位是1就有第三字节(第三字节与第二字节一致最大是128;第5个字节最后一位必须是0,若1不是前面的数据全部就没有了)

可变报头(连接请求)

在这里插入图片描述

  • 协议名(站6个字节,UTF-8格式),前面是字符串长度(高(MSB)低(LSB)位)
  • 协议级别: 版本。图中显示的是4对应3.1.1版本,这个版本就没有(属性5.0)
  • 连接标志: 尤其是初次连接(用户名,密码不可少)

遗嘱: 订阅者订阅的时候会有标志位信息,那遗嘱就是我关闭的时候也可以发送一段信息(连接后关闭的时候这个遗嘱就可以发布给其他订阅者了,或者取消订阅)

  • 新开始(新连接): 最开始已经连接过了但是中断了,那再连接时(遗嘱标志)就不需要置1了(最开始的连接需要置1)
  • 保留位: 对于遗嘱保留什么,这个保留没什么动作
  • 保持连接: 就算是心跳。心跳也是有时间的,图中设置成60秒
有效载荷

在这里插入图片描述

  • 遗嘱属性(不是mqtt5.0的是没有的)
  • 遗嘱主题(不是mqtt5.0的是没有的)
  • 遗嘱载荷(不是mqtt5.0的是没有的)

现在万物智联(物体要有智慧的话就需要以上操作)

  • 客户端标识符(必须有),也是utf-8格式(高()MSB)低(LSB)位)若长度是18那第19位就到用户名那了。18个就是18个字符串后不用像写\0或者\n这样

阿里云MQTT测试

参考文章
HMACSHA1 在线加密工具

迈向物联网第一步——MQTT理论知识详解

mqtt.fx-windows下载
至于密钥(适用于MQTT.fx(validUntil: 2040-10-18 03:13:04))

-----BEGIN CERTIFICATE-----
MIIG7jCCBNagAwIBAgIJAOiLlBQu/GDHMA0GCSqGSIb3DQEBDQUAMIGpMQswCQYD
VQQGEwJERTEQMA4GA1UECAwHQmF2YXJpYTERMA8GA1UEBwwIRXJsYW5nZW4xFzAV
BgNVBAoMDlNvZnRibGFkZSBHbWJIMRkwFwYDVQQLDBB3d3cuc29mdGJsYWRlLmRl
MRwwGgYDVQQDDBNTb2Z0YmxhZGUgUm9vdCBDQSAxMSMwIQYJKoZIhvcNAQkBFhRj
b250YWN0QHNvZnRibGFkZS5kZTAeFw0yMDEwMjIxOTEzMDRaFw00MDEwMTcxOTEz
MDRaMIGpMQswCQYDVQQGEwJERTEQMA4GA1UECAwHQmF2YXJpYTERMA8GA1UEBwwI
RXJsYW5nZW4xFzAVBgNVBAoMDlNvZnRibGFkZSBHbWJIMRkwFwYDVQQLDBB3d3cu
c29mdGJsYWRlLmRlMRwwGgYDVQQDDBNTb2Z0YmxhZGUgUm9vdCBDQSAxMSMwIQYJ
KoZIhvcNAQkBFhRjb250YWN0QHNvZnRibGFkZS5kZTCCAiIwDQYJKoZIhvcNAQEB
BQADggIPADCCAgoCggIBAMw3XhycExw0i5GtFgXJoQkYv4B7abAQgSvJoGB8qm9o
0zxr0mHtYBkH7VANQb/m49CEADEVMYVGLVEeBXJ8rEg11ckS4FMxwxzj+YPpvcwS
cqe453+tWC0pFbDkNsZF4Y1ATlSR3Ab7KiQtsgfrsft46oghFE8Oadp0gmwP5O1A
z7SZKBbNadTGfqOK67T5p2gR+TMrb2L2llsStspLfxmGoOZEzytW5goKWKXphio2
vtIuUTiQqAfr7utbY8ZAEjx/srdF9BbxQUpj4zFsqSJfSu1H+l/sN6zOsVAzqTpG
wU3mgttAzlxYlI/SMbhDN817LYHP4IEmg0hgqqk1oEBA1U3y8LWLUuNt4VREscSU
bvPwYdJjApi3CpTmp+YahMk4tqXeJ0bZA0WXpAzPAnCWMHOpGG4rzC2iUJu61klb
9jmmxkOzZV2p/RMKlCGEYuVBM3h7jx8oFZ19Hea9nBarSQyPSvkYt9q3gGgvxN6L
+RvHRmbkHkHsbImKCtNJGg/8wqVmO91GqqjJSuR0IAYta4aRVoNe7UnDMhM5A+jt
smfS4IDklqZrbw/NnVJL+FRnrBfcIHSVJbTs9IFdz6ZGjvCexEu/bgDTwBwvWu4o
YIKNdXMB+UBCifuQEuPEcn4ce2nL9UJcEIGDWjOnJNHhg8efxBenn3ENZNwRBD8P
AgMBAAGjggEVMIIBETAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRO6cF4TD6P
FCYoe+kyrhV335+BODCB3gYDVR0jBIHWMIHTgBRO6cF4TD6PFCYoe+kyrhV335+B
OKGBr6SBrDCBqTELMAkGA1UEBhMCREUxEDAOBgNVBAgMB0JhdmFyaWExETAPBgNV
BAcMCEVybGFuZ2VuMRcwFQYDVQQKDA5Tb2Z0YmxhZGUgR21iSDEZMBcGA1UECwwQ
d3d3LnNvZnRibGFkZS5kZTEcMBoGA1UEAwwTU29mdGJsYWRlIFJvb3QgQ0EgMTEj
MCEGCSqGSIb3DQEJARYUY29udGFjdEBzb2Z0YmxhZGUuZGWCCQDoi5QULvxgxzAN
BgkqhkiG9w0BAQ0FAAOCAgEAda2ef3YTFI2euS2EjZXa5jgdSAvrCpPjX4HVrG0n
3Su+FjIAGam0PMX635wTqj7np9s7NKqZj7IWS7o8EhVL4RqnAHFBq+ta8PXIZQB3
xWf8qbKIBoSmdwUaJw44MeBdhc4nni5O6zho4RY00/FJddLf4kCtcBsXu6Zs8K3a
IW/frSU4I7kD91xnFZ6SQQEZH1UBAttZvK5pO1m2MFkgYqXIOWycNB3CsPqor8sT
zF296Fp4LbyhkI+9HkeoiTce7oZQGPl346FwVYw4ERuiH7C217gy5TMRK/bangxq
yDOoOXyrRbWfyfhYnmexAe8k/IFix5XzHU9yU7iWvc1Y1nj4tnqIUnas3oXK08TU
vesfK4iUXviJQdRYIWpIJ1g1bagzec2sijFVIdSG0qThBXWiQp98tojCi9Z7fm5U
Et5douMZMm17wc5ELyX2nx083b6+5xMBpEFYrES9iiefMFFD7hmHb5r8B17iOnW6
ujZi5U/9ZhpnuVvI3VGqSDQfne8p3ra814X1gOtKJPWQRU6i0/1tfo+Pxw+ATB1j
h4ZxMEGx9zGF3UAD6VATeKE6yepfwrKiXAHz3gyLeD5F7Di8IFtKs5yIpjK4/Jfp
IkolTm9gBMKDT723nlfOS7xVHHnfP5auH+Wmgmb9BlavBO/k5zcqxMA3VfWsqnIS
Ekc=
-----END CERTIFICATE-----

在这里插入图片描述

在这里插入图片描述

#此mqtt服务器在上海(华东2)
Broker Address: ProductKey.iot-as-mqtt.cn-shanghai.aliyuncs.com
#一般端口为1883
Broker Port:1883
Client ID: DeviceName|securemode=3,signmethod=hmacsha1|
User Name:DeviceName&ProductKey
#忽略空格,加密密钥是DeviceSecret值
#举例: clientIdwlan_wifi_testdeviceNamewlan_wifi_testproductKeya1mqeQuLw0k
Password: clientId DeviceName deviceName DeviceName productKey ProductKey的hmacsha1加密

在这里插入图片描述
在这里插入图片描述

订阅Topic

在这里插入图片描述
阿里云上就有1订阅1
在这里插入图片描述
在这里插入图片描述

下发数据给MQTT.fx
/sys/productKey/DeviceName/thing/service/property/set

在这里插入图片描述
在这里插入图片描述

{"method":"thing.service.property.set","id":"621799578","params":{"CurrentTemperature":30},"version":"1.0.0"}
MQTT.fx 发布消息给服务器
/sys/productKey/DeviceName/thing/event/property/post

将上一段响应复制下来

//{"method":"thing.service.property.set","id":"621799578","params":{"CurrentTemperature":30},"version":"1.0.0"}
//改动了方法、消息ID(ID可自行用户定义)、params里的值
{"method":"thing.event.property.post","id":"621799531","params":{"CurrentTemperature":35},"version":"1.0.0"}

在这里插入图片描述

Response Topic : 跟上面订阅一样,但可以不填
Correlation Data: 必填即便是1都可以
没有右侧边的mqtt.fx软件可以无视

//json案例
{"method":"thing.event.property.post","id": "82485025","version": "1.0","params": {"CurrentTemperature": 46}
}

在这里插入图片描述

咱们mqqtt能通了那就可以下一步用单片机

下载mqtt(C-嵌入式版)

前面了解了MQTT协议和使用MQTT工具去如何通讯,接下来就看怎么用单片机进行通讯了(使用的还是W5500网卡驱动芯片)

参考文章

Paho-MQTT C(嵌入式版)

git clone https://github.com/eclipse/paho.mqtt.embedded-c.git

下载不了,可以用管理员运行记事本,用记事本打开windows的C:\Windows\System32\drivers\etc文件里面添加

140.82.113.4 github.com

在这里插入图片描述
重启计算机后即可

在这里插入图片描述
在这里插入图片描述

最主要的mqtt.h文件


#ifndef __MQTT_H
#define __MQTT_H#ifdef __cplusplus
extern "C" {
#endif/* 包含必要的头文件 */
#include <stdint.h>
#include <stdbool.h>
#include "FreeRTOS.h"
#include "queue.h"/* 阿里云MQTT配置 (根据实际修改) */
#define PRODUCT_KEY      "a1xxxxxx"      // 替换为您的产品Key
#define DEVICE_NAME      "device1"       // 替换为您的设备名称
#define DEVICE_SECRET    "your_secret"   // 替换为设备密钥/* MQTT服务器配置 */
#define MQTT_SERVER      PRODUCT_KEY ".iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define MQTT_PORT        1883
#define MQTT_KEEP_ALIVE  60              // 心跳间隔(秒)/* MQTT主题定义 */
#define TOPIC_PROP_POST  "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define TOPIC_PROP_SET   "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define TOPIC_UPDATE     "/" PRODUCT_KEY "/" DEVICE_NAME "/user/update"
#define TOPIC_GET        "/" PRODUCT_KEY "/" DEVICE_NAME "/user/get"/* MQTT QoS级别 */
typedef enum {MQTT_QOS0 = 0,  // 最多一次MQTT_QOS1 = 1,  // 至少一次MQTT_QOS2 = 2   // 恰好一次
} mqtt_qos_t;/* MQTT消息结构 */
typedef struct {char topic[128];        // 主题char payload[256];      // 负载内容mqtt_qos_t qos;         // QoS级别bool retained;          // 保留标志
} mqtt_message_t;/* MQTT客户端状态 */
typedef enum {MQTT_STATE_DISCONNECTED,MQTT_STATE_CONNECTING,MQTT_STATE_CONNECTED,MQTT_STATE_DISCONNECTING,MQTT_STATE_ERROR
} mqtt_state_t;/* 函数声明 *//*** @brief 初始化MQTT客户端*/
void mqtt_client_init(void);/*** @brief 连接到MQTT服务器* @return 0成功,其他失败*/
int mqtt_connect(void);/*** @brief 断开MQTT连接*/
void mqtt_disconnect(void);/*** @brief 发布消息* @param topic 主题* @param payload 负载内容* @param qos QoS级别* @param retained 是否保留* @return 0成功,其他失败*/
int mqtt_publish(const char *topic, const char *payload, mqtt_qos_t qos, bool retained);/*** @brief 订阅主题* @param topic 主题* @param qos QoS级别* @return 0成功,其他失败*/
int mqtt_subscribe(const char *topic, mqtt_qos_t qos);/*** @brief 取消订阅* @param topic 主题* @return 0成功,其他失败*/
int mqtt_unsubscribe(const char *topic);/*** @brief 发送心跳包* @return 0成功,其他失败*/
int mqtt_ping(void);/*** @brief 获取当前状态* @return mqtt_state_t 状态值*/
mqtt_state_t mqtt_get_state(void);/*** @brief 设置MQTT回调函数* @param connect_cb 连接回调* @param message_cb 消息回调*/
void mqtt_set_callback(void (*connect_cb)(bool connected), void (*message_cb)(const char *topic, const char *payload));/*** @brief 获取发送队列(用于其他任务发送消息)* @return QueueHandle_t 消息队列句柄*/
QueueHandle_t mqtt_get_tx_queue(void);/*** @brief 获取接收队列(用于其他任务接收消息)* @return QueueHandle_t 消息队列句柄*/
QueueHandle_t mqtt_get_rx_queue(void);/*** @brief 生成阿里云MQTT密码* @param client_id 客户端ID* @param product_key 产品Key* @param device_name 设备名称* @param device_secret 设备密钥* @param password_out 输出的密码缓冲区(至少65字节)*/
void mqtt_generate_password(const char *client_id, const char *product_key, const char *device_name, const char *device_secret, char *password_out);#ifdef __cplusplus
}
#endif#endif /* __MQTT_H */

这个阿里云MQTT配置可查看填入

我的W5500项目路径

太麻烦了,可以看下一个。这里之后更新

使用Cat1连接阿里云平台

AT指令串口连接

以塔石Cat1为例E27-EVK(内置SIM卡)

1. 开机联网

在这里插入图片描述

PWKY播到ON就可以正常使用AT指令,若没有拨到ON则会出现AT指令发送却收不到的现象

2. 激活内置SIM卡(贴片卡)
AT+CFUN=0  #注销网络
AT+QDSIM=1 #切卡SIM1内置贴片卡
AT+CFUN=1  #重新注册网络

之后就可以通过TCPIP连接还是UDP还是MQTT连接啦

3. 我这里使用连接的是阿里云的物联网平台
  • 我们先学会使用串口发数据,那用单片机去执行也很快
  1. 打开MQTT

AT+QMTOPEN指令
AT+QMTOPEN参数和相关返回值的含义

#举例: AT+QMTOPEN=0,"a1mqeQuLw0k.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883
AT+QMTOPEN=0,"ProductKey.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883

若出现在这里插入图片描述说明连接成功

  1. 连接阿里云
#举例: AT+QMTCONN=0,"wlan_wifi_test|securemode=3,signmethod=hmacsha1|","wlan_wifi_test&a1mqeQuLw0k","751050e9cca6018089a5dc729a55933e0da6ab74"
AT+QMTCONN=0,"DeviceName|securemode=3,signmethod=hmacsha1|","DeviceName&ProductKey","(DeviceName+DeviceName+DeviceSecret)通过hmacsha1加密而得到的"

加密工具密钥是DeviceSecret加密格式

阿里云MQTT配置
在这里插入图片描述

说明连接成功
查看物联网平台在这里插入图片描述
若出现

在这里插入图片描述
没有输出用户名密码或者出现QMTCONN:0,0,4的情况说明连接失败,请查看数据手册
在这里插入图片描述
出现QMTCONN:0,0,4需重新AT+QMTOPEN指令因为最后+QMTDISC: 0,0(断开连接)了

在这里插入图片描述

  1. 订阅主题
#举例: AT+QMTSUB=0,1,"/sys/a1mqeQuLw0k/wlan_wifi_test/thing/service/property/set",2
AT+QMTSUB=0,1,"/sys/ProductKey/DeviceName/thing/service/property/set",2

退订也是如此

#举例: AT+QMTUNS=0,1,"/sys/a1mqeQuLw0k/wlan_wifi_test/thing/service/property/set",2
AT+QMTUNS=0,1,"/sys/ProductKey/DeviceName/thing/service/property/set",2

请添加图片描述

  1. 数据推送
#举例: AT+QMTPUBEX=0,001,0,1,"/sys/a1mqeQuLw0k/wlan_wifi_test/thing/event/property/post",108
AT+QMTPUBEX=0,001,0,1,"/sys/ProductKey/DeviceName/thing/event/property/post",3

注意: 这个3和108是Length(发送数据的长度),小于发送数据的长度时数据全;大于发送数据的长度时会卡死(等待余下的数据,超时就ERROR)举例中的108是下面数据的长度

在这里插入图片描述
记住发送有时间规定

{"method":"thing.event.property.post","id":"726100847","params":{"CurrentTemperature":15},"version":"1.0.0"}

参数可以在这里查看
在这里插入图片描述
在这里插入图片描述

也可以设置-下发给设备
在这里插入图片描述

得到的数据是
在这里插入图片描述

+QMTRECV: 0,0,"/sys/a1mqeQuLw0k/wlan_wifi_test/thing/service/property/set","{"method":"thing.service.property.set","id":"1933324072","params":{"CurrentHumidity":20,"CurrentTemperature":10},"version":"1.0.0"}

出现日志中状态都是200说明上传成功
在这里插入图片描述
数据也得到修改

注意一点:在这里插入图片描述
即便是订阅了,发布成功,数据修改了,阿里云也没有显示订阅的Topic。这点我就不是很清楚了

4. (非必要)关闭MQTT连接
AT+QMTDISC=0

在这里插入图片描述

5. 总结:AT全部指令(简便式)
AT+CFUN=0  #注销网络
AT+QDSIM=1 #切卡SIM1内置贴片卡
AT+CFUN=1  #重新注册网络
AT+QMTOPEN=0,"a1mqeQuLw0k.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883
AT+QMTCONN=0,"wlan_wifi_test|securemode=3,signmethod=hmacsha1|","wlan_wifi_test&a1mqeQuLw0k","751050e9cca6018089a5dc729a55933e0da6ab74"
AT+QMTSUB=0,123,"/sys/a1mqeQuLw0k/wlan_wifi_test/thing/service/property/set",0
AT+QMTPUBEX=0,001,0,1,"/sys/a1mqeQuLw0k/wlan_wifi_test/thing/event/property/post",108
{"method":"thing.event.property.post","id":"726100847","params":{"CurrentTemperature":15},"version":"1.0.0"}

可以按照这个模板抄,换成自己的DeviceSecret(设备证书)

STM32单片机连接Cat1实现用MQTT连接阿里云

单片机和Cat1进行通讯还是用的AT指令

上例中Cat1默认波特率为115200
因为使用的是STM32所以我们就用CubeMX一笔配置
在这里插入图片描述
未完待续

http://www.xdnf.cn/news/1333531.html

相关文章:

  • Bigemap APP 详细使用教程,入门学习PPT
  • KDD 2025 | CMA:一次训练,预测任意过去与未来!元学习+扩散模型颠覆时序预测!
  • 【嵌入式电机控制#33】FOC:意法电控驱动层源码解析——整体框架篇(了解,常查阅)
  • 【Day 31】Linux-LNMP
  • 0基础安卓逆向原理与实践:第3章:逆向工程理论基础
  • 8 webUI中-Controlnet(控制与约束)的应用分类与使用方法
  • C++高频知识点(三十一)
  • 【ElasticSearch】ElasticSearch Overview
  • k8sday12数据存储(1/2)
  • AI 效应: GPT-6,“用户真正想要的是记忆”
  • 凸问题-非凸问题-非凸模型
  • JavaScript 性能优化实战(易懂版)
  • 【电气工程学习】
  • (nice!!!)(LeetCode 每日一题) 1277. 统计全为 1 的正方形子矩阵 (动态规划)
  • Qt5.9.9 + Windows API 开发系统监控工具 - 教学级项目实战
  • 项目各功能介绍
  • linux下MySQL安装与卸载
  • Tomcat 性能优化终极指南
  • 餐饮灶头:后厨效率与菜品稳定的核心载体
  • Linux《进程间通信(下)》
  • 海量数据测试指南与实战
  • 【PostgreSQL内核学习:WindowAgg 节点对 Tuplestore 的复用机制】
  • 超大型公共场所的智慧守护者——人脸动态识别与管理系统
  • Temu美国站大规模扫号封店:虚假本土店遭批量封禁,如何规避?
  • 心路历程-了解网络相关知识
  • 【C2000常见问题】当板子处于强电噪声环境下,或带重载时C2000芯片的PWM发波会出现异常,导致炸管。
  • Vue2封装Axios
  • 8.20网络编程——sqlite3数据库
  • LeetCode 刷题【47. 全排列 II】
  • 【Linux系统】匿名管道以及进程池的简单实现