一、MQTT协议

MQTT 协议的全称是 Message Queuing Telemetry Transport,翻译为消息队列传输探测,它是 ISO 标准下的一种基于发布 - 订阅模式的消息协议,它是基于 TCP/IP 协议簇的,它是为了改善网络设备硬件的性能和网络的性能来设计的。MQTT 一般多用于 IoT 即物联网上,广泛应用于工业级别的应用场景,比如汽车、制造、石油、天然气等。

这种订阅类的协议很新颖,客户端只需要订阅服务器的消息即可;无需重复的去请求接口获取信息,在物联网方面的应用比较常见;然后我就翻出了我的ESP8266和温度传感器(DHT11);

image-20230301201933642

二、实战

1、环境搭建

一如既往的使用arduino作为开发的,通过官网[Software | Arduino](https://www.arduino.cc/en/software下载按照后即可得到一个编译器;安装好对于的驱动和在arduino中设置开发板后即可进行开发步骤;

计算机管理->设备过管理器中可以看到esp8266的端口号;

image-20230301205646092

在arduino中开发板设置中选择相应的开发板,我选择的是“NodeMCU 1.0”(NodeMCU-12E和NodeMCU-12F没有太大的区别)

image-20230301205920015

并在端口处设置好刚才在设备管理器中看到的端口号:

image-20230301210101854

接下来就可以开始愉快的开发过程了;

2、代码开发

首先上网是关键,所以先让他连上网

#include<stdio.h>
#include <ESP8266WiFi.h>

const char* ssid = "WiFi-12-1";
const char* password = "********";

void setup() {
Serial.begin(9600);

//设置ESP8266工作模式
WiFi.mode(WIFI_STA);
// 连接WiFi
Wifi();
}

void loop() { 
}

// ESP8266连接wifi
void Wifi(){
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
 delay(1000);
 Serial.print(".");
}
Serial.println("");
Serial.println("Successfully connected to WIFI");  
Serial.println(""); 
}

联网成功后提示:

image-20230301213357882

测试mqtt通讯,我这里使用的是公共的服务器:免费的公共 MQTT 服务器 | EMQ (emqx.com)

测试使用可以,但别使用在真实的生产中;

#include<stdio.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "WiFi-12-1";
const char* password = "18084486541";
const char* mqttServer = "broker-cn.emqx.io";
int tim = 0;
int timax = 60;

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

void setup() {
Serial.begin(9600);

//设置ESP8266工作模式
WiFi.mode(WIFI_STA);
// 连接WiFi
Wifi();

// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
// 连接MQTT服务器
 connectMQTTServer();
mqttClient.setCallback(callback);// 设置回调
}

void loop() { 
 if (mqttClient.connected()) {  
 mqttClient.loop();          // 保持客户端心跳
} else {                 
 connectMQTTServer();    // 则尝试重新连接服务器
}
}

// 连接MQTT服务器
void connectMQTTServer(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "C3ting-" + WiFi.macAddress();

if (mqttClient.connect(clientId.c_str())) { //设置mqtt主题的id
 //连接成功后就订阅主题
 mqttClient.subscribe("c3ting");//订阅主题
 Serial.print("订阅主题成功!!");
} else {
 Serial.println(mqttClient.state());
 delay(3000);
}   
}
//MQTT回调函数
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");

for (int i=0;i<length;i++) {
char receivedChar = (char)payload[i];
Serial.print(receivedChar); // 打印mqtt接收到消息
}
Serial.println();
}
// ESP8266连接wifi
void Wifi(){
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
 delay(1000);
 Serial.print(".");
}
Serial.println("");
Serial.println("Successfully connected to WIFI");  
Serial.println(""); 
}

使用MQTT测试工具测试:

image-20230301215839322

接下来就是把获取温度传感器的数据上传到MQTT服务器上:

传感器与ESP8266的连线为:

传感器: esp8266:

+(电源)————3v

-(电源)————G

out(信号)————3V

即可

#include<stdio.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <dht11.h>

dht11 DHT11;
#define DHT11PIN 2
const char* ssid = "WiFi-12-1";
const char* password = "18084486541";
const char* mqttServer = "broker-cn.emqx.io";
int tim = 0;
int timax = 60;

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

double Fahrenheit(double celsius)
{
return 1.8 * celsius + 32; //摄氏温度度转化为华氏温度
}

double Kelvin(double celsius)
{
return celsius + 273.15; //摄氏温度转化为开氏温度
}

void setup() {
Serial.begin(9600);

//设置ESP8266工作模式
WiFi.mode(WIFI_STA);
// 连接WiFi
Wifi();

// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
// 连接MQTT服务器
 connectMQTTServer();
mqttClient.setCallback(callback);// 设置回调
}

void loop() { 
 if (mqttClient.connected()) {  
 mqttClient.loop();          // 保持客户端心跳
} else {                 
 connectMQTTServer();    // 则尝试重新连接服务器
}

DHT11.read(DHT11PIN); //更新传感器所有信息
tim++;
if(tim>=timax){
float temp = DHT11.humidity;
float hum = DHT11.temperature;
// json serialize
DynamicJsonDocument data(256);
data["temp"] = temp;
data["hum"] = hum;
// publish temperature and humidity
char json_string[256];
serializeJson(data, json_string);
sendMessage(json_string);
tim=0;
}
delay(1000);
}

// 连接MQTT服务器
void connectMQTTServer(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "C3ting-" + WiFi.macAddress();

if (mqttClient.connect(clientId.c_str())) { //设置mqtt主题的id
 //连接成功后就订阅主题
 mqttClient.subscribe("c3ting");//订阅主题
 Serial.print("订阅主题成功!!");
} else {
 Serial.println(mqttClient.state());
 delay(3000);
}   
}
//MQTT回调函数
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");

for (int i=0;i<length;i++) {
char receivedChar = (char)payload[i];
Serial.print(receivedChar); // 打印mqtt接收到消息
}
Serial.println();
}
//MQTT发送函数
void sendMessage(char* pubMessage){
if(mqttClient.publish("c3ting/send", pubMessage)){
 Serial.println("Publish Topic:c3ting");
 Serial.println("Publish message:");Serial.println(pubMessage);    
} else {
 Serial.println("Message Publish Failed."); 
}
}
// ESP8266连接wifi
void Wifi(){
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
 delay(1000);
 Serial.print(".");
}
Serial.println("");
Serial.println("Successfully connected to WIFI");  
Serial.println(""); 
}

上传测试连接情况:

image-20230301221507616

至此就差不多了;

MQTT的应用还是很多的的,也可以作为一个IM通讯服务器来使用。在推送信息等方面的应用还是比较好的,生态链也是很完整的,在js,java,python等语言上都支持这个协议;

这篇文章只是我的一个记录吧,在物联网板块中,我还只是小白,还在不断的学习中,如果有错误的地方还望多多包涵。