knolleary / pubsubclient

A client library for the Arduino Ethernet Shield that provides support for MQTT.
http://pubsubclient.knolleary.net/
MIT License
3.78k stars 1.46k forks source link

Library when subscribing to third topic won't connect to ethernet #1040

Open vidpesko opened 5 months ago

vidpesko commented 5 months ago

In my reconnect function, I am calling subscribe method of PubSubClient three times to subscribe to every topic for controlling my WS2812b Led strip. When i call it the third time, my code won't connect and i will get Library State Code = -2 (CAN'T CONNECT TO ETHERNET). But as soon I comment thrid subscribe call, my code works.

Device info:

My Reconnect function

void reconnect()
{
  while (!client.connected())
  {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("aarduinoClient"))
    {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("vid@pesko.si/peskohome/livingroom/stenge/data", "hello world");
      // ... and resubscribe
      client.subscribe("vid@pesko.si/peskohome/livingroom/stenge/edit/state");
      client.subscribe("vid@pesko.si/peskohome/livingroom/stenge/edit/color");

      // If i comment this tird call to subcribe, usually my code will run !!!! ?????
      client.subscribe("vid@pesko.si/peskohome/livingroom/stenge/edit/brightness");
    }
    else
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

And my code

#include <Arduino.h>
#include <SPI.h>

#include <EthernetENC.h>
#include <PubSubClient.h>
#include <FastLED.h>

// ! Web properties:
IPAddress ip( MY IP ADDRESS ); // ? Static Local IP Address
byte mac[] = {0x74, 0x69, 0x69, 0x2D, 0x30, 0x31};

EthernetClient ethClient;
PubSubClient client(ethClient);

// ! WS2812b Led Lights properties
#define NUM_LEDS 4
#define DATA_PIN 4

CRGB leds[NUM_LEDS];

bool state = true;
char color[8] = "#FF0000";

// This function is called every time you receive property update via mqtt
void updateProperties()
{
  // Updating state
  if (state)
  {
    Serial.println(color);
    leds[0] = CRGB::Red;
  }
  else
  {
    leds[0] = CRGB::Black;
  }

  FastLED.show();
}

// You have received command - execute it
void callback(char *topic, byte *payload, unsigned int length)
{
  // Displaying message and topic
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // If topic is equal to STATE_TOPIC
  if (!strcmp(topic, "vid@pesko.si/peskohome/livingroom/stenge/edit/state"))
  {
    // ? strncmp() = strcmp(), but only n-characters will be compared
    // If payload is on
    if (!strncmp((char *)payload, "on", length))
    {
      state = true;
    }
    // else if payload is off
    else if (!strncmp((char *)payload, "off", length))
    {
      state = false;
    }
  }

  // If you receive color change
  else if (!strcmp(topic, "vid@pesko.si/peskohome/livingroom/stenge/edit/color"))
  {
    memcpy(color, payload, length);

    color[length] = '\0';
  }

  updateProperties();
}

// If client drops connection to the broker, RUN this function UNTIL it is connected == BLOCKING CALL
void reconnect()
{
  while (!client.connected())
  {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("aarduinoClient"))
    {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("vid@pesko.si/peskohome/livingroom/stenge/data", "hello world");
      // ... and resubscribe
      client.subscribe("vid@pesko.si/peskohome/livingroom/stenge/edit/state");
      client.subscribe("vid@pesko.si/peskohome/livingroom/stenge/edit/color");

      // If i comment this tird call to subcribe, usually my code will run !!!! ?????
      client.subscribe("vid@pesko.si/peskohome/livingroom/stenge/edit/brightness");
    }
    else
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(9600);
  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("LED Stenge - Project by Vid Pesko");

  // Connect to broker
  client.setServer("broker.emqx.io", 1883);
  client.setCallback(callback);

  // Starting Ethernet connection
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware)
  {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true)
    {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF)
  {
    delay(500);
    if (Ethernet.linkStatus() == LinkOFF)
    {
      Serial.println("Ethernet cable is not connected.");
    }
  }

  Serial.print("Device IP is: ");
  Serial.println(Ethernet.localIP());

  // LED Lights Setup
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  // Add delay to allow for hardware to sort itself out
  delay(1500);
}

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

  client.loop();
}

My thoughts:

What could be the problem:

I have tried everything, changing the topic length, putting client.loop() between subscribe calls, but I can't solve it. Any help will be appreciated.