Introduction: XCLOCK (Tri-Colour Binary Clock)

About: I love making things. I have for as long as I can remember liked to make stuff. Now days I have two kids (Thomas and Emma) and most of the things I do are safe for them! I love electronics and Microchips, I ha…

This is my current state of mind, colorful but impossible to read.

So after last years clock building i still had some unfinished business. and if i am honest this wasn't one of them! but like so many of my projects i happened to have all the bits i needed to make this project so it happened!

This is a 24 hour clock with seconds. the display is 3 X's with each right side of a X indicating units and the left side tens. Now obviously there are only two segments which in binary means 4 possibilities (including zero) so i decided to use 3 different colours so show all the numbers! Red will indicate 1-3, green 4-6, and blue 7-9.

So let's get straight onto the build. it's the same construction method i like to use, which is design on a raspberry pi using Qcad, then save as a PDF. Then print out the design and stick to plywood then cut out using a fret saw.

The parts list is as follows...

3mm (1/8) plywood. About a square foot should do.

12 squares off frosted perspex 20 * 20mm (3mm thick)

off cuts of 1/2" balsa to space the two perspex layers.

Arduino Nano.

Real Time Clock DS1307.

4 buttons (push to make, momentary).

Small piece of veroboard.

Switch. SPDT

Battery holder (AAA * 4)

Resistors 100Ω,180Ω, 390Ω, 820Ω (*2) and 10KΩ, all i believe 1/8 Watt.

12 * WS2812B (full colour LED's with built in controller)

Black paint.

Step 1: The Casing Build.

So from the first page you should have seen all the bits which were cut out from 3mm plywood. As is the case with most of my projects i try to double up where i can to cut down on fret time. Before separating the perspex holding pieces it's worth checking the perspex fits in accurately but not to tight. Once you are happy with the fit you can glue the wood pieces together. i glued the sides and top together, and at the same time glued the balsa bits to front and then glued the rear two pieces of ply together. When the glue was dry i then temporarily positioned the perspex pieces in the correct places and glued the front and rear sections of ply into place making sure the perspex was flush with the front of the clock.

At this point i tried the led's with the perspex to see what the light was like, and found out that because the perspex is frosted all the light comes out of the sides and illuminates the other sections! so i then decided to spray the perspex pieces black (on both sides) But then when i next tried it the overspray had covered the ends! so i used a cotton bud with solvent to clean of the paint.

After one final check i then glued the perspex into place using 5 minute epoxy. i only put a very small blob on the end either side of where the LED will mount.

Lastly in this section i glued all the LED's into place with a good dollop of glue as i figured it would help with the light transmission? i tried to line up the LED's so all the positives were on the inside and negatives on the outside.

Step 2: The Electronics

I have used a couple off really nice tricks with this project and was very pleased with the outcome! The Arduino Nano board has loads of input and output pins but i have only used 5! all the LED's use just one pin (plus power) and the RTC used 2 pins, the switch then uses another digital input pin and finally the 4 buttons use just one analog pin.

So firstly i wired up all the LED's, these LED's are really nice to work with each one needs positive (5V) and ground and then a Data wire. looking from the front the right bottom LED is number one and the one above it is number two, then you move onto the other half of the X, again starting at the bottom segment and then going up. the same pattern is used all along. just make sure you put the data wire on the Din (Data input) of the first then from the Dout (Data out) of the first to the Din of the second, and so on. I decided to run the power and ground in a ring circuit and then common up the ends into a 3 wire servo lead.

Next i made up the buttons board, hopefully you should be able to see the construction in the above pictures. the resistors were chosen to be approximately double each time, and the idea is the switches all run in series and when a button is pressed it shorts out its resistor. At the end of the series is the final 820Ω resistor which prevents you shorting out the supply if all buttons are pressed at once! This means you get a different voltage at the end of the buttons for each combination of button presses (16 in total). i spent a bit of time getting this correct using the serial monitor to show me the analogue value with each button press, and i got very close to the values i calculated. The program uses values to check whether the result is higher or lower than a mid value, so with each check you cut the options in half and by the 4th check you have you result.

There really isn't much more to this project. just a couple of minor points to say.

When you switch to SET the RTC seconds is constantly reset, and will only start counting again when you set the switch to run. this is easy to implement, you just read the RTC then do a modulo calculation by doing %60 and subtracting the result from the RTC.

Lastly on each hour the clock does a nice rainbow pattern for a few seconds.

Step 3: Arduino Code.

#include 
#include 
#include 
#include 
#define PIN 17
int h = 0;
int b = 0;
int i = 0;
int j = 0;
int k = 0; 
int x = 0;
const int analogInput = A6;
const int setRun = 2;
tmElements_t tm;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  pinMode(setRun, INPUT);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  rainbowCycle(20);
  //Serial.begin(9600);
}
void readButtons()//there are 16 possible combinations of button
//presses, but i am only bothered by H and M + and -,
//i have also included a show rainbow on both minutes pressed.
{
  int checkSetRun = digitalRead(setRun);
  if (checkSetRun == 1)
  {
    int buttonVal = 0;
    unsigned long v = RTC.get();
    long rz = v%60;
    v = v - rz;
    buttonVal = analogRead(A6);
    //Serial.print("Button Value = ");
    //Serial.print(buttonVal);
    if (buttonVal < 486)//must be 8,9,10,11,12,13,14,15
    {
      if (buttonVal < 295)//must be 12,13,14,15
      {
        if (buttonVal < 148)//must be 14,15
        {
          if (buttonVal < 56)//must be 15
          {
            //Serial.print(" Buttons pressed 1,2,3,4 (15 pos 1,2,4,8)");
          }
          else//must be 14
          {
            //Serial.print(" Buttons pressed 2,3,4 (14 pos 2,4,8)");
          }
        }
        else//must be 12,13
        {
          if (buttonVal < 222)//must be 13
          {
            //Serial.print(" Buttons pressed 1,3,4 (13 pos 1,4,8)");
          }
          else//must be 12, add 1 hour and 1 minute
          {
            //Serial.print(" Buttons pressed 3,4 (12 pos 4,8)");
            v = v +3660;
          }
        }
      }
      else//must be 8,9,10,11
      {
        if (buttonVal < 401)//must be 10,11
        {
          if (buttonVal < 356)//must be 11,
          {
            //Serial.print(" Buttons pressed 1,2,4 (11 pos 1,2,8)");
          }
          else//must be 10, plus one hour, subtract one minute.
          {
            //Serial.print(" Buttons pressed 2,4 (10 pos 2,8)");
            v = v + 3660;
          }
        }
        else//must be 8,9
        {
          if (buttonVal < 440)//must be 9, both hours pressed, do a pattern?
          {
            //Serial.print(" Buttons pressed 1,4 (9 pos 1,8)");
          }
          else// must be 8, plus one hour.
          {
            //Serial.print(" Add one hour");
            v = v + 3600;
          }
        }
      }
    }
    else//must be 0,1,2,3,4,5,6,7
    {
      if (buttonVal < 598)//must be 4,5,6,7
      {
        if (buttonVal < 551)//must be 6,7
        {
          if (buttonVal < 526)//must be 7
          {
            //Serial.print(" Buttons pressed 1,2,3 (7 pos 1,2,4)");
          }
          else//must be 6, both minutes pressed, do a pattern? reset seconds to zero
          {
            //Serial.print(" Buttons pressed 2,3 (6 pos 2,4)");
            rainbowCycle(20);
          }
        }
        else//must 4,5
        {
          if (buttonVal < 574)//must be 5, minus one hour plus one minute.
          {
            //Serial.print(" Buttons pressed 1,3 (5 pos 1,4)");
            v = v - 3540;
          }
          else//must be 4, plus one minute.
          {
            //Serial.print(" Add one minute");
            v = v + 60;
          }
        }
      }
      else//must be 0,1,2,3
      {
        if (buttonVal < 636)//must be 2,3
        {
          if (buttonVal < 619)//must be 3, minus one hour and one minute.
          {
            //Serial.print(" Buttons pressed 1,2 (3 pos 1,2)");
            v = v - 3660;
          }
          else//must be 2, minus one minute
          {
            //Serial.print(" Minus one minute");
            v = v - 60;
          }
        }
        else//must be 0,1
        {
          if (buttonVal < 652)//must be 1, minus one hour.
          {
            //Serial.print(" Minus one hour");
            v = v - 3600;
          }
          else//must be 0
          {
            //Serial.print(" Buttons pressed none (0 pos)");
          }
        }
      }
    }
  //Serial.println();
  RTC.set(v);
  delay(200);
  }
  else
  {
    Serial.println("Run.");
  }
}
void scanDisplay(int loopies,int bri,int delayy)
{
  for(b=0; b= 10)
  {
    int tens = number / 10;
    int units = number - (tens * 10);
    tenNumbers(units,pos);
    pos = pos + 2;
    tenNumbers(tens,pos);
  }
  else 
  {
    int tens = 0;
    int units = number;
    tenNumbers(units,pos);
    pos = pos + 2;
    tenNumbers(tens,pos);
  }
}

void loop()
{
  if (RTC.read(tm))
  {
    j = (tm.Second);
    i = (tm.Minute);
    k = (tm.Hour);
    obtainNo(j,0);
    obtainNo(i,4);
    obtainNo(k,8);
    readButtons();
    delay(200);
    int checkSetRun = digitalRead(setRun);
    if (checkSetRun == 1)
    {
      //
    }
    else
    {
      if (j == 0 && i == 0)
      {
        rainbowCycle(20);
      }
    }
  }
}

void DelayTime(int v)
{
  strip.show();
  delay(v);
}
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*2; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
void blankIt()
{
  int b = 0;
  for (b= 0; b
Epilog Contest 8

Participated in the
Epilog Contest 8

Make it Glow Contest 2016

Participated in the
Make it Glow Contest 2016

Arduino Contest 2016

Participated in the
Arduino Contest 2016