Adafruit Neopixel RGBW Clock using SK6812

Hello all

I’m working on an RGBW LED Clock using a single strip of SK6812 using 72 pixels/LEDS.

60 pixels will be used as seconds and minutes, while 12 pixels will be used for hours.

Using Adafruit’s Neopixel library - I use a for loop to flash each pixel red to represent a second, from the 0th pixel to the 60th pixel. Again, the red colour represents a second.

Once the 60th LED is lit, the process starts all over again, but the first LED is now also blue, to indicate that a minute has gone pass - I use a global variable counter to keep track of the minutes that have passed, and use this variable as an argument for the strip.fill function.

Once the 60th LED has flashed blue, I want the 61th pixel to light green to indicate an hour - the second/minute double loop should repeat until the 72th pixel is lit green (12th hour) and then the seconds/minute and hour loops are back to zero.

However for some reason, the 61th to 72nd pixel all light up simultaneously, as seen in the video

Here is my code

/*
  RGBW CLOCK
  Version 2
  28/06/2020

  Version 2 - Minutes now work, however hours does not. 
*/

// NeoPixel test program showing use of the WHITE channel for RGBW
// pixels only (won't look correct on regular RGB NeoPixel strips).

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN     6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT  72
// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 100

// DELAY VALUE
int delayval = 1;

// COUNTER VALUES

int j = 0; // FOR MINUTES
int k = 61; // FOR HOURS

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(10); // Set BRIGHTNESS to about 1/5 (max = 255)
  Serial.begin(9600);
}

void loop() {
  // Fill along the length of the strip in various colors...
  singleLED(strip.Color(255,   0,   0)     , strip.Color(0,   0,   255), strip.Color(0,   255,   0),  delayval); // three color objects and a delay value

}
// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.

//COLOURS OF THE CLOCK - RED FOR SECONDS, BLUE FOR MINUTES, GREEN FOR HOURS

void singleLED(uint32_t colorSeconds, uint32_t colorMinutes, uint32_t colorHours,  int wait) {

  for (int i = 0; i < 60; i++) { // For each pixel in strip...

    // COUNTER
    if (i == 59) {
      j++;
      Serial.println(j);
      if (j == 61) {
        j = 0;
        k++;
        Serial.println(k);
        strip.clear();
      }
    }
    // TURN ON LEDS FOR MINUTES
    if (j >= 1) {
      strip.fill(colorMinutes, 0, j);
      strip.show();
    }
    // TURN ON LEDS FOR HOURS
    if (k >= 62) {
      strip.fill(colorHours, 60, k);
      strip.show();
    }
    // TURN ON LEDS FOR SECONDS
    strip.setPixelColor(i, colorSeconds);
    strip.show();
    //  Update strip to match
    delay(wait);                           //  Pause for a moment
    strip.clear();
  }
}

Here’s the snippet of code responsible for the green LEDS:

    // TURN ON LEDS FOR HOURS
    if (k >= 62) {
      strip.fill(colorHours, 60, k);
      strip.show();
    }

I don’t know why this code would flash all 61th-72nd leds…

Looking forward to your reply :slight_smile:

Kind Regards
Dennis

I don't know why this code would flash all 61th-72nd leds....

I don't think you read the documentation for strip.fill() carefully enough, or understood it. Read it again and see if you can figure out what you are doing wrong.