ESP32使用MQTT收发

简介

本文环境为:

单片机: ESP32
通讯协议: 串口通讯, MQTT, WIFI

所用库说明:

1 WiFi.h:这是一个ESP32开发板的WiFi库,用于连接WiFi网络。
2 PubSubClient.h:这是一个MQTT客户端库,用于连接MQTT代理并发布/订阅主题。
3 ArduinoJson.h:这是一个处理JSON数据的库,可以在ESP32上方便地解析和生成JSON数据。
4 Ticker.h:这是一个用于ESP32中的软件定时器库,可以在ESP32上运行回调函数。

实现功能:

●连接指定WIFI
●连接指定MQTT服务器
●发布唯一主题
●订阅唯一主题
●发布消息
●接受订阅消息
●收到主题"device/dev/1"的"ON"消息, 将LED2和D5设为高电平(开)
●收到主题"device/dev/1"的"OFF"消息, 将LED2设为低电平(关)
●(dev) 第一次启动必须将WIFI设置为特定名称和密码, 让ESP32连接WIFI, 然后通过MQTT设置自定义WIFI和密码, 一共两个WIFI和密码, 第一个可自定义, 第二个不可自定义, 以防丢失WIFI密码
●注: esp32本身可以当做WIFI去连接并控制

代码示例:

#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Ticker.h>


const int ledPin = 5; // D5针脚对应的数字编号
StaticJsonDocument<200> sensor_json; // JSON对象
String realmsg = ""; // 发布消息载体
int LED = 2;

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
// const char* ssid = "realme";
// const char* password = "12345678";
const char* mqttServer = "api.shuxinxin.top";//本机ip地址
//发布的消息字段
typedef struct {
  int msg1;
  int msg2;
  int msg3;
} msg;
int count = 0; //发布消息间隔
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
//------------------全局变量定义-----------------
msg mymsg = {123, 45, 6}; //定义消息结构体

Ticker ticker;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
//------------------全局变量定义-----------------
void tickerCount() 
{ //Ticker回调函数
  count++;
  //数据测试
  sensor_json["msg1"] = 12;
  sensor_json["msg2"] = 21;
  sensor_json["msg3"] = 98;
  serializeJson(sensor_json, realmsg);
}

void pubmsg( const String &topicString, const  String &messageString) 
{
  char publishTopic[topicString.length() + 1];
  strcpy(publishTopic, topicString.c_str());
  char publishMsg[messageString.length() + 1];
  strcpy(publishMsg, messageString.c_str());

  // 实现ESP8266向主题发布信息
  if (mqttClient.publish(publishTopic, publishMsg)) 
  {
    Serial.println("Publish Topic:"); Serial.println(publishTopic);
    Serial.println("Publish message:"); Serial.println(publishMsg);
  }
  else
  {
    Serial.println("Message Publish Failed.");
  }
}


void setup()
{
  pinMode(LED, OUTPUT);     // 设置板上LED引脚为输出模式
  pinMode(ledPin, OUTPUT); // 将D5针脚配置为输出模式
  digitalWrite(LED, LOW);  // 启动后关闭板上LED
  Serial.begin(9600);               // 启动串口通讯

  // Ticker定时对象
  ticker.attach(2, tickerCount); //每过2s调用其回调函数

  //设置ESP8266工作模式为无线终端模式
  // WiFi.mode(WIFI_STA);

  // 连接WiFi
  connectWifi();

  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  mqttClient.setCallback(receiveCallback);

  // 连接MQTT服务器
  connectMQTTserver();
}

void loop() 
{
  if (mqttClient.connected())
  { // 如果开发板成功连接服务器
    if (count >= 2) 
    {
      pubmsg("device/date", realmsg);
      realmsg = "";
      count = 0;
    }
    // mqttClient.loop();          // 处理信息以及心跳
  } 
  else 
  {                      // 如果开发板未能成功连接服务器
    connectMQTTserver();        // 则尝试连接服务器
  }
  mqttClient.loop();          // 处理信息以及心跳
}

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

  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str()))
  {
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address:");
    Serial.println(mqttServer);
    Serial.println("ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } 
  else 
  {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }
}


// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) 
{
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) 
  {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);
  int temp = 0;
  while (*topic) 
  {
    temp++;
    topic++;
  }
  Serial.println("主题长度:");
  Serial.println(temp);
  if (temp > 11) 
  {
    if ((char)topic[11] == '1') 
    {
      if ((char)payload[0] == 'O' && (char)payload[1] == 'F') 
      {     // 如果收到的信息以“1”为开始
        Serial.println("关灯");
        digitalWrite(LED, LOW);  // 则熄灭LED。
      } 
      else 
      {
        Serial.println("开灯");
        digitalWrite(LED, HIGH); // 否则亮LED。
        digitalWrite(ledPin, HIGH); // 输出高电平,点亮LED
      }
    }
  }
}


// 订阅指定主题
void subscribeTopic() 
{
  // 通过串口监视器输出是否成功订阅主题1以及订阅的主题1名称
  if (mqttClient.subscribe("device/dev/#")) 
  {
    Serial.println("Subscrib Topic:");
    Serial.println("device/action");
  } 
  else 
  {
    Serial.print("Subscribe Fail...");
  }
}


// ESP8266连接wifi
void connectWifi() 
{

  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(100);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");
  Serial.println("");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值