NTP clock code assistance

Hi All,

I’m working on an NTP clock project that I want to add an animation every hour, otherwise it behaves like a normal clock. I have two LED rings in use, a 12 LED ring for hours and a 24 LED ring for mins/secs.

What I want to add in (where I’m having trouble) is when the minute is equal to zero, go to the animation void called “rainbowCycle”. Otherwise keep doing the regular time display. Attached is my code for reference.

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include "TimeClient.h"

#define PIN_h D2
#define PIN_m D6

int smallringLEDS = 12;
int largeringLEDS = 24;
int currentSecond, currentMinute, currentHour;
long lastUpdate = millis();
long lastSecond = millis();

String hours, minutes, seconds;

char ssid[] = "SSID0"; 
char pass[] = "PASS";

const float UTC_OFFSET = -5; 
TimeClient timeClient(UTC_OFFSET);

Adafruit_NeoPixel strip_h = Adafruit_NeoPixel(smallringLEDS, PIN_h, NEO_GRB | NEO_KHZ800); //strip_h = 12 hrs LED ring
Adafruit_NeoPixel strip_m = Adafruit_NeoPixel(largeringLEDS, PIN_m, NEO_GRB | NEO_KHZ800); //strip_m = 24 mins/secs LED ring
//----------------------------------------------------------------------------------------------------------------------------------------------------------

void setup()
{
  strip_h.begin(); strip_h.setBrightness(64); strip_h.show();                                              //initialize LED's on hour ring
  strip_m.begin(); strip_m.setBrightness(64); strip_m.show();                                              //initialize LED's on min/sec ring
  Serial.begin(115200); Serial.println(); Serial.println();                                                //start up serial output for debugging
  Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, pass);                            //start up wifi connection
  while (WiFi.status() != WL_CONNECTED) {     delay(500); Serial.print(".");  }  Serial.println("");       //wait until wifi is connected...
  Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP());        //output connection status and LAN IP
  timeClient.updateTime();   updateTime();   lastUpdate = millis();   lastSecond = millis();               //timing components
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------

void loop()
{
  if ((millis() - lastUpdate) > 1800000) updateTime();    // do NTP update to ensure no clock drift
  if ((millis() - lastSecond) > 1000)
  {
    strip_m.setPixelColor(currentSecond / 2.5, 0, 0, 0);    //set LEDs to "off" color
    strip_m.setPixelColor(currentMinute / 2.5, 0, 0, 0);    //set LEDs to "off" color
    strip_h.setPixelColor(currentHour * 2, 0, 0, 0);    //set LEDs to "off" color
    strip_h.show(); strip_m.show();   //update LED rings

    lastSecond = millis();
    currentSecond++;
    if (currentSecond > 59) { currentSecond = 0; currentMinute++;
      if (currentMinute > 59) { currentMinute = 0; currentHour++;
        if (currentHour > 12) { currentHour = 0; 
        }
      }
    }
    String currentTime = String(currentHour) + ':' + String(currentMinute) + ':' + String(currentSecond);
    Serial.println(currentTime);
//if (currentMinute = 18) { // if the minute is 0 run rainbowCycle() instead of updating the strip_m and strip_h neopixels
//    void rainbowCycle();
//  } else {
    strip_m.setPixelColor(currentSecond / 2.5, 255, 0, 0);
    strip_m.setPixelColor(currentMinute / 2.5, 155, 0, 180);
    strip_h.setPixelColor(currentHour / 1, 84, 255, 255);
    strip_h.show(); strip_m.show();
  }
}
//}

void updateTime() 
{
  hours = timeClient.getHours();
  minutes = timeClient.getMinutes();
  seconds = timeClient.getSeconds();
  currentHour = hours.toInt();
  if (currentHour > 12) currentHour = currentHour - 12;
  currentMinute = minutes.toInt();
  currentSecond = seconds.toInt();
  lastUpdate = millis();
}

void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  
  for(j=0; j<256*15; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip_h.numPixels(); i++) {
      strip_h.setPixelColor(i, Wheel(((i * 256 / strip_h.numPixels()) + j) & 255));
    }
    strip_h.show();
    delay(wait);
    updateTime();
  }
}
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip_h.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip_h.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip_h.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

If anyone could provide some input on this it would be greatly appreciated!!

Thank you so much in advance
Nubstar

You have an interesting way of formatting your code.

If formatted “conventionally” it appears from inspection to go where shown, no?

.
.
.
        lastSecond = millis();
        currentSecond++;
        if (currentSecond > 59) 
        { 
            currentSecond = 0; 
            currentMinute++;
            if (currentMinute > 59) 
            {   
                rainbowCycle(10);  //<--- here?
                currentMinute = 0; 
                currentHour++;
                if (currentHour > 12) 
                { 
                    currentHour = 0; 
                }//if
            }//if
        }//if
.
.
.
  if ((millis() - lastSecond) > 1000)
  {
    strip_m.setPixelColor(currentSecond / 2.5, 0, 0, 0);    //set LEDs to "off" color
    strip_m.setPixelColor(currentMinute / 2.5, 0, 0, 0);    //set LEDs to "off" color
    strip_h.setPixelColor(currentHour * 2, 0, 0, 0);    //set LEDs to "off" color
    strip_h.show(); strip_m.show();   //update LED rings

    lastSecond = millis();
    currentSecond++;
    if (currentSecond > 59) { currentSecond = 0; currentMinute++;
      if (currentMinute > 59) { currentMinute = 0; currentHour++;
        if (currentHour > 12) { currentHour = 0; 
        }
      }
    }

First of all by using millis the way you do you are creating the drift yourself.(updating lastsecond straight away would help already, but doing lastsecong+=1000; instead of lastsecond=millis(); is better)
Determine the offset of millis() which you have sort of doneif ((millis() - lastUpdate) > 1800000) updateTime(); and then set the time now(), take the seconds from that multiply by 1000. this is the millis() offset. now take that offset

uint32_t minuteoffset=(millis()-(uint32_t) seconds*1000);
passedseconds=(millis()-minuteoffset)/1000;  // this is the seconds passed since the offset to 0 seconds
seconds=passedseconds%60;

and you can do the same for the minutes & hours. Now if the value for minutes changes (keep track using an oldminutes value) you can start the animation, and you won't missed counting any seconds because you are not counting but calculating. I hope you catch my drift.