Search code examples
c++arduinomqttesp8266

client.subscribe() taking a long time (30-45 seconds) to receive messages


While working with Arduino MQTT client I observed that, when I am publishing to a topic, the messages are sent immediately to the broker. I confirmed this with the help of a mqtt.fx tool. While receiving messages from the broker for the same topic, I am getting the published messages after a long delay. I am using Mosquitto broker configured on Openhab 2.5

This is the code that I am using:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <SeeedOLED.h>

const char* ssid = "Network";
const char* password = "NetworkPass";

#define mqtt_server "OpenhabIP"

WiFiClient espClient;
PubSubClient client(espClient);

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client","user","pass")) {
      Serial.println("connected");
    }else{
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length){
  char k=(char)payload[0];
  if(k=='0'){
    SeeedOled.clearDisplay();          
    SeeedOled.setNormalDisplay();      
    SeeedOled.setPageMode();           
    SeeedOled.setTextXY(0, 0);         
    SeeedOled.putString("Magnet");
  }else{
    SeeedOled.clearDisplay();          
    SeeedOled.setNormalDisplay();      
    SeeedOled.setPageMode();           
    SeeedOled.setTextXY(0, 0);         
    SeeedOled.putString("No Magnet");
  }
}

void setup()
{
  pinMode(15, OUTPUT); //To enable Wio Link Board
  digitalWrite(15, 1);
  Serial.begin(9600);
  Wire.begin(4,5);
  SeeedOled.init();
  WiFi.begin(ssid, password);
  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqtt_server,1883);
  pinMode(3, INPUT); //Enable Input for hall sensor
  client.setCallback(callback);
}

void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  client.publish("EntComp/HallSensor",String(digitalRead(3)).c_str(),true);
  client.subscribe("EntComp/HallSensor");
  delay(1000);
}

I have done this all on a Wio Node development board which is based on a ESP8266-12E module. I am facing the same issue when using the client.subscribe() and client.publish() functions on different boards. I am not able to understand why there is such a huge delay. Is it because of an error within the code or am I doing something wrong?


Solution

  • You have the "huge" delay in your code (loop):

       delay(1000);
    

    This stops processing for 1 second in each loop cycle so if it needs ten cycles to process something its 10 useless seconds your CPU waits in total. See blinkwithoutdelay Example in ArduinoIDE how to wait e.g. for one second before reentering a routine, without blocking other active (sub)routines. In communication based programs the "old" saying "Never use delay" is 100% true.
    Get also rid of the

     delay(5000);
    

    in the reconnect routine as a good exersise.
    For the wise guys here: Yes I know
    A delay during setup (which only runs once) is when used carefully and deliberatly not that bad.