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;
}