256dpi / arduino-mqtt

MQTT library for Arduino
MIT License
1.02k stars 236 forks source link

Encountering timeout issues / broken connections #213

Closed patrickjane closed 4 years ago

patrickjane commented 4 years ago

Hello,

I am using this MQTT library on a Arduino UNO WiFi Rev.2. I am following more or less the example code, however I am running into issues with timeouts and broken connections. The arduino connects to the MQTT server on startup and subscribes to two topics. If I just leave it running like this, without any additional code of mine beeing executed, I get disconnects/reconnects every couple of seconds/minutes.

In addition, I am using a motor shield to drive a motor, which also connects its encoder interrupt output to the arduino. The goal is to trigger the motor via MQTT messages. If, after a message was received, the motor starts to spin (and lots of interrupts are fired by the motors encoder), the MQTT connection gets lost.

Is there anything I can do about this?

Here is my code:

// ************************************************************************************
// Setup
// ************************************************************************************

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

  connectWIFI();

  client.begin(broker, port, wifiClient);
  client.setOptions(2, true, 15000);
  client.onMessageAdvanced(onMessageReceived);

  connectMQTT();
}

// ************************************************************************************
// Loop
// ************************************************************************************

void loop()
{
  if (WiFi.status() == 3)
  {
    client.loop();

    if (!client.connected())
    {
      Serial.println("[MQTT] Connection lost, trying to reconnect ...");
      connectMQTT();
    }    
  }
  else
  {
    Serial.println("[WIFI] Connection lost, trying to reconnect ...");

    disconnectWIFI();
    connectWIFI();
  }
}

// ************************************************************************************
// connect/disconnect WIFI
// ************************************************************************************

int connectWIFI()
{
    // attempt to connect to Wifi network

  Serial.print("[WIFI] Connecting to network ");
  Serial.print(ssid);
  Serial.println(" ...");

  int dotsPrinted = 0;

  while (WiFi.begin(ssid, pass) != WL_CONNECTED) 
  {
    // failed, retry
    Serial.print(".");
    dotsPrinted++;
    delay(1000);
  }

  if (dotsPrinted)
    Serial.print("\n[WIFI] Connected to network ");
  else
    Serial.print("[WIFI] Connected to network ");

  Serial.println(ssid);
  return 0;
}

int disconnectWIFI()
{
  WiFi.disconnect();
}

// ************************************************************************************
// connect/disconnect MQTT
// ************************************************************************************

int connectMQTT() 
{
  Serial.print("[MQTT] Connecting to host ");
  Serial.print(broker);
  Serial.println(" ...");

  while (!client.connect(clientIdentifier)) 
  {
    Serial.print(".");
    delay(1000);
  }

  Serial.println("[MQTT] Connected");

  int i = -1;

  while (topics[++i])
  {
    Serial.print("[MQTT] Subscribing to topic: ");
    Serial.println(topics[i]);

    // subscribe to a topic

    // client.unsubscribe(topics[i]);

    if (!client.subscribe(topics[i]))
    {
      Serial.println("[MQTT] Failed to subscribe, disconnecting ...");
      client.disconnect();
      return -1;
    }
  }

  return 0;
}

int disconnectMQTT()
{
  client.disconnect();
  return 0;
}

// ************************************************************************************
// onMessageReceived
// ************************************************************************************

void onMessageReceived(MQTTClient *client, char topic[], char payload[], int payload_length) 
{
  Serial.println("GOT MESSAGE");
  //dispatch(topic, payload);
}

// ************************************************************************************
// dispatch
// ************************************************************************************

void dispatch(const char* topic, const char* msg)
{
  Serial.print("Got message on topic: '");
  Serial.print(topic);
  Serial.println("'");

  if (!strcmp(topic, calibrateTopic))
  {
    motor.calibrate();
  }
  else if (!strcmp(topic, controlTopic))
  {
    if (!msg || !*msg || !isdigit(*msg))
      return;

    motor.goTo(atof(msg));
  }
}

Here is some example log output where the disconnects are visible:

12:57:18.095 -> [MQTT] Connected
12:57:18.095 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/control
12:57:18.095 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/calibrate
12:57:58.156 -> [MQTT] Connection lost, trying to reconnect ...
12:57:58.156 -> [MQTT] Connecting to host ceres.universe ...
12:57:58.156 -> [MQTT] Connected
12:57:58.156 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/control
12:57:58.156 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/calibrate
12:57:58.156 -> [MQTT] Connection lost, trying to reconnect ...
12:57:58.156 -> [MQTT] Connecting to host ceres.universe ...
12:57:58.156 -> [MQTT] Connected
12:57:58.156 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/control
12:57:58.156 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/calibrate
13:01:52.629 -> [MQTT] Connection lost, trying to reconnect ...
13:01:52.629 -> [MQTT] Connecting to host ceres.universe ...
13:01:52.629 -> [MQTT] Connected
13:01:52.629 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/control
13:01:52.629 -> [MQTT] Subscribing to topic: ha/rollerblind/bedroom/calibrate

It is not an issue with the WIFI as I am also tracking WIFI connectivity.

patrickjane commented 4 years ago

Please delete / ignore this issue. It was caused by a deadlock from systemcalls out of interrupt handlers on my side. I am sorry.