前言

之前研究了一段时间的 COAP 协议结果爱智那边没有测试工具,然后 arduino 也没有找到合适的库,我懒癌发作也懒得修这库,就只能非常尴尬先暂时放一放了。不过我在 爱智APP -> 设备 -> 设置 中发现爱智中做了一个 MQTT Broker ,也就是说我能利用精灵一号,在两块ESP32 之间进行通讯了,而且 arduino 也有现成的库,然后我就突击了一下MQTT ,把这玩意给弄起来了,这里就给大家分享一下。

配置 MQTT Broker

在爱智APP的设备中有个设置按钮:



在里面可以启用精灵一号的 MQTT Broker 功能并且进行设置:



在 MQTT 的设置中可以配置相关参数:



这些参数和与下面 ESP32 中的配置有关

代码获取

我使用的 MQTT 库直接在 IDE 的库管理器里就能下载到:



或者去GitHub下载:

https://github.com/adafruit/Adafruit_MQTT_Library

而示例代码,老样子在灵感桌面的秘密宝库 下载代码。

或者直接 git clone:

https://gitee.com/inspiration-desktop/eap-energy-conservation.git



里面有两个文件夹,分别是发布者和订阅者发的示例。

代码解析

为了方便讲解逻辑,我会打乱代码的顺序可能还会进行裁剪。本 demo 基于 MQTT 库自带的 DEMO 修改而来。

创建 MQTT 客户端

#include <WiFi.h>
//#include "WiFiClientSecure.h"
#include "WiFiClient.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h" /************************* WiFi Access Point *********************************/ #define WLAN_SSID "EOS-Tenda"
#define WLAN_PASS "1234567890" /************************* Adafruit.io Setup *********************************/ #define AIO_SERVER "192.168.128.1" // 在爱智APP->设备->MQTT Broker 设置,可以看到并且设置
#define AIO_SERVERPORT 1883 // 在爱智APP->设备->MQTT Broker 设置,可以看到并且设置
#define AIO_USERNAME "user"
#define AIO_KEY "passwd" /************ Global State (you don't need to change this!) ******************/ // 爱智似乎没有这个安全模式,于是使用了 WiFiClient
//WiFiClientSecure client;
WiFiClient client; // 通过传入WiFi客户端和MQTT服务端以及登录详细信息来设置MQTT客户端类,注意连入爱智必须设置 cid,可能和爱智那边设置有关系。
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, "Publish_cid", AIO_USERNAME, AIO_KEY);

需要注意的是虽然 Adafruit_MQTT_Client 有可以不带 cid 的实现

/***
* 函数1:创建MQTT客户端
* @param client 来源客户端,比如Wificlient eth以太网
* @param server mqtt服务器地址
* @param port mqtt服务器端口
* @param cid 客户端id,如果是8266,可以设置为芯片id之类的,每个端都是独一无二
* @param user mqtt服务器账号
* @param pass mqtt服务器密码
*/
Adafruit_MQTT_Client(Client *client, const char *server, uint16_t port,
const char *cid, const char *user, const char *pass):
Adafruit_MQTT(server, port, cid, user, pass),
client(client)
{} /***
* 函数2:创建MQTT客户端
* @param client 来源客户端,比如Wificlient eth以太网
* @param server mqtt服务器地址
* @param port mqtt服务器端口
* @param user mqtt服务器账号
* @param pass mqtt服务器密码
*/
Adafruit_MQTT_Client(Client *client, const char *server, uint16_t port,
const char *user="", const char *pass=""):
Adafruit_MQTT(server, port, user, pass),
client(client)
————————————————
版权声明:本文为CSDN博主「单片机菜鸟哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dpjcn1990/article/details/103376117

但是连接爱智时 Adafruit_MQTT_Client 函数必须设置 cid 而且 cid 必须是独一无二的,否则:



cid 重复会导致这两个设备收到同样的,重复的连接成功消息,使设备不停的去连接精灵一号

创建 MQTT 发布主题

// 设置一个名为“test”的提要用于发布。
// 注意AIO的MQTT路径遵循: <username>/feeds/<feedname>
Adafruit_MQTT_Publish test = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/test");

创建 MQTT 订阅主题

// 设置订阅的主题。
Adafruit_MQTT_Subscribe test = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/test");

初始化流程

void setup() {
Serial.begin(115200);
delay(10); Serial.println(F("Adafruit IO MQTTS (SSL/TLS) Example")); // Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID); delay(1000); WiFi.begin(WLAN_SSID, WLAN_PASS);
delay(2000); while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(); Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP()); // 设置测试需要的 MQTT 订阅。发布者把这一行注释掉
mqtt.subscribe(&test);
}

MQTT 连接

// 函数用于根据需要连接并重新连接到MQTT服务器
// 应该在循环函数中调用,它将注意是否连接。
void MQTT_connect() {
int8_t ret; // 如果已经停止连接。
if (mqtt.connected()) {
return;
} Serial.print("Connecting to MQTT... "); uint8_t retries = 3;
// 连接mqtt服务器
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
} Serial.println("MQTT Connected!");
}

发布者协议主循环

void loop() {
// 确保到MQTT服务器的连接是活动的(这将创建第一个连接,
// 并在断开连接时自动重新连接)。请参阅上面的MQTT_connect函数定义。
MQTT_connect(); // 现在我们可以发布东西了!
Serial.print(F("\nSending val "));
Serial.print(x);
Serial.print(F(" to test feed..."));
if (! test.publish(x++)) {
Serial.println(F("Failed"));
} else {
Serial.println(F("OK!"));
} // wait a couple seconds to avoid rate limit
delay(2000); }

订阅者协议主循环

void loop() {
// 确保到MQTT服务器的连接是活动的(这将创建第一个连接,
// 并在断开连接时自动重新连接)。请参阅上面的MQTT_connect函数定义。
MQTT_connect(); // 等待订阅消息循环
Adafruit_MQTT_Subscribe *subscription;
// 在5s内判断是否有订阅消息进来
while ((subscription = mqtt.readSubscription(5000)))
{
Serial.println("subscription");
// 判断是否是我们对应的主题
if (subscription == &test)
{
Serial.print(F("Got: "));
// 打印主题信息内容
Serial.println((char *)test.lastread);
} // wait a couple seconds to avoid rate limit
delay(2000);
}
}

总结



精灵一号的 MQTT Broker 还是好用的,两个 ESP32 板子完美的通讯了。

MQTT协议 - arduino ESP32 通过精灵一号 MQTT Broker 进行通讯的代码详解的更多相关文章

  1. COAP协议 - arduino ESP32 M2M(端对端)通讯与代码详解

    前言 最近我在研究 COAP 协议,在尝试使用 COAP 协议找了到了一个能在ESP32上用的coap-simple库,虽然库并不完善关于loop处理的部分应该是没写完,但是对于第一次接触COAP的朋 ...

  2. 微信JS-SDK]微信公众号JS开发之卡券领取功能详解

    js sdk: http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.952-.E6 ...

  3. 微信支付PHP SDK —— 公众号支付代码详解

    在微信支付 开发者文档页面 下载最新的 php SDK http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 这里假设你已经申请完微 ...

  4. 8 TFTP代码详解 协议写在程序中

    1.版本1:发送请求 # -*- coding:utf-8 -*- import struct from socket import * #0. 获取要下载的文件名字: downloadFileNam ...

  5. 转:XMPP协议、MQTT协议、HTTP协议、CoAP协议的基本比较

    一.先看下相关国外的专业数据对四大协议的比较: Protocol                                    CoAP                         XMP ...

  6. 为什么最近每份 Android 简历都说 “熟悉 MQTT 协议”?

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...

  7. 基于MQTT协议进行应用开发

    官方协议有句如下的话来形容MQTT的设计思想: "It is designed for connections with remote locations where a "sma ...

  8. 物联网MQTT协议分析和开源Mosquitto部署验证

    在<物联网核心协议—消息推送技术演进>一文中已向读者介绍了多种消息推送技术的情况,包括HTTP单向通信.Ajax轮询.Websocket.MQTT.CoAP等,其中MQTT协议为IBM制定 ...

  9. HTTP协议和XMPP协议、MQTT协议

    应用层协议:每个应用层的都是为了解决某一类应用问题.而问题的解决又必须通过位于不同主机中的多个应用进程之间的通信和协同工作来完成.应用进程之间必须遵守严格的规则.应用层协议应当定义如下几个: 应用进程 ...

随机推荐

  1. dart系列之:dart中的异步编程

    目录 简介 为什么要用异步编程 怎么使用 Future 异步异常处理 在同步函数中调用异步函数 总结 简介 熟悉javascript的朋友应该知道,在ES6中引入了await和async的语法,可以方 ...

  2. 关于【【故障公告】数据库服务器 CPU 近 100% 引发的故障(源于 .NET Core 3.0 的一个 bug)】IS NOT NULL测试

    测试如图,Core_Users的PhoneNumber可为空,存在索引,记录数1500000+ 增加is not null,查询计划消耗增加了一个0%的筛选器消耗,IO消耗如下一模一样 如果是IS N ...

  3. Hi3516开发笔记(三):Hi3516虚拟机基础环境搭建之交叉编译环境境搭建以及开机启动脚本分析

    前言   前面进行了可以传输,那么写一个简单的C程序来交叉编译并传入运行.   虚拟机   上一篇搭建的虚拟机环境,包含了sftp传递文件,网络能ping通,基于上一篇的虚拟机继续搭建.   海思交叉 ...

  4. 一文带你吃透CLR垃圾回收机制

    前言 今天我们来共同学习一下CLR的垃圾回收机制,这对我们写出健壮性的代码很有帮助,也许有人会认为多此一举,认为垃圾回收交给CLR就行,我不用关心这个,诚然,大多数情况下是这样的,但是,我们今天讨论的 ...

  5. 掌握Java的内存模型,你就是解决并发问题最靓的仔

    摘要:如果编写的并发程序出现问题时,很难通过调试来解决相应的问题,此时,需要一行行的检查代码,这个时候,如果充分理解并掌握了Java的内存模型,你就能够很快分析并定位出问题所在. 本文分享自华为云社区 ...

  6. vscode 整理————开篇之力(一)

    前言 作为一个开发为什么对一个vscode 这样的工具进行整理呢,因为vscode 非常的常用,它包含很多编辑器共同有的特征,这些特征帮助我们了解其他编辑器. 这里可能就有人疑问了,我们需要去非常的关 ...

  7. 9.2 k8s结合Jenkins与gitlab实现代码升级与回滚

    1.部署Jenkins 1.1 安装jdk # apt 安装jdk11 apt install openjdk-11-jdk # 查看 root@jenkins:~# java -version op ...

  8. 【基因组预测】braker2基因结构注释要点记录

    目录 流程使用 问题 记录下braker2的使用要点,以备忘记. 流程使用 braker2有很多流程,根据你的数据:组装的基因组.转录组.蛋白(同源,包括近缘或远缘)选择不同流程,官网有说明: htt ...

  9. php操作mongodb手册地址

    php操作mongodb手册地址: http://php.net/manual/zh/class.mongocollection.php

  10. PL\SQL和PL/SQL Developer 12安装与配置

    安装: (1)在已有安装包的情况下,直接将安装包解压到文件夹下,注意不要解压缩到c:\programs Files(x86)的文件夹下,不能解压缩到有中文文件夹命名的文件夹下面 (2)没有安装包的情况 ...