前言

之前研究了一段时间的 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. Java设计模式之(三)——建造者模式

    1.什么是建造者模式 Separate the construction of a complex object from its representation so that the same co ...

  2. Linux下编译tinyxml生成动态库

    首先去到sourceforge下载tinyxml的源码,https://sourceforge.net/projects/tinyxml/?source=dlp,最新版本是2.6.2. 将下载成功的t ...

  3. 第02章_MySQL环境搭建

    第02章_MySQL环境搭建 1. MySQL的卸载 步骤1:停止MySQL服务 在卸载之前,先停止MySQL8.0的服务.按键盘上的"Ctrl + Alt + Delete"组合 ...

  4. 『学了就忘』Linux权限管理 — 56、不可改变位权限(chattr)

    目录 1.命令格式 2.查看文件系统属性chattr权限 3.示例 文件系统属性chattr权限,也叫不可改变位权限,该权限没有风险,但是他能限制root用户. 1.命令格式 [root@localh ...

  5. vue3 高阶 API 大汇总,强到离谱

    高阶函数是什么呢? 高阶函数英文名叫:Higher Order function ,一个函数可以接收一个或多个函数作为输入,或者输出一个函数,至少满足上述条件之一的函数,叫做高阶函数. 前言 本篇内容 ...

  6. GIT Bash 简单讲解-git如何推/拉代码

    GIT Bash 简单讲解 一.            注册/登录GIT账号 注册(或者登录) GitHub地址:https://github.com/ 注册不做详细的讲解,按照注册指示进行注册就可以 ...

  7. Codeforces 590E - Birthday(AC 自动机+Dilworth 定理+二分图匹配)

    题面传送门 AC 自动机有时只是辅助建图的工具,真的 首先看到多串问题,果断建出 AC 自动机.设 \(m=\sum|s_i|\). 不难发现子串的包含关系构成了一个偏序集,于是我们考虑转化为图论,若 ...

  8. mysql 实现某年单季度内的品牌TOPn销量在此年此单季度内销量占比

    数据表:       结果表: mysql语句:  

  9. (转载)java排序实现

    Java实现几种常见排序方法 日常操作中常见的排序方法有:冒泡排序.快速排序.选择排序.插入排序.希尔排序,甚至还有基数排序.鸡尾酒排序.桶排序.鸽巢排序.归并排序等. 冒泡排序是一种简单的排序算法. ...

  10. FFmpeg笔记:使用MSVC工具链编译Windows版本静态库、动态库

    2019年3月开始,为了将音视频编解码功能集成到Cocos2d-x中,开始接触到FFmpeg: 当时开发环境还在Mac下,编译FFmpeg相比现在用Windows平台要方便的多: 最近,公司内部有个U ...