"Spark Internet Button" NeoPixel ring clock

Hi all
I have created a clock for the Spark Internet Button.
It uses my contributed library for the LEDs, and the 12th LED is the one on the Spark Core board itself.

if you have a Spark Internet Button give it a go, it looks quite impressive even if I do say so myself :smile:

Comments are always welcomed.

Greg

Red: Hour (brighter after midday)
Green: Minutes (pans across 2 pixels and brightness varies depending on the minute)
example:
Oā€™clock: top pixel lit 100% brightness
1 minute past: top and 1 pixel lit, top 80% brightness, 1 20% brightness
2 minutes past: top and 1 pixel lit, top 60% brightness, 1 40% brightness
3 minutes past: top and 1 pixel lit, top 40% brightness, 1 60% brightness
4 minutes past: top and 1 pixel lit, top 20% brightness, 1 80% brightness
5 minutes past: 1 pixel lit, 100% brightness.
Blue: Seconds (as minutes)

The image below was taken at 14:23:20

    // This #include statement was automatically added by the Spark IDE.
    #include "SparkButton/SparkButton.h"
    
    #include "application.h"
    //#include "spark_disable_wlan.h" // For faster local debugging only
    
    Button strip = Button();
    
    void setup() 
    {
        int i;
        strip.begin();
        strip.allLedsOff();
        RGB.control(true);
        RGB.color(0,0,0);
        i = Time.second();
        while(i == Time.second())
            delay(0.05);
    }
    
    void loop()
    {
        unsigned int pixels[12];
        int i, j;
        
        while(true)
        {
            for(i = 0;  i < 12; i++)
                pixels[i] = 0;
                
            i = Time.hour() % 12;
            pixels[i] = 0x700000 + (!Time.isAM() ? 0 : 0x800000);
    
            i = Time.minute();
            pixels[i / 5] += (0x002F00 * (5 - (i % 5)));
            if((i % 5) != 0)
            {
                pixels[((i / 5) + 1) % 12] += (0x002F00 * ((i % 5)));
            }
            i = Time.second();
            pixels[i / 5] += (0x00002F * (5 - (i % 5)));
            if((i % 5) != 0)
            {
                pixels[((i / 5) + 1) % 12] += (0x00002F * ((i % 5)));
            }
     
            for(i = 1; i <= PIXEL_COUNT; i++)
                strip.ledOn(i, (pixels[i] >> 16) & 0xFF, (pixels[i] >> 8) & 0xFF, pixels[i] & 0xFF);
            RGB.color((pixels[0] >> 16) & 0xFF, (pixels[0] >> 8) & 0xFF, pixels[0] & 0xFF);
            Spark.process();
        }
    }
5 Likes

Hey Greg, awesome work figuring out what I was up to! Itā€™s all much easier now- just search the libraries for ā€œSparkButtonā€. Easy access to the accelerometer and some functions that make the neopixels a bit cleaner to use. Enjoy, and Iā€™d love feedback!

1 Like

Nice library :smile:
I will remove my library and update the above code with your library.

You know when you get bored of all the cool stuff that passes over your deskā€¦ Iā€™d happily give it a loving new home and play with it every day :smile:

Greg

Feedback:

One of the features I would like is optionally being able to treat the RGB LED on the core itself as pixel 0. It would save some kludged code in my example above and make the experience "flow". The code in your library

Edit: Created pull request for this

void Button::ledOn(uint8_t i, uint8_t r, uint8_t g, uint8_t b){
    //i-1 shifts the location from human readable to the right index for the LEDs
    if(i == 12){
        ring.setPixelColor(0, ring.Color(r,g,b));
        ring.setPixelColor(10, ring.Color(r,g,b));
    }
    else{
        ring.setPixelColor(i-1, ring.Color(r,g,b));
    }
    ring.show();
}

could be changed easily in place of the the if(i == 12) section:

if(i == 0 && RGB.controlled()){
    RGB.color(r, g, b);
}

Using if(i == 12) will cause issues should the end user connect more neopixels to the exposed connector marked 12 on the board to extend the number of neopixels.

It is my consideration that the existing solution for if(i == 12) is very messy and if used by someone not familiar with the library itself it may lead to unnecessary debugging:

What happened to my code? I set 1 to red, 11 to blue and 12 to green, now 1, 11 and 12 are all green.

Greg

Hi Greg,

I built something similar to this yesterday at a build night,I did not know you already made this when I started it so if you have any problems with me doing almost the same thing, please say that to me :smile:

Mine works a bit different though, instead of different brightness levels it blinks an X amount of times to show the minutes. More about that later when I finish debugging and post it :smile:

I am completely against you doing a clock with the neopixel ring.
Nah, just kidding :smile:
Does it blink once per minute or once per (minute % 5)?
Iā€™d love to see the code once you post it.

Did anyone else come up with anything fun at the build night?

Geg

haha thanks :smile:

Well, for instance if it is 7 minutes, LED 1 will light up blue to show the 5 minutes and every 5 seconds it will blink 2 times in purple with short intervals to show the 2 minutes. That adds up to 7.

I am not familiar with the minute % 5 method, does this devide the minutes by 5?

At the build night 2 guys game up with a game that involved the neopixel ring and a RGB sensor. You would start with the 11 leds on in a certain color and need to find someone with the same color. If you find that person you hold your sparks close to eachother so the RGB sensor sees the neopixel ring of the other. If the colors match you will get a point and 1 led of the ring will go off and you get a new color. The first person to get all leds off wins. Sounds like a fun game but they couldenā€™t finish it during the build night.

% is the modulo operator, so it repeatedly taes the 2nd number away until there is less than the second number remaining.

Example: 4 % 5 = 4
5 % 5 = 0
45 % 5 = 0
18 % 5 = 3

1 Like

Ah yes, I understand now. I wrote a complete function for that which basically does the same haha