Unchanged code no longer working

I have run into a strange problem. A year or so ago I made a 60 pixel ring clock with NTP using a Wemos mini and everything work great. Over the next couple of months I made 3 more of these clocks and again, everything worked great. I have not touched the code for about a year and now and when I tried to create another clock, using the same Wemos mini and 60 pixel ring, the code compiles fine and is running as it should in the serial monitor but the LEDs on the 60 pixel ring are not indicating the time. When it connects to the NTP server it should display 3 colored LEDs, red = hours, green = minutes and blue = seconds. All I get is 2 pixels lit, (white and green), which normally displays while it waits to receive the time from the time server. Once it connects, these two LEDs should disappear and the time should be displayed. The serial monitor indicates that the connection is made.

I took one of the clocks that was working and uploaded the code and now it no longer works either. I can’t seem to find the problem. I don’t understand why it is working in the serial monitor but not on the 60 pixel ring, especially since the code has not been altered since the last working clock was made a year ago. The data pin for the pixel ring is set to D4 in the code and is wired as such on the Wemos mini. Any suggestions would be greatly appreciated.

Here is my code:

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Adafruit_NeoPixel.h>
 
#define PIN D4
#define PIXEL 60
int LED = 0;
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL, PIN, NEO_GRB + NEO_KHZ800);
 
 
// Replace with your network credentials
const char* ssid     = "MySSID";
const char* password = "MyPassword";
 
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
 
// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;
 
//Variables to hold Year, month and day substrings
String theyear;
String themonth;
String theday;
 
//Variable to convert month and day to integers
int yearval;
int monthval;
int dayval;
 
//Variables to get substrings of formatted date
 String thehour;
 String theminute;
 String thesecond;
 
//Variables to convert from strings to integers
int hourval;
int minuteval;
int secondval;
 
int DST;
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
// Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  timeClient.setTimeOffset(-14400);   //time offset for Ontario Canada.  Adjust for DST below
 
  strip.begin();
  strip.show();    // Initialize all pixels to 'off'
  strip.setBrightness(20);
}
void loop() {
  timedate();
//----------------< New Code >-----------------
 
switch (hourval){      //Synchronize the LEDs for 12 hour clock.
    case 1: case 13:
      LED = 5;
      break;
    case 2: case 14:
      LED = 10;
      break;
    case 3: case 15:
      LED = 15;
      break;
    case 4: case 16:
      LED = 20;
      break;
    case 5: case 17:
      LED = 25;
      break; 
    case 6: case 18:
      LED = 30;
      break;
    case 7: case 19:
      LED = 35;
      break;
    case 8: case 20:
      LED = 40;
      break;
    case 9: case 21:
      LED = 45;
      break;
    case 10: case 22:
      LED = 50;
      break;
    case 11: case 23:
      LED = 55;
      break;
    case 12: case 0:;
      LED = 0;
      break;
    }
 
    strip.setPixelColor(minuteval, 0x008000);      // Turn on LED for minutes.
    strip.setPixelColor(secondval, 0x0000ff);      // Turn on LED for seconds.
    strip.setPixelColor(LED, 0xff0000);            // Turn on LED for hours.
    strip.show();
       
    strip.setPixelColor(LED, 0x000000);            // Turn off LED for minutes.
    strip.setPixelColor(minuteval, 0x000000);      // Turn off LED for seconds.
    strip.setPixelColor(secondval, 0x000000);      // Turn off LED for hours.
   
 
//----------------< End New Code >-----------------
 }
 
void timedate(){
while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
 
 formattedDate = timeClient.getFormattedDate();
 
  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
 
  theyear = dayStamp.substring(0,4);   //Grab the year in a substring
  themonth = dayStamp.substring(5,7);   //Grab the year in a substring
  theday = dayStamp.substring(8,10);   //Grab the year in a substring
 
  Serial.print("Year: ");
  Serial.println(theyear);
  Serial.print("Month: ");
  Serial.println(themonth);
  Serial.print("Day: ");
  Serial.println(theday);
 
  yearval = theyear.toInt();
  monthval = themonth.toInt();
  dayval = theday.toInt();
 
  checkDST();
 
  // Extract time
  timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
  thehour = timeStamp.substring(0,2);
  theminute = timeStamp.substring(3,5);
  thesecond = timeStamp.substring(6,8);
  Serial.print("The Hour is: ");
  Serial.println(thehour);
  Serial.println("");
  Serial.print("The Minute is: ");
  Serial.println(theminute);
  Serial.println("");
  Serial.print("The Second is: ");
  Serial.println(thesecond);
  Serial.println("");
 
  hourval = thehour.toInt();
  minuteval = theminute.toInt();
  secondval = thesecond.toInt();
 
  delay(1000);
}
 
void checkDST(){
 
// ********************* Calculate offset for Sunday *********************
   int y = yearval - 2000;                // Get year from RTC and subtract 2000
   int x = (y + y/4 + 2) % 7;      // remainder will identify which day of month
                                                // is Sunday by subtracting x from the one
                                                // or two week window.  First two weeks for March
                                                // and first week for November
 
// *********** Test DST: BEGINS on 2nd Sunday of March @ 2:00 AM *********
   if(monthval == 03 && dayval == (14 - x) && hourval >= 2)
       {                                  
        DST = 1;                           // Daylight Savings Time is TRUE (add one hour)
       }
   if(monthval == 03 && dayval > (14 - x) || monthval > 03)
       {
        DST = 1;
       }
// ************* Test DST: ENDS on 1st Sunday of Nov @ 2:00 AM ************      
   if(monthval == 11 && dayval == (7 - x) && hourval >= 2)
       {
        DST = 0;                            // daylight savings time is FALSE (Standard time)
       }
   if(monthval == 11 && dayval > (7 - x) || monthval > 11 || monthval < 3)
       {
        DST = 0;
       }
 
   if(DST == 1)                        // Test DST and add one hour if = 1 (TRUE)
       {
        //hourval = hourval + 1;
       }
}

What do you see in the Serial monitor?

Did you update any of the underlying libraries since last year? may be something changed.

this is super very agressive

  while (!timeClient.update()) {
    timeClient.forceUpdate();
  }

you are sending tons of NTP requests and might get your IP banned from the NTP service.

Just do timeClient.update(); it will trigger a forced update every 60 seconds (by default) and during those 60s the arduino will use millis() to keep track of the elapsed time, so you read the time still correctly

My first guess: you installed a newer version of one or more of your libraries, and something in there changed.

Just to make sure: do these lines

  Serial.print("The Hour is: ");
  Serial.println(thehour);
 etc...

give the expected result?

Did you check the value of hourval after hourval = thehour.toInt(); ?

And this is something I don't understand:

   strip.setPixelColor(minuteval, 0x008000);      // Turn on LED for minutes.
   strip.setPixelColor(secondval, 0x0000ff);      // Turn on LED for seconds.
   strip.setPixelColor(LED, 0xff0000);            // Turn on LED for hours.
   strip.show();
      
   strip.setPixelColor(LED, 0x000000);            // Turn off LED for minutes.
   strip.setPixelColor(minuteval, 0x000000);      // Turn off LED for seconds.
   strip.setPixelColor(secondval, 0x000000);      // Turn off LED for hours.

Why do you switch all leds off, immediately after switching them on? I guess nothing happens because strip.show(); is not called, but I still think it should be the other way around...

Erik_Baas:
Why do you switch all leds off, immediately after switching them on? I guess nothing happens because strip.show(); is not called, but I still think it should be the other way around...

that's actually correct. this way the next time the loop comes back (1 second later since there is a delay(1000)) the old pixels are already erased in the buffer and the new ones are being set. smart :wink:

Got it working now. In the original code I had #define PIN D4 which worked fine. Since it stopped working I tried changing that line to #define PIN 2 which is the pin number for D4 and now it works again. Maybe something in one of the libraries?

Are you aware that using a bit-banged method to send neopixel signal (as you are doing) will at some point cause your wifi-connection to hang ? With only 60 leds and a refresh rate 1Hz, probably not very soon (or often really) but if there are wifi connection tasks to be executed while interrupts are turned off this issue arises.
If it has happened already, that is why.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.