TransWikia.com

How to avoid MQTT reconnect Loop

Arduino Asked on February 15, 2021

I have the following code designed to allow me to control my device from my website using mqtt broker while internet is available. I also built in a local webserver to control the device in case of internet outage given I’m still connected to the same router my device is connected to.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

int ledPin = 2; 

const char* ssid = "SSID";
const char* password = "PASS";
const char* mqtt_server = "MQTTSERVER";
const char* mqtt_user = "MQTTUSER";
const char* mqtt_pass = "MQTTPASS";
const char* mqtt_topic = "topic";
String mqttpayload;

WiFiServer server(80);
WiFiClient espClient; 
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);  pinMode(ledPin, OUTPUT);  digitalWrite(ledPin, LOW);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print(".");  }  Serial.println("");
  
  Serial.print("Connected to WiFi");  
  
  client.setServer(mqtt_server, 1883);    server.begin();  
}

void loop() {
  client.setCallback(callback);
  reconnect();
  if ( mqttpayload == "OFF" ) {   digitalWrite(ledPin, HIGH); Serial.println("Switced OFF"); }
  if ( mqttpayload == "ON" ) {   digitalWrite(ledPin, LOW);  Serial.println("Switced ON"); }
  mqttpayload = "";


  WiFiClient cclient = server.available();
  if (!cclient) {  return;  }  while(!cclient.available()){  }
  String request = cclient.readStringUntil('r');  Serial.println(request);  cclient.flush();

  int value = HIGH;
  if (request.indexOf("/LED=ON") != -1)   { 
    digitalWrite(ledPin, LOW);    value = LOW;      Serial.println("Publish message: ON");    reconnect();  client.publish(mqtt_topic, "ON", true); 
  } 
  if (request.indexOf("/LED=OFF") != -1)  { 
    digitalWrite(ledPin, HIGH);   value = HIGH;     Serial.println("Publish message: OFF");    reconnect(); client.publish(mqtt_topic, "OFF", true); 
  }

  cclient.println("HTTP/1.1 200 OK");  
  cclient.println("Content-Type: text/html");  
  cclient.println(""); 
  cclient.println("<!DOCTYPE HTML>");  
  cclient.println("<html>");  
  cclient.print("LED status: "); 
  
  if(value == HIGH) {    cclient.print("OFF");  } else {    cclient.print("ON");  }
  cclient.println("<br><br>");  
  cclient.println("Turn <a href="/LED=ON">ON</a><br>");  
  cclient.println("Turn <a href="/LED=OFF">OFF</a><br>");  
  cclient.println("</html>");
  Serial.println("");  
}

void callback(char* topic, byte* payload, unsigned int length) {
  for (int i = 0; i < length; i++) {     mqttpayload += (char)payload[i]; }
}

void reconnect() { 
  if (!client.connected()) { 
    while (!client.connected()) { 
      Serial.print("MQTT..");  
      if (client.connect("2021", mqtt_user, mqtt_pass)) { 
        Serial.println("MQTT connected");        client.subscribe(mqtt_topic);   
      } else { error(); } 
    }  
  }  
  client.loop(); 
}

void error() {  Serial.print("failed, rc=");      Serial.print(client.state());      Serial.println(" try again in 5 seconds");      delay(5000);   }

The problem lies when I test it while connected to my router with no internet. The code loops trying to connect to MQTT server and get stuck which doesn’t allow me to send local HTTP requests.

I tried modifying the MQTT reconnect loop to the one below, which solves the problem but introduces another issue which is delaying the HTTP requests up to 6-9 seconds.

void reconnect() { 
 if (client.connect("2021", mqtt_user, mqtt_pass)) { 
  Serial.println("MQTT connected");
  client.subscribe(mqtt_topic);   
 } else { error(); }
 client.loop(); 
}

So the question here, what should I do to get around this issue?

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP