Things used in this project

Hardware components:
Core
Particle Spark Core
×1
Anodised Aluminium Front Panel
×1
Perspex Panel & LED clamp
×1
NEOpixel 60 LED ring
×1
Software apps and online services:
Particle Development System
Hand tools and fabrication machines:
09507 01
Soldering iron (generic)

Custom parts and enclosures

Front and rear panels
Front Panel Express Files
LEDclock.zip

Schematics

Schematic PDF
PDF file
Fritzing Breadboard View
Fritzing Breadboard View.fzz
Altium Designer Files
PCB files for Altium Designer
LEDclockDesignFiles.zip

Code

LED Clock DriverC/C++
Use Particle Dev to build the code to run on your spark or photon core.
Requires Neopixel driver from the Particle libraries
#include "neopixel.h"

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_COUNT 60
#define PIXEL_PIN D4
#define PIXEL_TYPE WS2812B

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
//               note: if not specified, D2 is selected for you.
// Parameter 3 = pixel type [ WS2812, WS2812B, WS2811, TM1803 ]
//               note: if not specified, WS2812B is selected for you.
//               note: RGB order is automatically applied to WS2811,
//                     WS2812/WS2812B/TM1803 is GRB order.
//
// 800 KHz bitstream 800 KHz bitstream (most NeoPixel products ...
//                         ... WS2812 (6-pin part)/WS2812B (4-pin part) )
//
// 400 KHz bitstream (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//                   (Radio Shack Tri-Color LED Strip - TM1803 driver
//                    NOTE: RS Tri-Color LED's are grouped in sets of 3)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

uint16_t Hours = 4;
uint16_t Mins = 18;
uint16_t Seconds = 0;

#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();
uint16_t LastSeconds;

void setup()
{
    Serial.begin(57600);

    strip.begin();
    strip.clear();
    strip.show();

    strip.setBrightness(64);
    //
    // startup sequence
    //
    delay(500);
    colorWipe(strip.Color(255, 0, 0), 20); // Red
    colorWipe(strip.Color(0, 255, 0), 20); // Green
    colorWipe(strip.Color(0, 0, 255), 20); // Blue
    delay(500);

    LastSeconds = 61;   // Cause update on first run of the loop

    Time.zone(+7);
}

void loop()
{
    if (millis() - lastSync > ONE_DAY_MILLIS)
    {
        //
        // Request time synchronization from the Particle Cloud
        //
        Spark.syncTime();
        lastSync = millis();
    }
    //
    // Get the current time
    //
    Hours = Time.hourFormat12();
    Mins = Time.minute();
    Seconds = Time.second();

    if(Seconds != LastSeconds)
    {
        if(Seconds == 0 && Mins == 0)   // Do a sequence every hour
        {
            hourSequence();
        }
        strip.clear();

        setHours(Hours);
        setMins(Mins);
        setSeconds(Seconds);

        strip.show();

        LastSeconds = Seconds;
    }
    delay(100);
}

void setHours(int hours)
{
    int16_t out;

    out = 60 - (hours * 5);

    if(out == 60)
        out = 0;

    Serial.println(Hours);
    Serial.println(out);

    strip.setPixelColor(getOffset(out - 2), 20, 0, 0);
    strip.setPixelColor(getOffset(out - 1), 50, 0, 0);
    strip.setPixelColor(out, 255, 0, 0);
    strip.setPixelColor(getOffset(out + 1), 50, 0, 0);
    strip.setPixelColor(getOffset(out + 2), 20, 0, 0);
}

void setMins(int mins)
{
    int16_t out;

    out = 60 - mins;

    if(out == 60)
        out = 0;

    strip.setPixelColor(getOffset(out - 1), 0, 50, 0);
    strip.setPixelColor(out, 0, 255, 0);
    strip.setPixelColor(getOffset(out + 1), 0, 50, 0);
}

void setSeconds(int seconds)
{
    uint16_t out;

    out = 60 - seconds;

    if(out == 60)
        out = 0;

    strip.setPixelColor(out, 0, 0, 255);
}

uint16_t getOffset(int16_t in)
{
    int16_t out = in;

    if(in < 0)
    {
        out = 60 + in;
    }
    else if(in > 59)
    {
        out = in - 59;
    }
    return out;
}

//
// Fill the dots one after the other with a color
//
void colorWipe(uint32_t c, uint8_t wait) {
    for(int16_t i=(strip.numPixels() - 1); i >= 0; i--) {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
    }
}

void hourSequence()
{
    strip.clear();

    colorWipe(strip.Color(255, 0, 0), 20); // Red
    colorWipe(strip.Color(0, 255, 0), 20); // Green
    colorWipe(strip.Color(0, 0, 255), 20); // Blue
    delay(500);
}
LEDClockSource.zipC/C++
No preview (download only).

Credits

Me2015
David McLaughlin

Self taught electronics engineer with hardware and software design experience. Building & programming various home and commercial designs for the last 35 years.

Thanks to Peter Scargill.

Replications

Did you replicate this project? Share it!

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Particle Photon Doorbell
Intermediate
  • 611
  • 9

Full instructions

Get notified when the doorbell is pressed for about 1/6 the price of the RING doorbell!

DIYSprinkler Controller
Intermediate
  • 420
  • 3

Full instructions

Make your own sprinkler controller and I have the software to control it. Must have an existing sprinkler system or you could make your own

DIYSprinkler Controller

Team dougefresh89

Magic Eyeball
Intermediate
  • 781
  • 7

Full instructions

It's like a magic eight ball. But with Alexa, and two eyeballs.

Spoil your Valentine with Particle + Spoil + AWS
Intermediate
  • 475
  • 3

Full instructions

Instead of giving a box of chocolates this Valentines Day, keep the chocolates. Lets give a smart self-gifting box instead!

Pebble + Photon = IoT Watch Switch
Intermediate
  • 50
  • 1

Full instructions

When I arrive in my house I switch on the light with my Pebble Watch! The procedure to make this is very simple.

Automated Cat Feeder with Particle Photon
Intermediate
  • 1,544
  • 19

Work in progress

The goal was to make it possible to feed my cats when I'm not at home.

Add projectSign up / Login
Respect project