物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)

实验准备

  • 理论准备
(一)网络的分层结构
一般分为五层:
  1. 应用层(Application Layer):规定应用程序的数据格式。
2、传输层(Transport Layer):我们添加了一个参数,这个参数被称为“端口”(port)。每个任务拥有自己port,只接受对应port的数据,以此来区分数据。
3、网络层(Network Layer):少部分设备组成局域网,形成子网络,然后子网络不断组网形成覆盖全球的网络。以太网协议是通过MAC地址来寻址的(类似I2C的地址),但在如此巨大的网络中不可能每次寻找设备还需要给每个设备发送信息来匹配MAC地址,此时就产生“网址”的概念。此时,每一个网络设备就有了2种地址,一个是MAC地址,一个IP网络地址。
(1)MAC地址:又名物理地址、硬件地址,如身份证号一样,每个网络设备的MAC地址具有唯一性。
(2)IP地址:常见的IPv4协议,这个协议规定,网址由32个bit组成习惯上,我们用分成四段的十进制数表示IP地址,从0.0.0.0一直到255.255.255.255。互联网上的每个设备,都会分配到一个IP地址。这个地址分成两个部分,前一部分代表网络,后一部分代表设备。问题在于单单从IP地址,我们无法判断网络部分具体的占位。利用子网掩码,分别进行&运算,若两IP地址运算结果相同则说明它们在一个网络中。比如,已知IP地址192.168.1.1和192.168.1.5的子网掩码都是255.255.255.0,请问它们是否在同一个子网络?两者与子网掩码分别进行AND运算,结果都是192.168.1.0,因此它们在同一个子网络。
IP协议的作用主要有两个,一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络。
4、链接层(Link Layer):对0和1的定义进行规定(类似低电平为0,高电平为1),同时在传输0,1之后还需要对01进行分组如8bit为一个字节多少字节为一个包之类。这就是链接层的功能。Ethenet和Wifi基本就是属于这个层次。所以wifi协议其实就是解决的一个链路和物理层的问题
5、物理层(Physical Layer):硬件连接手段,规定设备的电气特性。例如:网线数量,无线信号的频段等。

每一个层都是完成了某一种功能,为了功能实现,所以规定了一些规则,这些规则就被称为“协议”(protocol)。
  • SAT与AP模式
1、AP,就是无线接入点,是一个无线网络的创建者,是网络的中心节点。例如家用无线路由器就是一个AP。
2、STA站点,每一个连接到无线网络的终端(手机电脑等用户设备)都可以成为STA站点。
(三)什么是MQTT
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议
简单来说MQTT服务器(常应用于物联网领域IOT)则是提供给我们一个可以实现远程信息传入的AP节点。
  • 开发环境(IDE)的搭建
我在这里选用了ardino的开发环境,也可选择vs code。
搭建过程推荐参考博客(1条消息) 玩转 ESP32 + Arduino (一) 开发环境搭建_finedayforu的博客-CSDN博客物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片
https://blog.csdn.net/finedayforu/article/details/108464784?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163344070016780262580280%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163344070016780262580280&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-3-108464784.first_rank_v2_pc_rank_v29&utm_term=esp32%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BAarduino&spm=1018.2226.3001.4187
(2021.10.5实测有效)
实验过程
  • 连接到公共MQTT服务器实现数据传输
参考博客
(1条消息) ESP32 连接到免费的公共 MQTT 服务器_emqx_broker的博客-CSDN博客物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片
https://blog.csdn.net/emqx_broker/article/details/119037189
基本原理:用esp32作为终端(SAT),利用已有的MQTT服务器作为AP,进行数据的传输(可以实现双向)

1,固件库的安装
(1)Esp32开发板的安装
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片

(2)PubSubClient 库的安装
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片



2,主要过程
(1)首先我们将导入 WiFi 和 PubSubClient 库,ESP8266WiFi 库能够将 ESP32 连接到 Wi-Fi 网络,PubSubClient 库能使 ESP32 连接到 MQTT 服务器发布消息及订阅主题。
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片



创建实例化对象来使用wifi与MQTT功能
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片



(2)设置 Wi-Fi 名称和密码,以及 MQTT 服务器连接地址和端口,设置 topic 为 “esp32/test”(注意这里wifi名字与密码是我自己热点的,用的时候更改一下)物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片


(3)set up()函数(只进行一次,相当于初始化)(主要都是库函数 了解怎么调用即可)
其作用是规定串口通信的波特率,连接WiFi,连接到公共的MQTT broker。
1’ WiFi连接
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片



2’连接到公共的MQTT broker
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片


3’ 简单的通信测试
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片



(4)Loop()函数
Loop函数 其实是一个一直运行的循环函数,我们需要的数据传输在这里进行,其实在测试样例中我们只需要一个client.publish(),但在这之前需要对其后一个参数进行类型转换,char*与string类都不行。
client.publish(topic, (char*) payload.c_str())
可以看博客MQTT client.publish, How do I publish a string? · Issue #334 · knolleary/pubsubclient · GitHub
【物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)】对于这个问题的讨论。
也可以用 String.toCharArray()对string进行类型转换(这个没试)。
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片

每500ms传输一次数据。(在此是随意测试数据样例)
完整代码如下:
#include #include // WiFi const char *ssid = "123q"; // Enter your WiFi name const char *psw = "bbz10001"; // Enter WiFi password// MQTT Broker const char *mqtt_broker = "broker.emqx.io"; const char *topic = "esp32/test"; const char *mqtt_username = "emqx"; const char *mqtt_password = "public"; const int mqtt_port = 1883; //for our data output loop char buff[50]; int car_speed=10; WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(115200); WiFi.begin(ssid,psw); while(WiFi.status()!=WL_CONNECTED){//未连接上 delay(500); Serial.println("connect to wifi..."); } Serial.println("successfully connected"); client.setServer(mqtt_broker, mqtt_port); while (!client.connected()) { String client_id = "esp32-client-"; client_id += String(WiFi.macAddress()); Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str()); if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { Serial.println("Public emqx mqtt broker connected"); } else { Serial.print("failed with state "); Serial.print(client.state()); delay(2000); } } // publish and subscribe client.publish(topic, "Hi EMQ X I'm ESP32 ^^"); client.subscribe(topic); }void loop() { sprintf(buff, "the speed is %d m/s.", car_speed++); String string_to_send = buff; uint16_t string_length = string_to_send.length(); char output_value_char[string_length]; string_to_send.toCharArray(output_value_char, string_length); for (uint8_t i = 0; i < string_length; i++) { Serial.print(output_value_char[i]); } Serial.println(); client.loop(); client.publish(topic, output_value_char); delay(500); }

3.MQTT服务器相关设置
下载MQTT X 客户端
新建一个连接(设置如下图)
Password:public(这些设置需要与你代码中的设置一致才能成功连接)
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片

将代码烧录进入esp32中,点向右箭头即可。
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片


最后用串口调试助手和MQTT X检验结果。

这是串口自己打印的结果,用serial函数。
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片

这是在公共服务器中显示的结果,用client.publish()来打印的。由此可知数据传输的基本任务大致完成。
物联网|基于esp32的MQTT服务器简单WiFi通信(零基础)
文章图片

注:博主也是刚开始接触esp32,很多资料都是网上查找,如果有缺漏欢迎各位指正。

    推荐阅读