Menu
CoddyTech

NeoPixel Clock: Set the Time

Part of the Projects section of Coddy's Arduino journey. Lesson 24 of 24.

The clock always starts at 10:24:50, which is right once a day. Two buttons fix that: the red one on pin 2 moves the clock on by an hour, the green one on pin 3 by 5 minutes, one pixel of the minutes hand.

The time is one number, so setting it is adding seconds. Keep what the buttons added in a variable and include it in the sum:

unsigned long adjust = 0;   // seconds added by the buttons

unsigned long now = startTime + adjust + millis() / 1000;

An hour is 3600 seconds and 5 minutes is 300. Count each press once, when the button goes down: LOW now and HIGH last time. Adding on every pass while it is held would spin the clock round. These buttons do not bounce.

int hourState = digitalRead(hourButton);
if (hourState == LOW && lastHour == HIGH) {
  adjust = adjust + 3600;
}
lastHour = hourState;

Every hand comes from now, so they all follow, and the remainders wrap the hours after 11 and the minutes after 55.

challenge icon

Challenge

Medium

Make the time settable:

  • pins 2 and 3 are INPUT_PULLUP
  • a press on pin 2 adds 3600 seconds, a press on pin 3 adds 300, each counted once when the button goes down
  • add those seconds to now

Press Run and set the clock to your time, then Check.

Try it yourself

#include <Adafruit_NeoPixel.h>

const int ringPin = 6;
const int pixelCount = 12;
Adafruit_NeoPixel ring(pixelCount, ringPin, NEO_GRB + NEO_KHZ800);

// The time the clock starts at, in seconds since midnight: 10:24:50
const unsigned long startTime = 10 * 3600UL + 24 * 60 + 50;

void setup() {
  ring.begin();
}

void loop() {
  unsigned long now = startTime + millis() / 1000;  // the time of day, in seconds
  int seconds = now % 60;
  int minutes = (now / 60) % 60;
  int hours = (now / 3600) % 12;

  int secondPixel = seconds / 5;
  int minutePixel = minutes / 5;
  int hourPixel = hours;

  // Each pixel gets red from the hours hand, green from the minutes hand
  // and blue from the seconds hand, so hands on one pixel mix.
  for (int i = 0; i < pixelCount; i++) {
    int r = 0;
    int g = 0;
    int b = 0;
    if (i == hourPixel) {
      r = 255;
    }
    if (i == minutePixel) {
      g = 255;
    }
    if (i == secondPixel) {
      b = 255;
    }
    ring.setPixelColor(i, ring.Color(r, g, b));
  }
  ring.show();
  delay(100);  // redraw ten times a second
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Projects

Practice on your own: Arduino playground