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

Drop of Life
Intermediate
  • 654
  • 17

Full instructions

A display to remind me when I can donate blood and save lives, powered by the Red Cross API and Particle.

IoT Drone - Part 2 - Sensors
Intermediate
  • 389
  • 4

Work in progress

Part 2 incorperates a GPS receiver, 10 DOF IMU, and Ultrasonic distance sensor to be used for flight controls.

How to run Particle on Raspberry Pi (Headless on Pi Zero W)
Intermediate
  • 1,653
  • 19

Protip

Use the most popular single-board computer with the most popular IoT tools.

Your Wife is Hot!
Intermediate
  • 602
  • 6

Full instructions

Not hot like she looked at your browser history, hot as in temperature hot! This can be avoided with an A/C Condensate Monitoring System.

Your Wife is Hot!

Team Is it Summer Yet?

Wireless Tank and Pump Monitoring System with Mobile App
Intermediate
  • 500
  • 3

Particle and Blynk to wirelessly monitor a 4,000 gallon water distribution system.

IoT Controlled Planter Lights
Intermediate
  • 554
  • 6

This is a shelf for starting plant seeds, controlled over the internet with automatic lights.

Add projectSign up / Login
Respect project