ESP32/ESP8266上云——阿里云物联网平台同步MQTT-一叶遮天的博客
ESP32/ESP8266上云——阿里云物联网平台同步MQTT
此内容为付费资源,请付费后查看
会员专属资源
您暂无购买权限,请先开通会员
开通会员
开通【尊贵SVIP会员】后,可联系QQ客服:【2123933105】或微信客服:【XZB1436056045】进行技术售后答疑哦,记得发您的付款截图或网站用户名给客服,方便给您备注
付费资源

ESP32/ESP8266上云——阿里云物联网平台同步MQTT

图片[1]-ESP32/ESP8266上云——阿里云物联网平台同步MQTT-一叶遮天的博客

1、文件资料获取方式

开通【尊贵SVIP会员】后,在文章内容顶部点击【百度网盘】按钮即可自动跳转到下载页面

2、开发环境搭建方式

关于如何搭建ArduinoIDE/Platformio跨平台开发环境,请详看下面的文章:

3、库文件添加方式

关于库文件如何添加到ArduinoIDE中使用,请详看下面的文章:
Arduino Library库文件安装教程

4、库功能

4.1 功能介绍

基于ESP32/ESP8266 Arduino软件框架使用同步MQTT通信接入阿里云物联网平台,功能强大,简单易用。

MQTT协议版本:3.1.1

支持的芯片/开发板 是否支持
ESP8266/ESP8285系列 是【√】
ESP32-S1系列 是【√】
ESP32-S2系列 是【√】
ESP32-S3系列 是【√】
ESP32-C2/ESP8684系列 否【×】
ESP32-C3/ESP8685系列 是【√】
ESP32-C6系列 否【×】
ESP32-H2系列 否【×】

注:这个库基于Arduino软件框架开发,对于ESP32平台来说,所支持的芯片/开发板受制于ESP32 For Arduino SDK版本,随着SDK版本的不断更新迭代,所支持的芯片/开发板也将会更多。这个库是在2.0.9的SDK版本基础上进行的开发,测试各系列芯片/开发板都没有问题,因此建议安装至少2.0.5的SDK版本或以上更新的版本配套使用。

4.2 注意事项

  • 1、不管是接收还是发送数据,仅支持JSON格式的数据,不支持用户自定义透传的数据,如果不是JSON数据或者数据丢包,则会进入receivedDataParsingErrorCallbackPoint回调函数
  • 2、MQTT订阅和发布的QOS等级支持0、1、2,但只测试过0,未测试过1和2
  • 3、如果使用一型一密预注册或一型一密免预注册,EEPROM中第0到第299字节空间将会用来保存deviceSecret、clientId、deviceToken等设备配置信息,请勿使用此段空间!
  • 4、所连接的WIFI名称和WIFI密码需要设置正确,并且仅支持连接2.4GHz的WIFI,不支持5GHz的WIFI
  • 5、设备所使用的产品标识符、设备名称等参数要和阿里云物联网平台所创建的产品中的参数一致
  • 6、相关属性名称标识符和数据类型需要设置正确

4.3 其他库文件

  • ArduinoJson:用于Arduino和物联网的C++ JSON库,负责处理JSON字符串与JSON对象数据
  • arduino-mqtt:用于ESP8266/ESP32同步MQTT通信,负责整体MQTT协议,以及实现MQTT客户端的功能(包括设置Client端来源、连接服务器、发送数据等)
  • YYZT_Crypto:常用加密解密算法库

4.4 相关资料

5、 函数介绍

5.1 设置阿里云设备参数相关函数

设置设备密钥认证类型

/**
 * 函数功能:设置设备密钥认证类型
 * 参数1:[_deviceKeyAuthenticationType] [DeviceKeyAuthenticationType] 设备密钥认证类型
 * 返回值:无
 * 注意事项:无
 */
void setDeviceKeyAuthenticationType(DeviceKeyAuthenticationType _deviceKeyAuthenticationType);

设置产品标识符

/**
 * 函数功能:设置产品标识符
 * 参数1:[_productKey] [String] 产品标识符
 * 返回值:无
 * 注意事项:1、所有设备密钥认证都必须使用该函数
 */
void setProductKey(String _productKey);

设置产品密钥

/**
 * 函数功能:设置产品密钥
 * 参数1:[_productSecret] [String] 产品密钥
 * 返回值:无
 * 注意事项:1、仅一型一密预注册和一型一密免预注册必须使用该函数
 */
void setProductSecret(String _productSecret);

设置设备名称

/**
 * 函数功能:设置设备名称
 * 参数1:[_deviceName] [String] 设备名称
 * 返回值:无
 * 注意事项:1、如果是一机一密必须使用该函数,DeviceName在云平台添加设备后获取
 *          2、如果是一型一密预注册使用该函数则为用户自定义的设备名称,但需要和云平台预注册设备DeviceName相同
 *          3、如果是一型一密免预注册使用该函数则为用户自定义的设备名称,但需要注意每个设备的设备名称不要相同
 *          4、如果是一型一密预注册或一型一密免预注册不使用该函数,则DeviceName默认为STA MAC地址,比如"AC08D6E4321F",12字节十六进制字符串(英文全部大写)
 *          5、如果是一型一密预注册不使用该函数,ESP32和ESP8266均使用STA MAC地址且字符串长度都是12字节,需要在云平台添加相同的DeviceName
 *          6、如果是一型一密免预注册不使用该函数,ESP32和ESP8266均使用STA MAC地址且字符串长度都是12字节,不需要在云平台添加相同的DeviceName
 */
void setDeviceName(String _deviceName);

获取设备名称

/**
 * 函数功能:获取设备名称
 * 参数:无
 * 返回值:[String] 设备名称
 * 注意事项:1、如果已使用setDeviceName函数设置过设备名称,DeviceName则为前面使用setDeviceName函数设置的设备名称
 *          2、如果未使用setDeviceName函数设置过设备名称,则DeviceName默认为STA MAC地址,比如"AC08D6E4321F",12字节十六进制字符串(英文全部大写)
 */
String getDeviceName();

设置设备密钥

/**
 * 函数功能:设置设备密钥
 * 参数1:[_deviceSecret] [String] 设备密钥
 * 返回值:无
 * 注意事项:1、仅一机一密必须使用该函数
 */
void setDeviceSecret(String _deviceSecret);

设置地区

/**
 * 函数功能:设置地区
 * 参数1:[_region] [String] 地区,默认为上海,即"cn-shanghai"
 * 返回值:无
 * 注意事项:1、一般免费版本都是华东2(上海),即"cn-shanghai",如果是企业实例,则需要设置对应的地区
 *          2、地域列表和Region ID:https://help.aliyun.com/document_detail/427435.htm?spm=a2c4g.147356.0.0.ce8a7bc8alfOOf#concept-2211170
 */
void setRegion(String _region);

设置MQTT服务器的端口号

/**
 * 函数功能:设置MQTT服务器的端口号
 * 参数1:[_port] [uint16_t] MQTT服务器的端口号,默认为 1883
 * 返回值:无
 * 注意事项:无
 */
void setPort(uint16_t _port);

设置实例类型

/**
 * 函数功能:设置实例类型
 * 参数1:[_type] [InstanceType] 实例类型,默认为旧版公共实例
 * 参数2:[_instanceId] [String] 实例ID,仅新版公共实例或企业版实例需要填写该参数,默认为空
 * 返回值:无
 * 注意事项:1、查看新版公共实例和企业版实例终端节点信息(实例ID):https://help.aliyun.com/document_detail/147356.htm?spm=a2c4g.356505.0.0.b76e7c0dnCvoiX#section-rtu-6kn-kru
 */
void setInstanceType(InstanceType _type, String _instanceId = "");

设置回调函数的最大数量

/**
 * 函数功能:设置回调函数的最大数量
 * 参数1:[_number] [uint8_t] 回调函数的最大数量,默认为50
 * 返回值:无
 * 注意事项:无
 */
void setCallbackCountMax(uint8_t _number);

设置调试打印

/**
 * 函数功能:设置调试打印,如果未设置,则不开启打印,如果传入串口,则开启打印
 * 参数1:[_serial] [Stream&] 串口
 * 返回值:无
 * 注意事项:无
 */
void setDebug(Stream& _serial);

设置MQTT接收和发送数据缓冲区大小

/**
 * 函数功能:设置MQTT接收和发送数据缓冲区大小,单位是:字节
 * 参数1:[_receiveBufferSize] [uint32_t] MQTT接收数据缓冲区大小,默认最大为1024字节
 * 参数1:[_sendBufferSize] [uint32_t] MQTT发送数据缓冲区大小,默认最大为1024字节
 * 返回值:无
 * 注意事项:1、此函数必须在setClient函数前使用才有效
 */
void setBufferSize(uint32_t _receiveBufferSize, uint32_t _sendBufferSize);

设置MQTT已连接回调函数

/**
 * 函数功能:设置MQTT已连接回调函数
 * 参数1:[_cb] [mqttConnectedCallbackPoint] 回调函数
 * 返回值:无
 * 注意事项:无
 */
void setConnectedCallback(mqttConnectedCallbackPoint _cb);

MQTT连接失败或断开连接回调函数

/**
 * 函数功能:MQTT连接失败或断开连接回调函数
 * 参数1:[_cb] [mqttDisconnectedCallbackPoint] 回调函数(MQTT连接失败或者断开连接的原因,请见"lwmqtt.h"文件中的lwmqtt_err_t枚举说明)
 * 返回值:无
 * 注意事项:无
 */
void setDisconnectedCallback(mqttDisconnectedCallbackPoint _cb);

设置MQTT动态注册连接失败回调函数

/**
 * 函数功能:设置MQTT动态注册连接失败回调函数
 * 参数1:[_cb] [mqttDynamicRegistrationFailCallbackPoint] 回调函数
 * 返回值:无
 * 注意事项:无
 */
void setDynamicRegistrationFailCallback(mqttDynamicRegistrationFailCallbackPoint _cb);

设置MQTT重连间隔时间

/**
 * 函数功能:设置MQTT重连间隔时间
 * 参数1:[_time] [uint32_t] MQTT重连间隔时间,单位为:ms,默认为10000ms,最小为1000ms
 * 返回值:无
 * 注意事项:1、重连间隔时间同样也是连接MQTT超时时间
 */
void setReconnectTime(uint32_t _time);

设置client

/**
 * 函数功能:设置client
 * 参数1:[_client] [Client&] client
 * 返回值:无
 * 注意事项:无
 */
void setClient(Client& _client);

获取MQTT连接状态

/**
 * 函数功能:获取MQTT连接状态
 * 参数:无
 * 返回值:[MqttConnectState] 见MqttConnectState枚举说明
 * 注意事项:无
 */
MqttConnectState getConnectStatus();

清空保存在EEPROM中的设备配置信息

/**
 * 函数功能:清空保存在EEPROM中的设备配置信息
 * 参数:无
 * 返回值:无
 * 注意事项:无
 */
void clearEepromDeviceInfo();

读取保存在EEPROM中的设备配置信息

/**
 * 函数功能:读取保存在EEPROM中的设备配置信息
 * 参数:无
 * 返回值:[String] 设备配置信息
 * 注意事项:无
 */
String getEepromDeviceInfo();

立即重连MQTT

/**
 * 函数功能:立即重连MQTT
 * 参数:[_deviceInfo] [String] 设备配置信息
 * 返回值:[bool] true--重连成功,false,重连失败
 * 注意事项:1、如果MQTT已连接状态下使用该函数,则只会返回true
 */
bool immediateReconnect();

MQTT任务运行

/**
 * 函数功能:MQTT任务运行
 * 参数:无
 * 返回值:无
 * 注意事项:1、尽量不要在程序中使用delay等延时堵塞程序的代码
 */
void runTask();

mqttClient

MQTTClient* mqttClient = NULL;  // 实例化mqttClient

5.2 发送数据相关函数

发送属性数据到云平台

/**
 * 函数功能:发送多个数据到云平台
 * 参数1:[_data] [String] 数据内容,需要提前拼接好,_data格式为:{"name":"一叶遮天","age":22,"site":"blog.yyzt.site","height":182.34},仿照这个格式根据实际情况改写,最外层需要加花括号
 * 参数2:[_qos] [uint8_t] qos等级,默认为0
 * 返回值:[bool] true--发送成功,false--发送失败,未联网
 * 注意事项:1、可自行将整数型、单精度浮点型、双精度浮点型、枚举型、布尔型、字符串、时间型、结构体、数组等数据类型打包成JSON字符串,再使用此函数发送打包的数据到云平台
 */
bool sendAttributeData(String _data, uint8_t _qos = 0);

发送事件到云平台

/**
 * 函数功能:发送事件到云平台
 * 参数1:[_eventId] [String] 事件ID,即标识符
 * 参数2:[_data] [String] 数据内容,默认为空则发送空数据,最外层需要加花括号
 * 参数3:[_qos] [uint8_t] qos等级,默认为0
 * 返回值:[bool] true--发送成功,false--发送失败,未联网
 * 注意事项:无
 */
bool sendEventData(String _eventId, String _data = "{}", uint8_t _qos = 0);

发送自定义主题和数据到云平台

/**
 * 函数功能:发送自定义主题和数据到云平台
 * 参数1:[_topic] [String] 主题,即Topic类,在产品中的Topic类列表中查看
 * 参数2:[_data] [String] 数据内容,默认为空,最外层需要加花括号
 * 参数3:[_qos] [uint8_t] qos等级,默认为0
 * 返回值:[bool] true--发送成功,false--发送失败,未联网
 * 注意事项:1、数据格式不能错误,否则会导致云平台接收或者解析不了
 */
bool sendCustomData(String _topic, String _data = "{}", uint8_t _qos = 0);

5.3 接收数据相关函数

绑定属性以及设置接收回调函数

/**
 * 函数功能:绑定属性以及设置接收回调函数
 * 参数1:[_attributeName] [String] 属性名称
 * 参数2:[_cb] [poniterReceiveDeserialization] 回调函数
 * 返回值:[bool] true--设置成功,false--设置失败,属性名称为空或者回调函数为空或者已超过最大设置数量,默认最大为50
 * 注意事项:1、如果已设置过相同属性名称,则后面的会覆盖前面的
 */
bool bindAttribute(String _attributeName, poniterReceiveDeserialization _cb);

取消绑定的属性

/**
 * 函数功能:取消绑定的属性
 * 参数1:[_attributeName] [String] 属性名称
 * 返回值:[bool] true--取消绑定成功,false--取消绑定失败,属性名称为空或者不存在该属性名称
 * 注意事项:无
 */
bool unbindAttribute(String _attributeName);

订阅主题

/**
 * 函数功能:订阅主题
 * 参数1:[_topicName] [String] 主题名称
 * 参数2:[_cb] [poniterReceiveDeserialization] 回调函数
 * 参数3:[_qos] [uint8_t] qos等级,默认为0
 * 返回值:[bool] true--订阅成功,为false--订阅失败,主题名称为空或者或者回调函数为空或者回调函数已超过最大设置数量(默认最大为50)或者未联网
 * 注意事项:无
 */
bool subscribeTopic(String _topicName, poniterReceiveDeserialization _cb, uint8_t _qos = 0);

取消订阅主题

/**
 * 函数功能:取消订阅主题
 * 参数1:[_topicName] [String] 主题名称
 * 返回值:[bool] true--取消订阅成功,false--取消订阅失败,主题名称为空或者不存在该主题名称或者未联网
 * 注意事项:无
 */
bool unsubscribeTopic(String _topicName);

订阅设备属性设置主题

/**
 * 函数功能:订阅设备属性设置主题
 * 参数1:[_qos] [uint8_t] qos等级,默认为0
 * 返回值:[bool] true--订阅成功,为false--订阅失败,未联网
 * 注意事项:1、此功能仅订阅设备属性设置主题
 */
bool subscribeAttributeSetting(uint8_t _qos = 0);

设置接收的数据解析成JSON数据错误的回调函数

/**
 * 函数功能:设置接收的数据解析成JSON数据错误的回调函数
 * 参数1:[_cb] [receivedDataParsingErrorCallback] 回调函数
 * 返回值:无
 * 注意事项:1、因为本库不管是接收还是发送数据,仅支持JSON格式的数据,不支持用户自定义透传的数据,所以如果不是JSON数据或者数据丢包,则会进入设置的回调函数
 */
void setReceivedDataParsingErrorCallback(receivedDataParsingErrorCallbackPoint _cb);

设置未知主题或JSON数据回调函数

/**
 * 函数功能:设置未知主题或JSON数据回调函数
 * 参数1:[_cb] [unknownTopicDataCallbackPoint] 回调函数
 * 返回值:无
 * 注意事项:1、进入此回调函数则表示主题名称不存在或对应的回调函数未设置
 */
void setUnknownTopicDataCallback(unknownTopicDataCallbackPoint _cb);

5.4 相关定义

设备密钥认证类型

/**
 * 枚举功能:设备密钥认证类型
 * 参考文档:https://help.aliyun.com/document_detail/42649.html?spm=a2c4g.74005.0.0.5929b91eKnQ1tl
 */
typedef enum {
  OneMachineOneSecret = 0,              // 一机一密(已支持)
  OneTypeOnePasswordPreRegistration,    // 一型一密预注册(已支持)
  OneTypeOnePasswordNoPreRegistration,  // 一型一密免预注册(已支持)
  DynamicRegistrationOfSubDevices       // 子设备动态注册(暂不支持)
} DeviceKeyAuthenticationType;

实例类型

/**
 * 枚举功能:实例类型
 * 参考文档:https://help.aliyun.com/document_detail/356505.html?spm=a2c4g.148361.0.0.52bb13ddtDmA6Y
 */
typedef enum {
  OldVersionPublicInstance = 0,          // 旧版公共实例
  NewPublicOrEnterpriseVersionInstances  // 新版公共实例或企业版实例
} InstanceType;

MQTT连接状态

// MQTT的连接状态
typedef enum {
  MqttDisconnected = 0,  // MQTT已断开连接
  MqttConnecting,        // MQTT连接中
  MqttConnected          // MQTT已连接
} MqttConnectState;

回调函数

typedef void (*poniterReceiveDeserialization)(JsonVariant _data);                    // 定义一个接收json字符串反序列化的函数指针
typedef void (*mqttConnectedCallbackPoint)(void);                                    // 定义一个MQTT已连接回调函数的函数指针
typedef void (*mqttDisconnectedCallbackPoint)(lwmqtt_err_t _state);                  // 定义一个MQTT断开连接回调函数的函数指针
typedef void (*receivedDataParsingErrorCallbackPoint)(String _topic, String _data);  // 定义一个接收数据解析成JSON数据错误的回调函数的函数指针
typedef void (*unknownTopicDataCallbackPoint)(String _topic, JsonVariant _data);     // 定义一个未知主题或JSON数据回调函数指针
typedef void (*mqttDynamicRegistrationFailCallbackPoint)(void);                      // 定义一个MQTT动态注册失败回调函数的函数指针

6、使用示例

6.1 基础篇

6.1.1 课程介绍

6.1.2 开发环境安装教程

6.1.3 示例1:一次上报单个属性数据到云平台

6.1.4 示例2:一次上报多个属性数据到云平台

6.1.5 示例3:上报事件数据到云平台

6.1.6 示例4:接收云平台属性数据

6.1.7 示例5:上报和接收属性数据

6.1.8 示例6:NTP时钟同步,获取网络时间

6.1.9 示例7:自动OTA远程升级

6.1.10 示例8:手动OTA远程升级

6.1.11 示例9:自定义订阅和发布

数据流转脚本代码模板参考:

// 通过payload函数,获取设备上报的消息内容,并按照JSON格式转换。
var data = payload("json");
// 直接流转物模型上报数据。
writeIotTopic(数据目的ID,"流转目的的主题", data);

6.1.12 示例10:一型一密预注册的使用

6.1.13 示例11:一型一密免预注册的使用

6.1.14 示例12:Iot Studio平台的使用

6.1.15 示例13:云智能APP(阿里云生活物联网平台)的使用

6.2 应用篇

6.2.1 云智能APP——温湿度计_DHT11

6.2.2 云智能APP——远程控制继电器

6.2.3 uniapp(微信小程序)——第1节:课程介绍

6.2.4 uniapp(微信小程序)——第2节:软件安装

6.2.5 uniapp(微信小程序)——第3节:温湿度计_DHT11

6.2.6 uniapp(微信小程序)——第4节:远程控制继电器

6.2.7 云智能APP——Arduino ESP32 阿里云 毕业设计 课程设计 DIY制作 0001——基于ESP32的智能家居自动与远程控制系统的设计与制作

6.3 拓展篇

7、库版本

  • v0.1

    1、将"Crypto"库文件替换为"YYZT_Crypto",优化加密算法,节省内存空间。
    2、将发送属性数据到云平台的函数统一改为"sendAttributeData",需要自行组装JSON格式数据,具体见更新的的示例程序,解决了ESP32-C3编译报错的问题,无需再做数据类型强制转换。
    3、增加了设置MQTT服务器的端口号的函数"setPort",为后续MQTTS连接做兼容。
    4、优化了底层断开MQTT重新连接代码。

  • v0.0

    1、增加了自定义订阅和发布的示例,可以使用阿里云物联网平台的消息转发(云产品流转),自由接入自主开发的APP、小程序、web网页等,对设备进行操作。
    2、增加了设备动态注册功能(仅支持一型一密预注册和一型一密免预注册),无需为每个设备逐一烧录设备证书,可批量烧录相同的产品证书,适合量产的产品。
    3、增加了接入阿里云生活物联网平台功能,使用云智能App(公版App)对设备进行操作。
    4、库底层将StaticJsonDocument更换为DynamicJsonDocument,解决ESP32S2解析JSON数据为null的问题。
    5、将异步MQTT库"AsyncMqttClient"更换为同步MQTT库"arduino-mqtt",解决频繁发送消息导致设备重启的问题。

© 版权声明
THE END
喜欢就支持一下吧
分享