ESP8266 PubSubClient disconnecting when using with NeoPixel show() in loop

Hello,
I'm working on a little project, where i can control my LED Strips over MQTT (with animations).
Every 20 milliseconds strip.show() gets called and everything works great with receiving commands.
But after a few seconds (~30) the connection to the broker fails and it tries to reconnect but everytime it fails (this doesn't happen without strip.show()). I tested the WiFi connection but everytime it tries to reconnect the WiFi connection seems ok.

When I call strip.show() on a single command coming via mqtt everything's fine.

Almost everytime I managed to debug my code but this time i just wanna shoot myself pls help!

Here's the simplified code:

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "classes.h"

byte counter = 0;

// Update these with values suitable for your network.

const char* ssid = "XYZ";
const char* password = "PeterLustig";
const char* mqtt_server = "192.168.178.109";

Adafruit_NeoPixel tableStrip = Adafruit_NeoPixel(PIXNUMPC, D8, NEO_GRB + NEO_KHZ800);

pcController konrad(D5, D6);

rgbController tableCtrl(&tableStrip);

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;


void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  tableStrip.begin();

  for(int i = 0; i < PIXNUMPC; i++) {
    tableStrip.setPixelColor(i,0,0,0);
  }

  tableStrip.show();
}

void setup_wifi() {

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

  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("] ");
  String payloadStr = "";
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    payloadStr += (char)payload[i];
  }
  Serial.println();

  String topicStr = String(topic);

  // Switch on the LED if an 1 was received as first character
 if(topicStr=="smartHome/tableStrip") {
    byte stCommaIndex = payloadStr.indexOf(",");
    byte ndCommaIndex = payloadStr.indexOf(",", stCommaIndex + 1);
    byte r =payloadStr.substring(rgbStart,stCommaIndex).toInt();
    byte g =payloadStr.substring(stCommaIndex+1, ndCommaIndex).toInt();
    byte b =payloadStr.substring(ndCommaIndex+1).toInt();
    for (int i = 0; i < PIXNUMPC; i++) {
      tableStrip.setPixelColor(i, r, g, b);
    }
    tableStrip.show();

    if(r>0 || g>0 || b>0) {
      tableStripState = "on";
      client.publish("smartHome/tableStripResponse", "on");
    } else {
      tableStripState = "off";
      client.publish("smartHome/tableStripResponse", "off");
    }
  } else if(topicStr=="smartHome/devices" && payloadStr=="status") {
    String konradTopicMsg = String("smartHome/KonradPC:") + konrad.pcState;
    char konradTopicMsgAr[50];
    konradTopicMsg.toCharArray(konradTopicMsgAr, sizeof(konradTopicMsgAr));
    Serial.println(konradTopicMsgAr);
    
    String tableStripTopicMsg = String("smartHome/tableStrip:") + String(tableStripState);
    char tableStripTopicMsgAr[50];
    tableStripTopicMsg.toCharArray(tableStripTopicMsgAr, sizeof(tableStripTopicMsgAr));
    Serial.println(tableStripTopicMsgAr);

    String couchStripTopicMsg = String("smartHome/couchStrip:") + String(couchStripState);
    char couchStripTopicMsgAr[50];
    couchStripTopicMsg.toCharArray(couchStripTopicMsgAr, sizeof(couchStripTopicMsgAr));
    Serial.println(couchStripTopicMsgAr);
    
    client.publish("smartHome/devices", konradTopicMsgAr);
    client.publish("smartHome/devices", tableStripTopicMsgAr);
    client.publish("smartHome/devices", couchStripTopicMsgAr);

    if (konrad.pcState=="off") {
      client.publish("smartHome/devices", "smartHome/KonradPC:off");
    }
  } else if(topicStr=="smartHome/KonradPC" && payloadStr=="on") {
      konrad.pcState = "on";
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    int connectResult = WiFi.waitForConnectResult();
    Serial.println(connectResult);
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266...", "username", "password")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.subscribe("smartHome/KonradMonitor");
      client.subscribe("smartHome/KonradPC");
      client.subscribe("smartHome/tableStrip");
      client.subscribe("smartHome/devices");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

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

    tableCtrl.pixelColor(2, 12, counter, 10, 20);
    counter++;
    tableCtrl.paint();
  }
}

Here's the code from classes.h and classes.cpp

###classes.h###

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

#ifndef classes_h
#define classes_h

typedef struct {
	uint8_t r;
	uint8_t g;
	uint8_t b;
	uint8_t fadespeed;
	uint8_t fadevalue;
  bool fadeup;
} rgbcanvas;

class pcController {

  private:
    bool shouldStartPC;
    long pcStartActivated;
    byte pcPin, monitorPin;

  public:
    String pcState, monitorState;

    pcController(byte givenPCPin, byte givenMonitorPin);

    void
      startPC(),
      startMonitor(),
      shutdownMonitor(),
      run();
};

class rgbController {
  public:
    rgbController(Adafruit_NeoPixel*);
    rgbcanvas* _canvas;
    Adafruit_NeoPixel* _strip;
    unsigned long exec;

    void
      paint(void),
      pixelColor(int pixel, int pixelTo, byte r, byte g, byte b),
      run(void);
};

#endif


###classes.cpp###
#include "classes.h"
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>


pcController::pcController(byte givenPCPin, byte givenMonitorPin) {
    pcPin = givenPCPin;
    monitorPin = givenMonitorPin;

    shouldStartPC = false;
    pcStartActivated = 0;
    pcState = "off";
    monitorState = "on";
};

void pcController::startPC() {
    shouldStartPC = true;
};

void pcController::startMonitor() {
    digitalWrite(monitorPin, LOW);
    monitorState = "on";
};

void pcController::shutdownMonitor() {
    digitalWrite(monitorPin, HIGH);
    monitorState = "off";
};

void pcController::run() {
    if(shouldStartPC && pcState == "off") {
        if(pcStartActivated == 0) {
            digitalWrite(pcPin, HIGH);
            digitalWrite(monitorPin, LOW);
            pcStartActivated = millis();
        } else if((pcStartActivated + 1000) < millis()) {
            monitorState = "on";
            pcState = "on";
            digitalWrite(pcPin, LOW);
            pcStartActivated = 0;
            shouldStartPC = false;
        }
    } else if(shouldStartPC && pcState == "on") {
        digitalWrite(monitorPin, LOW);
        shouldStartPC = false;
    }
};


rgbController::rgbController(Adafruit_NeoPixel* strip) {
    _strip = strip;
    _canvas = (rgbcanvas*)calloc(strip->numPixels(), sizeof(rgbcanvas));
    exec = 0;
};

void rgbController::paint() {
    for(int i = 0; i < _strip->numPixels(); i++) {
        _strip->setPixelColor(i, _canvas[i].r, _canvas[i].g, _canvas[i].b);
    }
    _strip->show();
};

void rgbController::pixelColor(int pixel, int pixelTo, byte r, byte g, byte b) {
    for(int i = pixel; i <= pixelTo; i++) {
        _canvas[i].r = r;
        _canvas[i].g = g;
        _canvas[i].b = b;
    }
}

void rgbController::run() {
    if((exec+20)<millis()) {
        paint();
        exec=millis();
    }

    if(exec>millis()+1) exec=0;
}

powering issue

Hmmm it has the same problem and i have my 5v 26A power supply connected but i noticed something... the chip doesn't power when i only plug the power supply to vin and gnd - only when i plug usb into it.
I ordered a new chip maybe its a problem of the chip.

Thanks for the answer if it doesn't work with the new one, i'll reply in this thread

on some NodeMcu and Wemos models you can't supply power over Vcc. It is not Vin.

Oh damn sorry i meant vin not vcc sorry

Juraj:
powering issue

Ok i got another ESP8266 and uploaded the sketch but the issue is still there. The board is fully powered through my 26A power supply and the strip too. The chip works fine without usb powering. Any idea, what it could be?

what esp8266 board? "The chip works fine without usb powering."?

I found the problem. instead of calling rgbController.run(), which executes strip.show() every 20 ms, i called rgbController.paint(), which executes strip.show() constantly.

Thank you so much for helping, even if your solution didn't helped, you helped me not giving up.
Have a nice day!