周凯,个人博客

  • 前端
  • 嵌入式
  • 工具
  • 后端
  • 随笔
个人记录
  1. 首页
  2. 嵌入式
  3. arduino
  4. 正文

arduino 连接mqtt

2023年 8月 25日 901点热度 0人点赞 0条评论

代码

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 状态define
#define STATE_INIT  0
#define STATE_WIFI_CONNECTING 1
#define STATE_MQTT_CONNECTING 2
#define STATE_WORKING 3
#define STATE_MQTT_ERROR  4
#define STATE_WIFI_ERROR  5
//参数定义
//TODO:read from serial config
const char* ssid = "Xiaomi_53C8";
const char* password = "dka123456@";
const char* mqttServer = "emqx.start6.com";
const int mqttPort = 1883;
const char* mqttClient = "test123123";
const char* mqttUser = "mqtt";
const char* mqttPassword = "667f245d912a42139f285b0a0eba2df5";

//wifi client
WiFiClient espClient;
//mqtt client
PubSubClient client(espClient);
//状态参数
int workstate = STATE_INIT;

void setup() {
  // pinMode(LED_BUILTIN, OUTPUT);  // Initialize the LED_BUILTIN pin as an output
  Serial.begin(115200);
}

/*
主要根据状态进行各种操作:
INIT状态:检查参数配置,如果配置有错误,卡死,等待配置
wifi连接状态:connectwifi,如果连接失败,到wifi error状态(进行wifi断开或其他清理工作),
再回到init状态进行参数load和检查
mqtt连接状态:connectmqtt,如果连接失败,到mqtt error状态(进行mqtt断开或其他清理工作),
5次以后wifi重连,wifi失败后重新init
working状态:mqtt连接成功,errtimes清零,loop查看是否有mqtt下发消息,检测mqtt状态
wifi状态进行状态跳转。
*/
void loop() {
  int ret = 0;
  int mqtt_err_times = 0;

  serial_data_handle();

  switch(workstate){
    case STATE_INIT:
      if((ssid== "")||(password=="")){
          //error wifi args
          break;
      }
      if((mqttServer =="")||(mqttPort == 0)||(mqttUser=="")||(mqttPassword == "")){
        //error mqtt args  
        break;
      }
      workstate = STATE_WIFI_CONNECTING;
      break;
   case STATE_WIFI_CONNECTING:
      ret = wifi_connect();
      if(ret == 0){
        //connect success
        workstate = STATE_MQTT_CONNECTING;
      }else{
        //connect error
        workstate = STATE_WIFI_ERROR;
      }
      break;
   case STATE_MQTT_CONNECTING:
      ret = mqtt_connect();
      if(ret == 0){    
        // control temp
        client.subscribe("closeValue");
        mqtt_err_times = 0;
        workstate = STATE_WORKING;
      }else{
        //connect error
        workstate = STATE_MQTT_ERROR;
      }
      break;
   case STATE_WORKING:
      client.loop();
      if (!client.connected()) {
        if(WiFi.status() != WL_CONNECTED){
          workstate = STATE_WIFI_ERROR;  
        }else{
          workstate = STATE_MQTT_ERROR;
        }
      }
      //Serial.println("state:%d",client.state());
      break;
   case STATE_MQTT_ERROR:
      mqtt_err_times++;
      if(mqtt_err_times>=5){
        //reconnect wifi
        mqtt_err_times = 0;
        workstate = STATE_WIFI_ERROR;
      }else{
        workstate = STATE_MQTT_CONNECTING;
      }
      break;
   case STATE_WIFI_ERROR:
      //wifi disconnect 
      workstate = STATE_INIT;
      break;
   default:
      workstate = STATE_INIT;
      break;
  }   
}

int wifi_connect(void)
{
  int retry_times = 0;

  WiFi.begin(ssid,password);

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
    retry_times++;
    if(retry_times>=10){
        Serial.print("Wifi Connect timeout");
        Serial.println();
        return -1;
    }
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());

  return 0;
}

int mqtt_connect()
{
  int retry_times = 0;

  client.setServer(mqttServer,mqttPort);
  client.setCallback(callback);

  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");
    if (client.connect(mqttClient, mqttUser, mqttPassword)) {
      Serial.println("connected");  
      break;
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      retry_times++;
      if(retry_times>=10){
        return -1;  
      }
      delay(500);
    }
  }
  return 0;
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
  Serial.print((char)payload[i]);
  }
  Serial.println("-----------------------");
}

void serial_data_handle()
{
  //todo:read serial datas config or send to server
  //Serial read
}

参考

  • 物联网开发——使用Arduino IDE开发ESP8266添加MQTT - 知乎 (zhihu.com)

🎯 拓展阅读提示

本文涉及的内容已同步至公众号后台,我会在那里分享更多深度内容和实用技巧

→ 点击关注:一行梦境

公众号二维码
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2023年 8月 25日

周凯

这个人很懒,什么都没留下

打赏 点赞
< 上一篇

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2022-现在 周凯,个人博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蒙ICP备18004897号