Arduino UNO + ESP8266 + MQTT

Hi,

I am trying to connect to MQTT server using Arduino UNO with a Wifi Shield (ESP8266). I am able to connect to my Wifi successfully but, unsuccessful for MQTT. I am not sure where am I wrong

Logs at MQTT server tell a different story and says that the connection has been established.

2023-04-26T00:42:04: New client connected from 192.168.68.64:2845 as AquariumATO (p2, c1, k60).
2023-04-26T00:42:04: No will message specified.
2023-04-26T00:42:04: Sending CONNACK to AquariumATO (0, 0)
2023-04-26T00:42:11: Received DISCONNECT from AquariumATO
2023-04-26T00:42:11: Client AquariumATO disconnected.
2023-04-26T00:42:12: New connection from 192.168.68.64:48360 on port 1883.
2023-04-26T00:42:22: Received DISCONNECT from (null)
2023-04-26T00:42:22: Client <unknown> disconnected.
2023-04-26T00:42:26: New connection from 192.168.68.64:27055 on port 1883.
2023-04-26T00:42:26: New client connected from 192.168.68.64:27055 as AquariumATO (p2, c1, k60).
2023-04-26T00:42:26: No will message specified.
2023-04-26T00:42:26: Sending CONNACK to AquariumATO (0, 0)
2023-04-26T00:42:59: Client <unknown> has exceeded timeout, disconnecting.
2023-04-26T00:43:26: Client AquariumATO closed its connection.
2023-04-26T00:43:31: New connection from 192.168.68.64:37258 on port 1883.
2023-04-26T00:43:31: New client connected from 192.168.68.64:37258 as AquariumATO (p2, c1, k60).
2023-04-26T00:43:31: No will message specified.
2023-04-26T00:43:31: Sending CONNACK to AquariumATO (0, 0)
2023-04-26T00:43:40: Client AquariumATO closed its connection.

The Error is as below

00:48:36.989 ->  : mqtt_reconnect
00:48:36.989 -> Attempting MQTT connection...
00:48:37.054 -> [WiFiEsp] Connecting to 192.168.68.51
00:48:40.183 -> MQTT:Connecct command response::: 0
00:48:40.214 -> failed, rc=-2 try again in 5 seconds
00:48:49.181 -> [WiFiEsp] >>> TIMEOUT >>>
00:48:49.213 -> [WiFiEsp] Data packet send error (1)
00:48:49.245 -> [WiFiEsp] Failed to write to socket 3
00:48:53.197 -> [WiFiEsp] Disconnecting  3
00:48:53.229 ->  : mqtt_reconnect
00:48:53.262 -> Attempting MQTT connection...
00:48:53.294 -> [WiFiEsp] Connecting to 192.168.68.51
00:48:56.487 -> MQTT:Connecct command response::: 0
00:48:56.520 -> failed, rc=-2 try again in 5 seconds
00:49:05.498 -> [WiFiEsp] >>> TIMEOUT >>>
00:49:05.530 -> [WiFiEsp] Data packet send error (1)
00:49:05.563 -> [WiFiEsp] Failed to write to socket 3
00:49:09.543 -> [WiFiEsp] Disconnecting  3

Code used is as below

#include "WiFiEsp.h"
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial epsWifi(6, 7); // RX, TX
#endif

#define MQTT_KEEPALIVE 60

#include <PubSubClient.h>

char ssid[] = "SSID";            // your network SSID (name)
char pass[] = "PASSWORD";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

IPAddress mqtt_server = {192,168,68,51};
const int mqtt_port = 1883;
const char* mqtt_clientID = "AquariumATO";

const char* mqtt_publish_topic = "qiot/things/admin/ESP8266/button";
const char* mqtt_subscribe_topic = "qiot/things/admin/ESP8266/led";

void callback(char* topic, byte* payload, unsigned int length);

WiFiEspClient espClient;
// PubSubClient client(espClient);
PubSubClient client(mqtt_server, mqtt_port, callback, espClient);
boolean connectCommandStatus = false;
void setup() {
  // initialize serial for debugging
  Serial.begin(9600);
  epsWifi.begin(115200);
  connectToWifi();
  
  client.setKeepAlive(60);
  client.setSocketTimeout(60);
  
}

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++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // // Switch on the LED if an 1 was received as first character
  // if ((char)payload[0] == '1') {
  //   digitalWrite(LED_PIN, HIGH);   // Turn the LED on
  // } else {
  //   digitalWrite(LED_PIN, LOW);  // Turn the LED off
  // }

}


void publish(String topic, String payload)
{

    Serial.println(topic + " ====== " + payload);

    // Our payload may be too too long for a single publish() call, need to split
    int messageSize = payload.length();
    int leftToSend = messageSize;
    int offset = 0;

    // VT: NOTE: we don't want to set retain = true until the timestamp can be provided -
    // otherwise consumers might get quite confused
    client.beginPublish(topic.c_str(), messageSize, false);

    while (leftToSend > 0) {

        int packetSize = MQTT_MAX_PACKET_SIZE < leftToSend ? MQTT_MAX_PACKET_SIZE : leftToSend;
        leftToSend -= packetSize;
        String packet = payload.substring(offset, offset + packetSize);

        //Serial.printf("## size, packet/left %d, %d/%d\n", messageSize, packetSize, leftToSend);
        //Serial.printf("## packet: %s\n", packet.c_str());

        client.write((const uint8_t *)packet.c_str(), packetSize);

        offset += packetSize;
    }

    client.endPublish();
}

void reconnect() {
  // Loop until we're reconnected
  Serial.println("Attempting MQTT connection...");
  // Attempt to connect
  connectCommandStatus = client.connect(mqtt_clientID);
  Serial.print("MQTT:Connecct command response::: ");
  Serial.println(connectCommandStatus);
  if (connectCommandStatus) {
    Serial.println("MQTT:Connected");
    //Subscribe
    publish(mqtt_publish_topic, "Test" + String(millis()));
    connectCommandStatus = client.connected();
    Serial.print("Checking MQTT status now after connected::: ");
    Serial.println(client.connected());
    Serial.print("Checking MQTT status now after connected BOOL::: ");
    Serial.println(connectCommandStatus);

  } else {
    Serial.print("failed, rc=");
    Serial.print(client.state());
    Serial.println(" try again in 5 seconds");
    // Wait 5 seconds before retrying
    delay(5000);
  }
}

char msg[50];

void loop() {

  if (!client.connected()) {
    Serial.print(" : ");
    Serial.println("mqtt_reconnect");
    reconnect();
  }
  // print the network connection information every 10 seconds
  // client.loop();
  client.disconnect();
  
  // Serial.print(F("Publish message: "));
  // String msg_a = "{\"value\":"+ String(1) +"}";
  // msg_a.toCharArray(msg, 50);
  // Serial.println(msg);
  // //Publish
  // client.publish(mqtt_publish_topic, msg);
}


void connectToWifi() {
  // initialize ESP module
  WiFi.init(&epsWifi);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
  Serial.println("You're connected to the network");
}

Thank you in advance for your help

Software serial can not operate at that baud rate. use 9600

I recommend you to use my WiFiEspAT library.
https://github.com/JAndrassy/WiFiEspAT#getting-started

Have you ever searched for it on the internet? In the YT video is also a description. Alternatively, my tip would be to check the wifi connection or select a different IP. Have you also looked that they have set the correct password + username for the device?
As it seems to me, the device can not connect to the broker. The central error is actually:

Hi @blh64 My ESP operates at 115200, Also I am able to connect to Wifi, it's only the MQTT broker that I am unable to connect.

Just a clarification if baud rate was the problem will I still be able to connect to Wifi?

Hi @Juraj

Thank you for your reply. Do you. reckon the problem if with the Wifi library even though it is only the MQTT broker that I am unable to connect to?

Hi @cloudDev

Thanks for your response, yes I checked the errors, but my MQTT broker logs tell a different story which I have mentioned above. The MQTT broker is receiving the connection and also establishing a session.

This is why I am confused as to why this problem.

You mentioned select a different IP. Is this for ESP or for broker?
I am connecting as anonymous user, allow_anonymous is set to true on my MQTT broker. So credentials is not a problem.

IMO, doing it that way overcomplicates things. Why not dump the Uno and write the whole application on an ESP8266? Or, better yet, on an ESP32.

https://github.com/JAndrassy/WiFiEspAT#why-a-new-wifiesp-library <<<

Maybe I'm annoying with the list, but you could just work through each point and see if the problem is solved.

  1. you are using port 1883, do you have other devices connected to the broker? If so, they probably use port 1883 as well, so try to change it.
  2. is your mqtt_clientID correct? AquariumATO
  3. is the path correct? qiot/things/admin/ESP8266/button + qiot/things/admin/ESP8266/led
  4. [Most likely] Are you sending too much to the AquariumATO? You first send CONNACK to AquariumATO (0, 0) and then the connection breaks. What is CONNACK? Can the problem lie at this?

Hi All,

Thank you for your responses. I've been able to workout a solution. I was running a very old version of Firmware AT 1.2. After upgrading to AT 1.7.5, this is not an issue at all and works like a charm

If you have any further questions, feel free to get back to me!