Arduino Client Disconnects After A Few Seconds

I have successfully gotten my openHAB item to communicate with my MQTT broker and also my Arduino UNO is able to connect to my MQTT broker. My Arduino code only needs to subscribe to the topic “kitchen” connected to my broker as I want to use the condition of the item as a loop variable. I am unsure how to do this but I know it has something to do with the callback function and the payload. My other problem is that after my Arduino connects to the broker the broker logs say " Client Arduino-UNO had closed it’s connection" I know this is because of my void loop() function but I do not know what to do about it! Any help would be appreciated and my code can be found bellow!

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Function prototypes
void callback(char* topic, byte* payload, unsigned int length);
 
// Set your MAC address and IP address here
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 1);
 
// Make sure to leave out the http and slashes!
const char* server = "192.168.2.139";
 
// Ethernet and MQTT related objects
EthernetClient ethClient;
PubSubClient mqttClient(ethClient);

void setup() {
  // put your setup code here, to run once:
  
  // Useful for debugging purposes
  Serial.begin(9600);
  
  // Start the ethernet connection
  Ethernet.begin(mac, ip);              
  
  // Ethernet takes some time to boot!
  delay(3000);                          
 
  // Set the MQTT server to the server stated above ^
  mqttClient.setServer(server, 1883);   
 
  // Attempt to connect to the server with the ID "arduino-UNO"
  if (mqttClient.connect("arduino-UNO")) 
  {
    Serial.println("Connection Established To MQTT Broker!!!!!");
 
    // Establish the subscribe event
    mqttClient.setCallback(callback);

    // Ensure that we are subscribed to the topic "kitchen"
    mqttClient.subscribe("kitchen");
  } 
  else 
  {
    Serial.println("Connection Failed :(");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

  // This is needed at the top of the loop!
  mqttClient.loop();
 
  // Dont overload the server!
  delay(4000);
}

void callback(char* topic, byte* payload, unsigned int length)
{
  // Print the topic
  Serial.print("Topic: ");
  Serial.println(topic);
 
  // Print the message
  Serial.print("Message: ");
  for(int i = 0; i < length; i ++)
  {
    Serial.print((char)payload[i]);
  }
 
  // Print a newline
  Serial.println("");
}

Hello, are you using knolleary’s pubsubclient library ?
Try to comment the lines, it should be not necessary parameters for the library…

// Set your MAC address and IP address here
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 1);

I had disconnection issue when the Arduino board ID is not unique and brokes goes mad.

I am quite new to the topic of MQTT and Arduino so I built my code from this article ([https://www.digikey.ca/en/maker/blogs/2018/how-to-use-basic-mqtt-on-arduino]) and the Arduino client did not disconnect when using that code but when I removed the publish statement from the loop() it started to disconnect but I do not need to publish anything to the broker just receive information via subscribe which is found in my setup function.

I can confirm you that is the same library I use
PubSub Library

try to adapt these similar example (eliminate SDRAM part) and let me know…

there is another file in that link you previously sent called mqtt_basic.ino that does not use SDRAM but it uses a reconnect function which I have seen before but I do not know why it is necessary. I found this article that is interesting and close to what I need but it uses WIFI instead of Ethernet. ESP32: Subscribing to MQTT topic - techtutorialsx

I’m not 100% expert but I think it doesn’t matter if you use WiFi or Eth.
the important thing is to connect to your network.

When you start your board the first 3 main steps are:

  1. serial enable
  2. connection to the net (wifi or ethernet)
  3. connection to broker

these steps are in cascade…

I will share with you one of my simplest arduino sketch based on Nodemcu (same as arduino basically but with built-in wi-fi) in some hours, now I have not access to my PC.

These is my arduino domotique MQTT “skeleton” sketch
You have to replace <ESP8266WiFi.h> with an arduino equivalent library (i think ethernet.h or similar)

If you want to perform actions if received certain message on topic, search the if (message == "") inside callback function and adapt to your need. You can add as else if statement as you want

let me know if it works for you

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


// Update these with values suitable for your network.
char ssid[] = "YOUR_SSID";            // your network SSID (name)
char password[] = "YOUR_PASS";        // your network password
const char* mqtt_server = "SERVER_BROKER_IP";
const char* clientID = "UNIQUE_CLIENT ID";
const char* outTopic = "OUT_MESSAGE_TOPIC";
const char* inTopic = "IN_MESSAGE_TOPIC/#";
int status = WL_IDLE_STATUS;     // the Wifi radio's status

WiFiClient espClient;
PubSubClient client(espClient);
char msg[50];

void setup() {
  Serial.begin(9600);

  // initialize ESP module
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}


void loop() {
  
  delay(100);
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  //HERE YOUR SKETCH

}


void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void callback(char* topic, byte * payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  payload[length] = '\0';
  String message = String((char*)payload);

  Serial.println(message);

  if (String(topic) == inTopic) {
    if (message == "MESSAGE_TRIGGER") {
      
     }
  }
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(outTopic, clientID);
      // ... and resubscribe
      client.subscribe(inTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}