kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266
MIT License
1.6k stars 347 forks source link

Problem when connected with mqtt #346

Closed my-reminiscence closed 5 months ago

my-reminiscence commented 10 months ago

MQTT connects for a while but when it disconnects, it shows failed, rc=-2 error (Error code rc-2 is caused by a network error between the device and MQTT broker). When I comment ws2812fx.service(); in loop() then mqtt stays connected.

moose4lord commented 10 months ago

Elaborate on the hardware you're using and cut/paste your sketch.

my-reminiscence commented 10 months ago
  1. When I use the sketch without ws2812fx.service(); in loop() then everything works fine for several hours but when I include ws2812fx.service(); in loop() then MQTT disconnects after few minutes.
  2. Then it started to try reconnecting, after several minutes it says "MQTT!: Can't connect to broker after too many attempt, resetting WiFi".
  3. After several retries connecting with wifi, it reboots the device.
  4. I tried the same ESP01 and ESP12F.
moose4lord commented 10 months ago

Which MQTT library are you using? It would be nice to see your sketch, so that I can try to reproduce the problem on my end.

moose4lord commented 10 months ago

I haven't used MQTT for quite a while, so I installed Nick O’Leary's excellent PubSubClient library and added some WS2812FX code to it's mqtt_esp8622 example sketch. That seemed to work fine for me. I ran the sketch overnight and didn't see any dropped connections or crashes.

Maybe you could try my test sketch and see if that works for you.

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

#define LED_PIN   D2  // digital pin used to drive the LED strip
#define LED_COUNT  8  // number of LEDs on the strip

// Update these with values suitable for your network.

const char* ssid = "xxxxxxxx";
const char* password = "xxxxxxxx";
//const char* mqtt_server = "broker.mqtt-dashboard.com";
const char* mqtt_server = "broker.hivemq.com";  // public MQTT broker

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
int inTopicMsgCnt = 0;

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

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(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  inTopicMsgCnt++;
  // to reduce Serial Monitor clutter, disable printing a line every time a message is received
  // 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(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... 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);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);

  ws2812fx.init();
  ws2812fx.setBrightness(8);
  ws2812fx.setSegment(0, 0, LED_COUNT-1, FX_MODE_SCAN, BLUE, 1000);
  ws2812fx.start();

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  ws2812fx.service();

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

  unsigned long now = millis();
  if (now - lastMsg > 20000) {  // publish every 20 seconds
    lastMsg = now;

    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);

    Serial.print("inTopic message count: ");
    Serial.println(inTopicMsgCnt);
  }
}
my-reminiscence commented 10 months ago

I found that when I'm connecting with a mobile hotspot it's working fine but when I connect with a broadband (Airtel Fiber) router then it's occurring. I checked unique device id, client id, hostname but it's happening.

moose4lord commented 10 months ago

Hmmm...I vaguely remember reading about an issue with MQTT disconnect errors being caused DHCP's IP release/renew cycle. Can you try assigning your ESP8266 a static IP address and see if that helps?

moose4lord commented 5 months ago

This issues seems stale, so I'm closing. Reopen if you think it needs more attention.