15th June 2015 | By:

How to Build a Binary Clock [PART 1]

Electronics have always been very interesting for me, but I’ve never had a lot of opportunities and tools to try it. Now, as our office has become more of an electronics lab, I can start to get closer to the electronic part of world.

I decided to begin with building a binary clock. It seems to be easy to build and definitely cool to have on my desk. There are a lot of projects online with ready-to-go plans for this kind of thing, however I wanted to learn something new, so I decided to find my own way to create it. The basic prototype was built on an Arduino UNO and the whole concept transferred into a custom built PCB board with an Atmel processor.


How the binary clock works:

Reading the time in binary is fairly easy. Each diode represents a power of 2. The clock has three compartments for hours, minutes and seconds respectively. To read the time you need to add the lit diodes for each compartment.

Simple board schematic:

Screen Shot 2015-06-11 at 10.40.22

The algorithm:

The first task was to write common functions to turn on and off the right diodes respectively for the decimal value of the time. For that it’s enough to have only the seconds compartment. The algorithm I wrote is built from three basic functions and a few constants:

typedef enum {SEC_1 = 10, SEC_2 = 11, SEC_3 = 12, SEC_4 = 13, SEC_10 = 7, SEC_20 = 8, SEC_30 = 9} SECONDS_MAP; // Map for pins
const uint8_t VALUES_MAP[] = {1, 2, 4, 8}; // Map for powers of 2

The function to calculate value for particular diodes:

void set_pins(uint8_t *pins_list, uint8_t pins_list_size, uint8_t time_part){
  uint8_t quotient;

  // Specify if diode should be turned on or off
  for(int i=pins_list_size - 1; i>=0; --i){
    uint8_t val = LOW; // initial value to assign for pin
    quotient = time_part / VALUES_MAP[i]; // int division (eg. 2/4 = 0, 3/2 = 1)

    if(quotient){ // If quotient greater than 0 set HIGH value for diode and decrease the initial value of time
      time_part -= VALUES_MAP[i];
      val =  HIGH;
    digitalWrite(pins_list[i], val); // digitalWrite sets value for pin(helper function from Arduino library)

The next function is designed to control separate compartments.

void control_compartment(uint8_t time_part, uint8_t *decimal_pin_numbers, uint8_t *unity_pin_numbers){
  uint8_t unity = time_part % 10; // unity part of time (eg. for seconds 56 is number 6)
  uint8_t decimal = time_part / 10; // decimal part of time (eg. for seconds 56 is number 5)

  set_pins(decimal_pin_numbers, 3, decimal); // Calculate which pins turns on for decimal part
  set_pins(unity_pin_numbers, 4, unity); // Calculate which pins turns on for unity part

Last bit will set up the initial mode of pins and control the whole workflow of the program and will execute in an infinite loop.

void setup() { // setup function is a helper function from Arduino
  for(int i=SEC_1; i<=SEC_4; i++){
    pinMode(i, OUTPUT); // Set OUTPUT mode for each pin

void loop() { // loop function is a helper function from Arduino
  uint8_t sec = (millis()/1000) % 60; // Just for prototype, take seconds since the program has been running

  uint8_t decimal_pins[] = {SEC_10, SEC_20, SEC_30}; // Specify pins for decimal part of seconds
  uint8_t unity_pins[] = {SEC_1, SEC_2, SEC_3, SEC_4}; // Specify pins for unity part of seconds

  control_compartment(sec, decimal_pins, unity_pins); // Run the control function for compartment

This was just a prototype to start with. The next step is to move the logic onto a custom PCB without using an Arduino.

Screen Shot 2015-06-11 at 10.55.06

Tags: , , , ,

Leave a reply

Your email address will not be published. Not now, not ever. Required fields are marked *


You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>