前言

之前研究了一段时间的 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. [loj3285]Circus

    将奶牛的状态用序列$\{a_{1},a_{2},...,a_{m}\}$来描述,其中$a_{i}$表示第$i$头奶牛的位置(奶牛数量为$m$) 下面,先来考虑对于某个特定的$m$如何处理: 对于一条简 ...

  2. 手把手教你实现Android真机远程截屏

    先看效果演示 接下来手把手教你实现这样的效果. minicap简介 minicap是一个可以远程获取android屏幕画面的开源库,它在低版本的Android系统上采用截屏的方式获取画面,在Andro ...

  3. NOI 2008 志愿者招募

    NOI 2008 志愿者招募 考虑用 $ p_i $ 表示第 $ i $ 天实际招收的人数,我们假设我们有三种志愿者,分别是 $ 1\to 2,1 \to 3 , 2\to 3 $ ,我们招手的人数分 ...

  4. R语言实战-Part 2笔记

    R 语言实战(第二版) part 2 基本方法 -------------第6章 基本图形------------------ #1.条形图 #一般是类别型(离散)变量 library(vcd) he ...

  5. CSS浮动效果

    #div1{ background-color: yellow; width: 150px; height:150px; position: absolute; top:150px; left: 15 ...

  6. C语言 指针数组指针

    指向指针数组的指针. 1 #include <stdio.h> 2 3 int main(void) 4 { 5 char *pa[4]={"aaaaa"," ...

  7. 关于蓝牙Mesh您必须知道的七件事

    蓝牙技术联盟于7月19日正式宣布,蓝牙(Bluetooth)技术开始全面支持Mesh网状网络.全新的Mesh功能提供设备间多对多传输,并特别提高构建大范围网络覆盖的通信能力,适用于楼宇自动化.无线传感 ...

  8. 字符scanf 的输入注意

    1.注意scanf 不能有空格,如果有空格会将空格给输入进去 scanf("d "):---有空格 和scanf("d");--没有空格 有很大的区别

  9. 以DevExpress开发的WinFrom程序的多语言功能的实现

    以DevExpress开发的WinFrom程序的多语言功能的实现 写在前面: 多语言切换功能在Winform程序中是经常遇到的需求,尤其是需要给国外客户使用的情况下,多语言功能是必不可少的.前一段时间 ...

  10. 30个类手写Spring核心原理之环境准备(1)

    本文节选自<Spring 5核心原理> 1 IDEA集成Lombok插件 1.1 安装插件 IntelliJ IDEA是一款非常优秀的集成开发工具,功能强大,而且插件众多.Lombok是开 ...