Hey guys,
I got this code running on my old setup with blynk. Now I switched to MQTT with Node-RED and so on.
If I start any effect (only 3 effects are possible with analog LEDs xD) except the rainbow it is running as expected. A few miliseconds after starting the rainbow my Wemos D1 Mini R2 freezes ![]()
Is there a better way to cycle smoothly through the colours then I did?
The rainbow effect is at the bottom. The LED_effect Timer is only active if a switch in Node-RED is switched to "on" (true). And the LED_effect time checks the variable "effect" and starts the choosen effect.
#include <pfodBufferedStream.h>
#include <loopTimer.h>
#include <millisDelay.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <SimpleTimer.h>
#define BAUD_RATE 115200
const size_t bufSize = 130;
uint8_t buf[bufSize];
pfodBufferedStream bufferedStream(BAUD_RATE, buf, bufSize, false);
const char* mqttServer = "BrokerIP";
const int mqttPort = 1883;
const char* mqttUser = "USER";
const char* mqttPassword = "PASSWORD";
WiFiClient espClient;
PubSubClient client(espClient);
char msg[50];
unsigned long now, time_now = 0;
unsigned long lastReconnectAttempt = 0;
unsigned long period = 50;
// LED Stuff
void LED_effect();
void Rainbow();
void OneHourLater(byte, byte, byte, unsigned long);
void clearStrip();
int Rpin = 5;
int Gpin = 14;
int Bpin = 12;
int r, g, b;
int red, green, blue;
byte effect = 1;
bool stopEffect;
bool LEDswitch = false;
bool firststartRB = true;
bool debug = false;
// Timer
SimpleTimer timer;
int LED_effect_timerID;
void pdelay(unsigned long);
millisDelay mqttDelay;
void setup() {
Serial.begin(BAUD_RATE);
Serial.println();
for (int i = 5; i > 0; i--) {
Serial.println(i);
delay(500);
}
Serial.println();
bufferedStream.connect(&Serial);
pinMode(Rpin, OUTPUT);
pinMode(Gpin, OUTPUT);
pinMode(Bpin, OUTPUT);
LED_effect_timerID = timer.setInterval(1 * 1000L, LED_effect);
WiFiManager wifiManager;
//wifiManager.resetSettings();
wifiManager.autoConnect("ESP8266");
bufferedStream.println("Connected.");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
bufferedStream.println("Connecting to MQTT...");
if (client.connect("ESP-Buero2", mqttUser, mqttPassword )) {
bufferedStream.println("connected");
} else {
bufferedStream.print("failed with state ");
bufferedStream.print(client.state());
delay(2000);
}
}
client.publish("esp/bueroB/status", "connected");
client.publish("esp/bueroB/status", "first time");
client.publish("esp/bueroB/led", "false");
client.publish("esp/bueroB/effect", "effect1");
client.publish("esp/bueroB/period", String(period).c_str(), true);
client.subscribe("esp/bueroB/led");
timer.disable(LED_effect_timerID);
}
void callback(char* topic, byte* payload, unsigned int length) {
bufferedStream.print("Message arrived ["); bufferedStream.print(topic); bufferedStream.print("] ");
char msg[length + 1];
for (int i = 0; i < length; i++) {
msg[i] = (char)payload[i];
}
msg[length] = '\0';
bufferedStream.println(msg);
String LEDmsg = msg;
if (LEDmsg.indexOf('a') >= 20) {
int R_1 = LEDmsg.indexOf(':') + 1;
int R_2 = LEDmsg.indexOf(',');
int G_1 = LEDmsg.indexOf(':', R_1) + 1;
int G_2 = LEDmsg.indexOf(',', R_2 + 1);
int B_1 = LEDmsg.indexOf(':', G_1) + 1;
int B_2 = LEDmsg.indexOf(',', G_2 + 1);
red = LEDmsg.substring(R_1, R_2).toInt();
green = LEDmsg.substring(G_1, G_2).toInt();
blue = LEDmsg.substring(B_1, B_2).toInt();
bufferedStream.print("Red: "); bufferedStream.print(red);
bufferedStream.print(" - Green: "); bufferedStream.print(green);
bufferedStream.print(" - Blue: "); bufferedStream.println(blue);
} else if (LEDmsg.indexOf('e') == 0) {
if (effect != LEDmsg.substring(6).toInt()) {
effect = LEDmsg.substring(6).toInt();
}
if (LEDswitch) {
timer.enable(LED_effect_timerID);
}
} else if (strcmp(msg, "false") == 0) {
LEDswitch = false;
stopEffect = true;
clearStrip();
} else if (strcmp(msg, "true") == 0) {
LEDswitch = true;
if (effect > 2) {
effect = 1;
}
timer.enable(LED_effect_timerID);
} else {
period = LEDmsg.toInt();
bufferedStream.print("New Delay: "); bufferedStream.println(period);
}
}
boolean reconnect() {
if (client.connect("ESP-Buero2", mqttUser, mqttPassword )) {
client.publish("esp/bueroB/status", "connected");
client.subscribe("esp/bueroB/led");
}
return client.connected();
}
void mqttConnection() {
if (!client.connected()) {
mqttDelay.start(5000);
client.publish("esp/bueroB/status", "disconnected");
if (mqttDelay.justFinished()) {
if (reconnect()) {
mqttDelay.stop();
}
}
} else {
client.loop();
}
}
void pdelay(unsigned long milli)
{
unsigned long end_time = millis() + milli;
while (millis() < end_time) {
yield();
}
}
void loop() {
timer.run();
bufferedStream.available();
mqttConnection();
if (debug) {
loopTimer.check(&bufferedStream);
}
}
/********************* LED Stuff ***********************/
void LED_effect() {
bufferedStream.print("Effect: "); bufferedStream.println(effect);
if (effect == 1) {
setAll(red, green, blue);
} else if (effect == 2) {
stopEffect = false;
Rainbow();
} else if (effect == 3) {
OneHourLater(random(255), random(255), random(255), period * 15);
OneHourLater(0, 0, 0, period);
} else if (effect == 4) {
OneHourLater(255, 0, 0, period * 15);
OneHourLater(0, 0, 0, period * 15);
}
}
void setAll(byte r, byte g, byte b) {
analogWrite(Rpin, r);
analogWrite(Gpin, g);
analogWrite(Bpin, b);
}
void clearStrip() {
timer.disable(LED_effect_timerID);
setAll(0, 0, 0);
bufferedStream.println("Clear Strip");
}
void Rainbow() {
if (firststartRB) {
bufferedStream.println("RainbowLoop started");
firststartRB = false;
for (int k = 0; k <= 255; k++) {
r = k; //rot nimmt ZU
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (!stopEffect) {
for (int k = 0; k <= 255; k++) {
g = k; //grün nimmt ZU
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (!stopEffect) {
for (int k = 255; k >= 0; k--) {
r = k; //rot nimmt AB
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (!stopEffect) {
for (int k = 0; k <= 255; k++) {
b = k; //blau nimmt ZU
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (!stopEffect) {
for (int k = 255; k >= 0; k--) {
g = k; //grün nimmt AB
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (!stopEffect) {
for (int k = 0; k <= 255; k++) {
r = k; //rot nimmt ZU
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (!stopEffect) {
for (int k = 255; k >= 0; k--) {
b = k; //blau nimmt AB
setAll(r, g, b);
pdelay(period);
if (effect != 2) {
stopEffect = true;
break;
}
}
}
if (stopEffect) {
bufferedStream.println("RainbowLoop stopped");
r, g, b = 0;
clearStrip();
firststartRB = true;
}
}
void OneHourLater(byte r, byte g, byte b, unsigned long sDelay) {
setAll(r, g, b);
pdelay(sDelay);
}

