Led controller disconnects

hello. trying to understand why this sketch below does not want to be online. or frequent disconnections sometimes after five minutes or several hours.
the sketch controls a ring neopixelixel 16b led rgb with departure to daytime wanted. thanks for a help.translate with google

#include <ESP8266WiFi.h>        
#include <BlynkSimpleEsp8266.h> 
#include "FastLED.h"
#define LED_PIN 2 // GPIO pin for RGB LEDs.
#define NUM_LEDS 16 // Number of LEDs connected.
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define FRAMES_PER_SECOND 40
//#include <TimeLib.h>
 #include <WidgetRTC.h>
 CRGB leds[NUM_LEDS];
 //BlynkTimer timer;
 WidgetRTC rtc;
 WidgetLED led1(V11);
 SimpleTimer timer;
 
char currentTime[9];
char auth[]   = ""; 
char ssid[]   = "moreno12344";                     
char pass[]   = "lucky123";                     
char server[] = "blynk-cloud.com"; 


bool isFirstConnect = true;
int r = 255;
int g = 255;
int b = 255;
int Brightness ;
int masterSwitch ;
int autoMode = 1;
uint8_t gHue = 0;

void setup() {
  Serial.begin(9600);
  Serial.println();
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness(Brightness);
  Blynk.begin(auth, ssid, pass,server);   
 
  timer.setInterval(1500L, ringled);
  timer.setInterval(30000L, activetoday);
} 
BLYNK_CONNECTED() {
    rtc.begin();
    Blynk.syncAll();
}

void activetoday(){   
  if(Blynk.connected())
  if(year() != 1970){
    Blynk.syncVirtual(V8);  // sync scheduler #1
    
}
}
BLYNK_WRITE(V8) {   // Scheduler #1 Time Input widget  
  TimeInputParam t(param);
  int Avvio1; 
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);  
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  int dayadjustment = -1;  
  if(weekday() == 1){
   dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if(t.isWeekdaySelected((weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){    // 62s on 60s timer ensures 1 trigger command is sent
     led1.on();  // turn on virtual LED
     Avvio1 = masterSwitch = 1;
     Blynk.virtualWrite(10, 1);
      //Serial.println("Schedule 1 started");
    }                  
    if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){   // 62s on 60s timer ensures 1 trigger command is sent
      led1.off();   // turn OFF virtual LED
     Avvio1 = masterSwitch= 0;
      Blynk.virtualWrite(10, 0);
                
      //Serial.println("Schedule 1 finished"); 
       
}
    }               
  }
BLYNK_WRITE(V10) {
  masterSwitch = param.asInt();
}
void ringled(){ 
 FastLED.setBrightness(Brightness);
  if(masterSwitch == 0) {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Black;
      FastLED.show();
      
      }
    }
  
  if(autoMode == 0 && masterSwitch == 1) {
    for (int i = 0; i < NUM_LEDS; i++){
      leds[i] = CRGB(r, g, b);\
      FastLED.show();
      
    }
  }
  if(autoMode == 1 && masterSwitch == 1) {
    fill_rainbow( leds, NUM_LEDS, gHue, 2);
    // send the 'leds' array out to the actual LED strip
    FastLED.show(); 
    // insert a delay to keep the framerate modest
    FastLED.delay(40/FRAMES_PER_SECOND); 
    EVERY_N_MILLISECONDS(80) {
      gHue++; // slowly cycle the "base color" through the rainbow
}
 
 }
   } 
  

BLYNK_WRITE(V6) {
  Brightness = param.asInt();
}

//---Master On/Off---
BLYNK_WRITE(V0) {
  masterSwitch = param.asInt();
}

//--- Red slider value---
BLYNK_WRITE(V1) {
  r = param.asInt();
}

//--- Green slider value---
BLYNK_WRITE(V2) {
  g = param.asInt();
}
 
//--- Blue slider value---
BLYNK_WRITE(V3) {
  b = param.asInt(); 
}

//--- Toggle Auto/Manual Mode ---
BLYNK_WRITE(V4) {
  autoMode = param.asInt();
}


    
 

void loop() 
{ 
  if(Blynk.connected()){ 
     Blynk.run();        
  }                    
  timer.run();
}

The actual process of sending data to the LED strip is a blocking oneā€¦ thus no Blynk communication happening. The key is to keep the process as quick as possible and rely on short (sub) timers, perhaps inside the function, to determine the frequency of the processā€¦ not any additional blocking functions like delays.

It might also be beneficial to add in a Blynk.run(); command into the colour cycle if it takes too longā€¦ experiment with best place to add suchā€¦ just donā€™t dump them everywhere.

And now to totally confuse you :stuck_out_tongue: In the past I made a basic solar monitoring sketch that also runs an RGB strip with multiple sequences that loopā€¦ I didnā€™t remove the FastLED delays, but did keep them very short and actually embedded the process into the void loop()ā€¦ I know, normally bad Blynk practice, but totally functional if done with care and speed in mind. I could do it even better, but it has been running 24/7 this way for the better portion of the year. Probably doesnā€™t hurt that I am running a Local Server with very little lag.

You can check it out here:

And now to totally confuse you,:grinning: sure, I will do some experiments, to find the best. Thank you::sunglasses:

Yesā€¦ sorryā€¦ when mixing in multiple timing sensitive routines, there is really no magic code pillā€¦ and unless you are running ESP32 and advanced multi-core processing, you need to simply juggle the processes so each takes ā€œjust enoughā€ time, but not ā€œtoo muchā€ time so as to disturb the rest.

I have a slightly smaller RGB ring (12) and an ESP-01, and can wire up a power rig for both to try out your code when I get a chance.

PS you should change your Auth code so we all canā€™t join in and take control of your RGB :stuck_out_tongue_winking_eye:

:+1:

I had to guess on some of your widget settingsā€¦ but I got it running.

I added in an elapsed time indicator (display widget on V0) to see how long your various options took to run in your void ringled() loop. Overall very fast, so I am not seeing any real blocking going on.

However I did notice that when you are in manual mode, the void ringled() loop takes the longest (27-28ms with my 12 RGB ring and setup) as compared to your auto modeā€¦ in which the loop is only 3ms

I would rework your logic so that when in manual mode then there is only for() & FastLED.show() action happening when slider state changes occurā€¦ the Neopixel RGBs will retain last known state as long as powered.

And when the Master is OFF, just shut off the RGBs once and be done with itā€¦ no need to loop that process.

The only other issue I can guess at is power relatedā€¦ perhaps the ESP is occasionally browning out and resetting? Even though they donā€™t use much, there should be separate power sources for the ESP and the RGBs. And I recommend small ā€œreserveā€ capacitors (I usually use 470uf+ 16v+ electrolytic) across the power & GND for both ESP and RGB as an additional precaution.

1 Like

@gionni So, how is your code revamping going? Any improvements?

I ended up taking your general code, moving the logic around a bit and adding it to my existing ESP-01 test-bench codeā€¦ running a DHT11 for temp and humidity, a DS18B20 temp (with a piggybacked LED that flashes whenever reading the temp) and now the RGB Ring, usually cycling through the hues. I am not quite sure if the timer function is doing what it should, i usually just use the simple Timer Widget, but the sketch it is reading and writing to the 3 GPIOs, 24/7, and everything is nice and stable.

Thanks for the code :smiley: for whatever reason I have never gotten to writing custom coding for all my neopixels and only stuck with pre-canned routinesā€¦ but you code was nice and basic to breakdown and readā€¦ thus I think something finally triggered in me olā€™ noggin :exploding_head: and I get it!

Yes, it has one glitchy pixelā€¦ slowly got worse from day one :frowning:

Hope this code is of use to you

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
char IP[] = "xxx.xxx.xxx.xxx";

#include "FastLED.h"
#define LED_PIN 0 // GPIO pin for RGB LEDs.
#define NUM_LEDS 12 // Number of LEDs connected.
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define FRAMES_PER_SECOND 40
CRGB leds[NUM_LEDS];

#include <WidgetRTC.h>
WidgetRTC rtc;
WidgetLED led1(V17);

BlynkTimer timer;

// DHT22 Sensor setup
#include <DHT.h>
#define DHTPIN 3
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;

// DS18B20 Sensor setup
#include <OneWire.h>
#include<DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float DS18B20Temp;

char currentTime[9];
bool isFirstConnect = true;
int r = 255;
int g = 255;
int b = 255;
int Brightness;
int masterSwitch;
int autoMode;
uint8_t gHue = 0;
long millisStart;
long millisLoop;



void setup() {
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);

  DS18B20.begin();

  Blynk.connectWiFi(ssid, pass);
  Blynk.config(auth, IP, 8080);
  Blynk.connect();

  timer.setInterval(1000L, UpTime);
  timer.setInterval(60000L, DS18B20TempSensor);
  timer.setInterval(10050L, DHTTempHumSensor);
  timer.setInterval(49L, ringled);
  timer.setInterval(30000L, activetoday);

  Blynk.virtualWrite(V2, BLYNK_VERSION);
  Blynk.virtualWrite(V6, ESP.getCoreVersion());
  Blynk.virtualWrite(V8, WiFi.macAddress());
  Blynk.virtualWrite(V9, WiFi.localIP().toString());
  led1.setValue(255);

  ArduinoOTA.setHostname("ESP-01 Multi-Temp RGB Ring");  // For OTA
  ArduinoOTA.begin();  // For OTA
}



void loop() {
  Blynk.run();
  timer.run();
  ArduinoOTA.handle();  // For OTA
}



BLYNK_CONNECTED() {
  rtc.begin();
  Blynk.syncAll();
}



BLYNK_WRITE(V16) {   // Time Input widget Scheduler
  TimeInputParam t(param);
  unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
  unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
  unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
  int dayadjustment = -1;
  if (weekday() == 1) {
    dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
  }
  if (t.isWeekdaySelected((weekday() + dayadjustment))) { //Time library starts week on Sunday, Blynk on Monday
    //Schedule is ACTIVE today
    if (nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ) {  // 62s on 60s timer ensures 1 trigger command is sent
      led1.on();  // turn on virtual LED
      Blynk.virtualWrite(V14, 1);
      Blynk.syncVirtual(V14);
    }
    if (nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ) { // 62s on 60s timer ensures 1 trigger command is sent
      led1.off();   // turn OFF virtual LED
b      Blynk.virtualWrite(V14, 0);
      Blynk.syncVirtual(V14);
    }
  }
}



void activetoday() {
  if (Blynk.connected())
    if (year() != 1970) {
      Blynk.syncVirtual(V16);  // sync scheduler #1
    }
}



void ringled() {  // FastLED Auto Cycle
  if (autoMode == 1 && masterSwitch == 1) {
    FastLED.setBrightness(Brightness);
    fill_rainbow( leds, NUM_LEDS, gHue, 2);
    // send the 'leds' array out to the actual LED strip
    FastLED.show();
    // insert a delay to keep the framerate modest
    FastLED.delay(40 / FRAMES_PER_SECOND);
    EVERY_N_MILLISECONDS(10) {
      gHue++; // slowly cycle the "base color" through the rainbow
    }
  }
}



void colourRGB() {  // FastLED Manual
  if (autoMode == 0 && masterSwitch == 1) {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB(r, g, b); \
      FastLED.setBrightness(Brightness);
      FastLED.show();
    }
  }
}



//--- RGB Master On/Off ---
BLYNK_WRITE(V14) {
  masterSwitch = param.asInt();
  if (masterSwitch == 0) {  // Shut all LEDs OFF
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Black;
      FastLED.show();
    }
  } else {
    colourRGB();  // Process FastLED Manual
  }
}



//--- Red slider value ---
BLYNK_WRITE(V11) {
  r = param.asInt();
  colourRGB();  // Process FastLED Manual
}



//--- Green slider value ---
BLYNK_WRITE(V12) {
  g = param.asInt();
  colourRGB();  // Process FastLED Manual
}



//--- Blue slider value ---
BLYNK_WRITE(V13) {
  b = param.asInt();
  colourRGB();  // Process FastLED Manual
}



//--- Toggle Auto/Manual Mode ---
BLYNK_WRITE(V15) {
  autoMode = param.asInt();
  if (autoMode == 1) {
    Blynk.virtualWrite(V14, 1);  // Turn on Master
    Blynk.syncVirtual(V14);  // Run Master function
  } else {
    Blynk.syncVirtual(V11);  // Get current RED
    Blynk.syncVirtual(V12);  // Get current GREEN
    Blynk.syncVirtual(V13);  // Get current BLU
    colourRGB();  // Process FastLED Manual
  }
}



//--- Brightness slider value ---
BLYNK_WRITE(V10) {
  Brightness = param.asInt();
  FastLED.setBrightness(Brightness);
  Blynk.syncVirtual(V11);  // Get current RED
  Blynk.syncVirtual(V12);  // Get current GREEN
  Blynk.syncVirtual(V13);  // Get current BLU
  colourRGB();  // Process FastLED Manual
}



void DS18B20TempSensor() { // DS18B20 sensor reading
  DS18B20.requestTemperatures();
  delay(500);
  Blynk.virtualWrite(V3, DS18B20.getTempCByIndex(0));
}



void DHTTempHumSensor() { // DHT sensor reading
  h = dht.readHumidity();
  t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
  Blynk.virtualWrite(V4, h);
  Blynk.virtualWrite(V5, t);
}



BLYNK_WRITE(V1) {  // Quick test read
  if (param.asInt()) {
    Blynk.virtualWrite(V0, 0);
    Blynk.virtualWrite(V3, 0);
    Blynk.virtualWrite(V4, 0);
    Blynk.virtualWrite(V5, 0);
    DS18B20TempSensor();
    DHTTempHumSensor();
  }
}



void UpTime() {
  Blynk.virtualWrite(V0, millis() / 1000);
  Blynk.virtualWrite(V7, WiFi.RSSI());
}

Thank you for your availability, I also thought to divide the code into more void. It works great.have translated with google

Wow, nice diffuser coverā€¦ much classier then my old fruit cup bowls :rofl: