Stability Problem: Sunrise alarm clock , controlled by Eventor, but Wemos crashes multiple time a night

hi everybody,
I added a sunrise alarm clock function which is controlled by the new eventor widget in the app. This sunrise circle fades the leds from red to orange to white in about 18 minutes. The eventor widget works basically as the timer widget. This widget sets virtual pin V1 18 minutes before wake-up-time to case 8 (see code). When I go to bed, I’m setting the activity slider to case 9 because the lamp has to be on and the brightness has to be set to 255.
But now my Problem: the wemos d1 mini seems to crash 4 to 5 times a night. When it crashes, the first led is set to white with full brightness. It’s actually so bright that I’m always waking up when it crashes. It also doesn’t start the sunrise circle in the morning after a crash. So basically the alarm function doesn’t work at all. I tried two different boards and two different wifis but it’s always crashing. So maybe something is wrong with the code.
I’m using 144 leds as a 12X12 matrix by the way.
It’s sad because I wanted to give the lamp as a gift.

I’m new to programming and I hope you may help me.


/*
     Neopixel stonelamp by Markus Rohner
     Version 1.0     23. 3. 2017

     Funtion: 12 activities

   Aknowledgements:
     1. Adafruit Neopixel library: http://learn.adafruit.com/adafruit-neopixel-uberguide/neomatrix-library
     2. Arduino – LEDStrip effects for NeoPixel and FastLED: https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/

   Pin assignments:
      Wemos
   D2 to DI 5050 RGB LED string

   Blynk Virtual Pins:
   V0: ON OFF Button
   V1: Activity slider
   V2: Terminal
   V8: Blink button
   V10: Brightness slider
   V11: Speed slider
   V12: Colour select
   V13: ON OFF LED
   V14: UP LED

   Bill of material:
     -Wemos D1 mini
     -Adafruit Neopixelstring 60 LEDs
     -1000uF capacitor
     -5V 4A Power Supply

*/


#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

// Set ESP8266 Serial object
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
SimpleTimer timer;

// Blynk
//#define BLYNK_DEBUG
//#define BLYNK_PRINT Serial
int ONOFF_LED = V13;
int UP_LED = V14;
long int last_UP_change = millis();
bool runn = 1;
WidgetTerminal terminal(V2);

// RGB Lights
#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 144
const int NUM_LEDS4 = NUM_LEDS / 4;
#define PIN D4
//const int long red = 16711680;
//const int long green = 65280;
const int long blue = 255;
int brightness = 255;
int standard_speed = 50;
int current_activity = 0;
int this_activity = 0;
long current_color = blue;
bool lamp_on = false;
bool blinkon = false;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);


// Wireless settings
const char AUTH[] = "";
const char SSID[] = "";
const char PASSWORD[] = "";

// Timing
volatile int WDTCount = 0;


void setup() {
  Serial.begin(115200);
  Serial.println(F("setup start"));

  //Blynk
  WiFi.mode(WIFI_STA);
  Blynk.begin(AUTH, SSID, PASSWORD);
  while (Blynk.connect() == false) {  // Wait until connected
    if ((millis() - last_UP_change) > 30000) { // 30s before reset
      Serial.println(F("resetting"));
      terminal.println(F("resetting"));
      terminal.flush();
      ESP.restart();
    }
  }
  wait(500);


  // Init Neopixels
  strip.begin();
  all_lights(0);


  //OTA
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);
  // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setHostname("Lampe");
  // No authentication by default
  ArduinoOTA.setPassword((const char *)"");
  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();

  Serial.println(F("Entering loop"));
  wait(3000);
  timer.setInterval(2003L, blinkonoff);
  //timer.setInterval(1000L, ISRwatchdog);
  printStatus();
  Serial.println();
  Blynk.virtualWrite(ONOFF_LED, 0);
  Blynk.virtualWrite(UP_LED, 0);
}


void loop() {
  Blynk.run();
  if (!Blynk.connected()) {
    Serial.println(F("Resetting in loop"));
    ESP.restart();
  }
  WDTCount = 0;
  timer.run();
  ArduinoOTA.handle();
  activity(current_activity);
}


void activity(int activity_button) {
  if (lamp_on) {
    this_activity = activity_button;
    strip.setBrightness(brightness);
    switch (activity_button) {
      case 0:  // no activity
        all_lights(current_color);
        if (blinkon) {
          wait(standard_speed * 2);
          strip.setBrightness(15);
          strip.show();
          wait(standard_speed * 2);
          strip.setBrightness(brightness);
        }
        break;
      case 3:  // colorWipe
        colorWipe(0);
        colorWipe(current_color);
        break;
      //case 2:  // theaterChase
      //theaterChase(strip.Color(random(255), random(255), random(255)));
      //break;
      case 2:  // rainbow
        rainbow();
        break;
      case 1:  // rainbowCycle
        rainbowCycle();
        break;
      //case 5:  // theaterChaseRainbow
      //theaterChaseRainbow();
      //break;
      case 6:  // CylonBounce
        CylonBounce(splitColor (current_color, 'r'), splitColor (current_color, 'g'), splitColor (current_color, 'b'), 3);
        break;
      case 4:  // TwinkleRandom
        TwinkleRandom(20, false);
        break;
      //case 8:  // Sparkle
      //Sparkle(random(255), random(255), random(255));
      //break;
      //case 9:  // RunningLights
      //RunningLights(splitColor (current_color,'r'), splitColor (current_color,'g'), splitColor (current_color,'b'));
      //break;
      case 7:  // Fire
        Fire(55, 120); // was 55,120
        break;
      case 5:  // fade
        FadeInOut(splitColor (current_color, 'r'), splitColor (current_color, 'g'), splitColor (current_color, 'b'));
        break;
      //case 12:  // rotate
      //rotate();
      //break;
      case 8: //sunrise
        Serial.println(F(" "));
        terminal.println(F(" "));
        terminal.flush();
        Serial.println(F("Start Sonnenaufgang"));
        terminal.println(F("Start Sonnenaufgang"));
        terminal.flush();
        sunrise1();
        sunrise2();
        Serial.println(F(" "));
        terminal.println(F(" "));
        terminal.flush();
        Serial.println(F("Hast du gut geschlafen?"));
        terminal.println(F("Hast du gut geschlafen?"));
        terminal.flush();
        break;
      case 9:  // black
        all_lights(0, 0, 0);
        break;
    }
  }
  else {
    strip.setBrightness(0);
    strip.show();
  }
}


// Fill the dots one after the other with a color (1)
void colorWipe(uint32_t c) {
  for (int i = 0; i < NUM_LEDS4; i++) {
    if (!lamp_on || this_activity != current_activity) break;
    for (int j = 0; j < 4; j++) {
      strip.setPixelColor(i + j * NUM_LEDS4, c);
    }
    strip.show();
    wait(standard_speed / 3);
  }
}


//Theatre-style crawling lights. (2)
void theaterChase(uint32_t c) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    if (!lamp_on || this_activity != current_activity) break;
    for (int q = 0; q < 3; q++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int i = 0; i < NUM_LEDS4; i = i + 3) {
        if (!lamp_on || this_activity != current_activity) break;
        for (int m = 0; m < 4; m++) {
          strip.setPixelColor(i + q + m * NUM_LEDS4, c); //turn every third pixel on
        }
      }
      strip.show();
      wait(standard_speed * 3);
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        if (!lamp_on || this_activity != current_activity) break;
        for (int m = 0; m < 4; m++) {
          strip.setPixelColor(i + q + m * NUM_LEDS4, 0);    //turn every third pixel off
        }
      }
    }
  }
}


// (3)
void rainbow() {
  uint16_t i, j;
  for (j = 0; j < 256; j += 2) {
    if (!lamp_on || this_activity != current_activity) break;
    for (i = 0; i < NUM_LEDS4; i++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int m = 0; m < 4; m++) {
        strip.setPixelColor(i + m * NUM_LEDS4, Wheel((i + j) & 255));
        strip.show();
        wait(standard_speed / 5);
      }
    }
  }
}


// Slightly different, this makes the rainbow equally distributed throughout (4)
void rainbowCycle() {
  uint16_t i, j;
  for (j = 0; j < 256 * 1000; j++) { // 5 cycles of all colors on wheel
    if (!lamp_on || this_activity != current_activity) break;
    for (i = 0; i < NUM_LEDS4; i++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int m = 0; m < 4; m++) {
        strip.setPixelColor(i + m * NUM_LEDS4, Wheel(((i * 256 / NUM_LEDS4) + j) & 255));
      }
    }
    strip.show();
    wait(standard_speed / 2);
  }
}


//Theatre-style crawling lights with rainbow effect (5)
void theaterChaseRainbow() {
  for (int j = 0; j < 256; j += 2) { // cycle all 256 colors in the wheel
    if (!lamp_on || this_activity != current_activity) break;
    for (int q = 0; q < 3; q++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int i = 0; i < NUM_LEDS4; i = i + 3) {
        if (!lamp_on || this_activity != current_activity) break;
        for (int m = 0; m < 4; m++) {
          strip.setPixelColor(i + q + m * NUM_LEDS4, Wheel( (i + j) % 255)); //turn every third pixel on
        }
      }
      strip.show();
      wait(standard_speed * 3);
      for (int i = 0; i < NUM_LEDS4; i = i + 3) {
        if (!lamp_on || this_activity != current_activity) break;
        for (int m = 0; m < 4; m++) {
          strip.setPixelColor(i + q + m * NUM_LEDS4, 0);    //turn every third pixel off
        }
      }
    }
  }
}


// (6)
void CylonBounce(byte red, byte green, byte blue, int EyeSize) {
  for (int i = 0; i < NUM_LEDS4 - EyeSize - 2; i++) {
    if (!lamp_on || this_activity != current_activity) break;
    all_lights(0);
    for (int m = 0; m < 4; m++) {
      setPixel(i + m * NUM_LEDS4, red / 10, green / 10, blue / 10);
    }
    for (int j = 1; j <= EyeSize; j++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int m = 0; m < 4; m++) {
        setPixel(i + j + m * NUM_LEDS4, red, green, blue);
      }
    }
    for (int m = 0; m < 4; m++) {
      setPixel(i + EyeSize + 1 + m * NUM_LEDS4, red / 10, green / 10, blue / 10);
    }
    strip.show();
    wait(standard_speed / 2);
  }
  wait(standard_speed);

  for (int i = NUM_LEDS4 - EyeSize - 2; i > 0; i--) {
    if (!lamp_on || this_activity != current_activity) break;
    all_lights(0);
    for (int m = 0; m < 4; m++) {
      setPixel(i + m * NUM_LEDS4, red / 10, green / 10, blue / 10);
    }
    for (int j = 1; j <= EyeSize; j++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int m = 0; m < 4; m++) {
        setPixel(i + j + m * NUM_LEDS4, red, green, blue);
      }
    }
    for (int m = 0; m < 4; m++) {
      setPixel(i + EyeSize + 1 + m * NUM_LEDS4, red / 10, green / 10, blue / 10);
    }
    strip.show();
    wait(standard_speed / 2);
  }
  wait(standard_speed);
}


// (7)
void TwinkleRandom(int Count, boolean OnlyOne) {
  all_lights(0);
  for (int i = 0; i < Count; i++) {
    if (!lamp_on || this_activity != current_activity) break;
    setPixel(random(NUM_LEDS), random(0, 255), random(0, 255), random(0, 255));
    strip.show();
    wait(standard_speed);
    if (OnlyOne) {
      all_lights(0);
    }
  }
  wait(standard_speed / 2);
}


// (8)
void Sparkle(byte red, byte green, byte blue) {
  all_lights(0);
  int Pixel = random(NUM_LEDS);
  setPixel(Pixel, red, green, blue);
  strip.show();
  wait(standard_speed);
  setPixel(Pixel, 0, 0, 0);
}


// (9)
void RunningLights(byte red, byte green, byte blue) {
  int Position = 0;
  for (int i = 0; i < NUM_LEDS4 * 2; i++)  {
    if (!lamp_on || this_activity != current_activity) break;
    Position++; // = 0; //Position + Rate;
    for (int i = 0; i < NUM_LEDS4; i++) {
      if (!lamp_on || this_activity != current_activity) break;
      for (int m = 0; m < 4; m++) {
        if (!lamp_on || this_activity != current_activity) break;
        setPixel(i + m * NUM_LEDS4, ((sin(i + Position) * 127 + 128) / 255)*red,
                 ((sin(i + Position) * 127 + 128) / 255)*green,
                 ((sin(i + Position) * 127 + 128) / 255)*blue);
      }
    }
    strip.show();
    wait(standard_speed * 2);
  }
}


// (10)
void Fire(int Cooling, int Sparking) {
  static byte heat[NUM_LEDS];
  int cooldown;
  // Step 1.  Cool down every cell a little
  for (int m = 0; m < 4; m++) {
    for ( int i = 0; i < NUM_LEDS4; i++) {
      cooldown = random(0, ((Cooling * 10) / NUM_LEDS4) + 2);
      if (cooldown > heat[i + m * NUM_LEDS4]) {
        heat[i + m * NUM_LEDS4] = 0;
      } else {
        heat[i + m * NUM_LEDS4] = heat[i + m * NUM_LEDS4] - cooldown;
      }
    }
  }
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for (int m = 0; m < 4; m++) {
    for ( int k = NUM_LEDS4 - 1; k >= 2; k--) {
      if (!lamp_on || this_activity != current_activity) break;
      heat[k + m * NUM_LEDS4] = (heat[k + m * NUM_LEDS4 - 1] + heat[k + m * NUM_LEDS4 - 2] + heat[k + m * NUM_LEDS4 - 2]) / 3;
    }
  }
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  for (int m = 0; m < 4; m++) {
    if ( random(255) < Sparking ) {
      int y = random(3); //was 7
      heat[y + m * NUM_LEDS4] = heat[y + m * NUM_LEDS4] + random(160, 255);
    }
  }
  // Step 4.  Convert heat to LED colors
  for ( int j = 0; j < NUM_LEDS; j++) {
    if (!lamp_on || this_activity != current_activity) break;
    setPixelHeatColor(j, heat[j]);
  }
  strip.show();
  wait(standard_speed);
}


void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature / 255.0) * 191);
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
  // figure out which third of the spectrum we're in:
  if ( t192 > 0x80) {                    // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if ( t192 > 0x40 ) {            // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}


//(11)
void FadeInOut(byte red, byte green, byte blue) {
  float r, g, b;

  for (int k = 20; k < 256; k = k + 1) {
    if (!lamp_on || this_activity != current_activity) break;
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    all_lights(r, g, b);
    wait(standard_speed / 6);
  }

  for (int k = 255; k >= 20; k = k - 2) {
    if (!lamp_on || this_activity != current_activity) break;
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    all_lights(r, g, b);
    wait(standard_speed / 6);
  }
}


//Rotate (12)
void rotate() {
  all_lights(0);
  for (int m = 0; m < 4; m++) {
    for (int i = m * NUM_LEDS4; i < (m + 1)*NUM_LEDS4; i++) {
      if (!lamp_on || this_activity != current_activity) break;
      strip.setPixelColor(i, current_color);
    }
    strip.show();
    wait(standard_speed * 2);
    for (int i = m * NUM_LEDS4; i < (m + 1)*NUM_LEDS4; i++) {
      if (!lamp_on || this_activity != current_activity) break;
      strip.setPixelColor(i, 0);
    }
    strip.show();
  }
}

void sunrise1() {
  wait(100);

  for (int k = 0; k < 65; k = k + 1) {
    if (!lamp_on || this_activity != current_activity) break;


    all_lights(k, 0, 0);
    for ( int i = 1; i <= 10; i++) {
      wait(500);
    }

  }
  for (int l = 0; l < 45; l = l + 1) {
    if (!lamp_on || this_activity != current_activity) break;


    all_lights(65, l, 0);
    for ( int i = 1; i <= 10; i++) {
      wait(500);
    }
  }
}
void sunrise2() {
  for (int m = 0; m < 50; m = m + 1) {
    if (!lamp_on || this_activity != current_activity) break;


    all_lights(65 + 2 * m, 45 + m, 0);
    for ( int i = 1; i <= 10; i++) {
      wait(300);
    }
  }
  for (int n = 0; n < 90; n = n + 1) {
    if (!lamp_on || this_activity != current_activity) break;


    all_lights(165 + n, 95 + n, 0);
    for ( int i = 1; i <= 10; i++) {
      wait(150);
    }
  }

  for (int o = 0; o < 185; o = o + 1) {
    if (!lamp_on || this_activity != current_activity) break;


    all_lights(255, 185, o);
    for ( int i = 1; i <= 10; i++) {
      wait(100);
    }
  }


  for (int p = 0; p < 70; p = p + 1) {
    if (!lamp_on || this_activity != current_activity) break;


    all_lights(255, 185 + p, 185 + p);
    for ( int i = 1; i <= 10; i++) {
      wait(100);
    }
  }


}


void all_lights(int g, int r, int b) {
  wait(1);
  for (int x = 0; x < NUM_LEDS; x++) {
    strip.setPixelColor(x, g, r, b);
  }
  strip.show();
}


void all_lights(int color) {
  wait(1);
  for (int x = 0; x < NUM_LEDS; x++) {
    strip.setPixelColor(x, color);
  }
  strip.show();
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}


/**
   splitColor() - Receive a uint32_t value, and spread into bits.
*/
byte splitColor ( uint32_t c, char value )
{
  switch ( value ) {
    case 'r': return (uint8_t)(c >> 16);
    case 'g': return (uint8_t)(c >>  8);
    case 'b': return (uint8_t)(c >>  0);
    default:  return 0;
  }
}


void printStatus() {
  Serial.print(F(" ON: "));
  Serial.print(lamp_on);
  Serial.print(F(" Blink: "));
  Serial.print(blinkon);
  Serial.print(F(" Activity: "));
  Serial.print(current_activity);
  Serial.print(F(" Color: "));
  Serial.print(current_color);
  Serial.print(F(" Brightness: "));
  Serial.print(brightness);
  Serial.print(F(" Speed: "));
  Serial.println(standard_speed);
  terminal.print(F("ON:"));
  terminal.print(lamp_on);
  //terminal.print(F(" Blk:"));
  //terminal.print(blinkon);
  terminal.print(F(" Act:"));
  terminal.print(current_activity);
  terminal.print(F(" Col:"));
  terminal.print(current_color);
  terminal.print(F(" Bright:"));
  terminal.print(brightness);
  terminal.print(F(" Spd:"));
  terminal.println(standard_speed);
  terminal.flush();
}


void wait (int ms) {
  long current_time = millis();
  long end_time = current_time + ms;
  while (current_time < end_time) {
    if (!lamp_on || this_activity != current_activity) break;
    current_time = millis();
  }
  Blynk.run();
  timer.run();
}


void blinkonoff() {
  // Turn runn LED on/off
  Blynk.virtualWrite(UP_LED, runn * 255); // turn Up off
  runn = !runn;
  last_UP_change = millis();
  WDTCount = 0;
}

BLYNK_WRITE(V0) { //ON Off
  if (param.asInt()) lamp_on = 1;
  else {
    all_lights(0);
    lamp_on = 0;
  }
  Blynk.virtualWrite(ONOFF_LED, lamp_on * 255); // turn Up off
  printStatus();
}

BLYNK_WRITE(V1) { //Activity slider
  current_activity = param.asInt();
  printStatus();
}

BLYNK_WRITE(V8) { //Blink
  if (param.asInt()) blinkon = true;
  else blinkon = false;
  printStatus();
}

BLYNK_WRITE(V10) { // Brightness slider
  brightness = param.asInt();
  strip.setBrightness(brightness);
  strip.show();
  printStatus();
}

BLYNK_WRITE(V11) { // Speed
  standard_speed = param.asInt();
  printStatus();
}

BLYNK_WRITE(V12) { //RGB light
  current_color = param[2].asInt() + 256 * param[1].asInt() + 256 * 256 * param[0].asInt();
  printStatus();
}


void ISRwatchdog() {
  WDTCount++;
  if (WDTCount == 5) {
    Serial.println(F("WDT reset"));
    terminal.println(F("WDT reset"));
    terminal.flush();
    ESP.reset();
  }
}


void setPixel(int Pixel, byte red, byte green, byte blue) {
  strip.setPixelColor(Pixel, strip.Color(red, green, blue));
}

I’ve edited your post so that your code displays correctly.
In future you should do it like this:

Blynk%20-%20FTFC

Pete.

I’ve edited your post so that your code displays correctly.
In future you should do it like this:

Blynk%20-%20FTFC

Pete.

thank you :slight_smile:

FYI, I moved your issue into your own topic.

1 Like

Here’s the link to the original code:

I hope somebody can help me:)

For me, it seems to be a Power-Problem. Maybe your powering of the device is not stable enough.

On my Projects i get those Problems only when using a bread-board + Jumper-Wires. It took me long time to see, that those breadboards have several problems with stability of connections.

1 Like

Thanks for your reply, but when i try some other code everything works just fine without connection losses.

This is not a conclusive argument. Different code maybe produces less power consumption… and this may result in more stability.

you did not tell us, if you are using unstable wiring and so on (like breadboard + jumper wires)

Indeed i use jumper wires which are soldered to a 5V 8A power supply on the one side an connected to the pins of the wemos on the other side.

I will try to solder the wemos directly to the power supply.
I never thought about this beeing the problem because of other codes running smoothly.