Introduction: 12 Hr Binary Clock, Hours and Minutes Only, DS1307 RTC, I2C, Arduino-Nano

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…

For a while now I have wanted to make a binary clock, but after looking around I decided I wanted something just a bit different. So I decided to only display the hours and minutes and only display a 12 hours clock, this means you only need 3 columns and the pattern of LED’s looks neater. Also with only 11 LED’s you don’t need to multiplex, you can just drive the LEDs on the output pins directly.

So with the above in mind I had decided on the design, all I really needed was a suitable case and while I was sat in front of my computer I realised the small speaker would make an idea case.

So the basic set up is 11 LED's and resistors linked to a Arduino NANO, a DS1307 RTC connected to the NANO via i2C and then two buttons to adjust the hours and minutes, all fitted into a "dumb" speaker using 5volts supply from the active usb powered speaker.

Step 1: The LED Board

So to start with I am using 5mm Green LEDS and these along with the resistors are all soldered onto a small piece of breadboard 17 tracks wide by 17 long. The resistors are 470ohm and as you can see in the photos I have soldered 3 on the correct side of the breadboard but the rest of the resistors and the links were soldered onto the track side (the wrong side) Where the legs of the resistors go over other tracks I have covered them using insulation stripped from single core wire. Have a good look at the photos as there are several track breaks
under some resistors. All the resistors have a common ground, which means that 3 of the tracks are ground which allows the RTC and Arduino nano to get the ground from the breadboard.

I haven’t gone into much detail about the LED board as it’s not too hard to complete, and you may wish to change the spacing. The 11 LEDs connect to pins 2 to 12 on the nano (via a 470ohm resistor) it doesn’t really matter which order you put them as long as you define the order in the sketch.

After I had completed the LEDs and resistors and links I soldered on different coloured wires to the edge and then checked each LED worked.

Just in case you don't understand Binary clocks, the right column displays the units of minutes (0-9) the middle column displays the tens of minutes (0-5) and the left column displays the hours (1-12). In all cases the bottom LED is worth 1 the second is worth 2 the third 4 and the 4th is worth 8, to get the time you add up all the LED's in the column which are illuminated to give the number.

You may have spotted in one of the pictures above that I managed to pick up the wrong value resistor and solder it in place. I spotted it and replaced it as I did the links.

Step 2: The Aduino Nano.

Once the LED board was complete and checked to be working I Then used foam double sided tape and stuck the Arduino Nano on top of the resistors. Then looped the previously connected wired from the breadboard to the input pins, at this stage I just soldered then all in place neatly not worrying about the pin order, the last connection from the breadboard to the Nano is the ground, again to keep it neat I choose the ground pin next to the digital pin 2.

Step 3: RTC DS1307 Connected Via I2C

Next to be wired is the RTC module, the Tiny RTC I2C DS1307 Clock Module was brought from Ebay and cost about £1.00. It connects to the nano via i2C on pins A4 and A5 (A5 SCL and A4 SDA). The module also needs a ground and 5volt, the ground was from the breadboard and the 5 volts was from the VCC pin next to A4. The RTC module will be foam tapped to the speaker so the wires are about 5” long.

Step 4: Hour and Minute Adjust Buttons.

The buttons were what I had laying around, they are a bit too big and I would have preferred black, but that are what I had and as they are mounted on the back it doesn’t really matter. I chose to mount the buttons either side of the cable entry hole. The holes had to be 12mm so I drilled in steps and at 9mm I filed to the correct size aligning the holes so they looked even. All the wires were then connected, the buttons to the nano (via the inline resistors) and the 4 core speaker and USB cable to the relevant connections (ground and “RAW” on the nano)

The buttons are single pole, normally open (momentary close). They are wired so they are pulled down to ground via a 10K resistor and set to 5volts when the button is pressed. A 1k resistor is on each input to the nano. I decided to connect the resistors to the wires as shown in the photos, it’s a neat way to connect the switches and as long as you cover the connections with heatshrink you shouldn’t have any problems with shorts. The two buttons connect to A0 and A1 which can be configured to digital by adding 14 to the pin number so pin A0 is 14 and A1 is 15. One button is for the hour adjust and the other for the minutes, each button just adds either a minute or hour to the clock.

Step 5: Fitting the Clock Into the Speaker

The speaker looked ideal to house the LED’s and as the speakers were amplified I could use the USB voltage to power the clock. However the speaker which has the amplifier and the USB 5 volts didn’t have room for the clock so the “slave” speaker was going to be used to house the clock, I was then going to run an extra pair of wires from the amplified speaker to the slave to supply the 5 volts.

I then had a light bulb moment and realised I could use an old USB keyboard cable and replace the existing 2 wire cable. This meant a little more work but I think it was worth it. One thing I will point out is that you should not use a mouse cable as within each core of the 4 wires are fibres of plastic? So it is a bit harder to work with. The keyboard cable is slightly bigger in diameter but the cores don’t have fibres in them and are a bigger diameter. You can see in the photos the 4 connections I made at each end. In one photo you can see the difference in the mouse cable and keyboard cable, the green wire is the mouse cable and has plastic strands in each core, the red wire is from the keyboard and is tinned copper.

To mount the LEDs in the slave speaker I firstly masked the front with tape then marked out the 11 holes. Because I have used breadboard the spacing is nice and even with each column 0.5” apart and 0.4” between LEDs in each column. Take care not to get carried away and drill out the middle top LED, as there isn’t an LED in that position!

When drilling the masking tape helps to stop the drill bit wondering and if you start with a 2mm drill you can check everything is in line before drilling bigger, and even then I prefer to drill in steps using a 3.3mm drill then lastly 5mm.

Step 6: The Arduino NANO Program Explained and Libraries Needed/

The program uses the RTC library and the time library which was downloaded from:

http://www.pjrc.com/teensy/td_libs_DS1307RTC.html

Make sure you unzip the libraries into the Arduino/ libraries file.

I then programed the binary clock using a simple decimal to binary code. However I had a few problems as the RTC returns a time value in 24 hour format, so to overcome this problem I firstly check if the hours is zero and if it is, set it to 12. Then if the hour’s value is greater than 13 then I subtract 12. That sorts out the 24 hour time. Then we come to setting the time, the hours and minutes are adjusted by adding to the “raw” time code, 60 is added for each minute and 3600 for each hour.

if (digitalRead(setM) == HIGH)

{

unsigned long j = RTC.get();

j = j + 60;

RTC.set(j);

}

if (digitalRead(setH) == HIGH)

{

unsigned long j = RTC.get();

j = j + 3600;

RTC.set(j);

}

There is a little problem with this code, if you load this code into your Arduino and nothing happens then you may need to set the RTC using the “setTime” sketch in the Sketchbook/libraries/DS1307RTC/setTime file. Once loaded click the serial monitor to check the time is correct, from what I can work out if you buy a new RTC module it needs to be “started” else it won’t be active. Then reload the binaryRTC code again and everything should work.

I have listed the code, but please note I am not very good at programming so don’t expect too much!

Step 7: The Full Program.

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
const int setH = 14; //button for hour increase
const int setM = 15; // button for minute increase
const int UnitMin01 = 12;
const int UnitMin02 = 9;
const int UnitMin04 = 8;
const int UnitMin08 = 7;
const int UnitTen01 = 2;
const int UnitTen02 = 11;
const int UnitTen04 = 10;
const int UnitHrs01 = 3;
const int UnitHrs02 = 4;
const int UnitHrs04 = 5;
const int UnitHrs08 = 6;

void setup()
{
  delay(200);
  pinMode(setH, INPUT);
  pinMode(setM, INPUT);
  pinMode(UnitMin01, OUTPUT);
  pinMode(UnitMin02, OUTPUT);
  pinMode(UnitMin04, OUTPUT);
  pinMode(UnitMin08, OUTPUT);
  pinMode(UnitTen01, OUTPUT);
  pinMode(UnitTen02, OUTPUT);
  pinMode(UnitTen04, OUTPUT);
  pinMode(UnitHrs01, OUTPUT);
  pinMode(UnitHrs02, OUTPUT);
  pinMode(UnitHrs04, OUTPUT);
  pinMode(UnitHrs08, OUTPUT);
}
void loop()
{
  tmElements_t tm;
  if (RTC.read(tm))
  {
    if (digitalRead(setM) == HIGH)
    {
      unsigned long j = RTC.get();
      j = j + 60;
      RTC.set(j);
    } 
    if (digitalRead(setH) == HIGH)
    {
      unsigned long j = RTC.get();
      j = j + 3600;
      RTC.set(j);
    }
    binaryOutputHours(tm.Hour);
    binaryOutputMinutes(tm.Minute); 
  }
  delay(1000);
}
  
void binaryOutputHours(int number)
{
  if (number == 0)
  {
    number = 12;
  } 
  if (number >= 13)
  {
    number = number - 12;
  }
  setBinaryHours(number);
} 
  
void binaryOutputMinutes(int number)
{
  if (number >= 10)
  {
    int tens = number/10;
    int units = number - (tens*10);
    setBinaryMins(units);
    setBinaryTens(tens);
  }
  else 
  {
    int tens = 0;
    int units = number;
    setBinaryMins(units);
    setBinaryTens(tens);
  }
} 

void setBinaryMins(int units)
{
  if (units >= 8)
  {
    digitalWrite(UnitMin08, HIGH);
    units = units - 8;
  }
  else
  {
    digitalWrite(UnitMin08, LOW);
  }
  if (units >= 4)
  {
    digitalWrite(UnitMin04, HIGH);
    units = units - 4;
  }
  else
  {
    digitalWrite(UnitMin04, LOW);
  }
  if (units >= 2)
  {
    digitalWrite(UnitMin02, HIGH);
    units = units - 2;
  }
  else
  {
    digitalWrite(UnitMin02, LOW);
  }
  if (units >= 1)
  {
    digitalWrite(UnitMin01, HIGH);
    units = units - 1;
  }
  else
  {
    digitalWrite(UnitMin01, LOW);
  }
}
void setBinaryTens(int tens)
{
  if (tens >= 4)
  {
    digitalWrite(UnitTen04, HIGH);
    tens = tens - 4;
  }
  else
  {
    digitalWrite(UnitTen04, LOW);
  }
  if (tens >= 2)
  {
    digitalWrite(UnitTen02, HIGH);
    tens = tens - 2;
  }
  else
  {
    digitalWrite(UnitTen02, LOW);
  }
  if (tens >= 1)
  {
    digitalWrite(UnitTen01, HIGH);
    tens = tens - 1;
  }
  else
  {
    digitalWrite(UnitTen01, LOW);
  }
}
   
void setBinaryHours(int hours)
{
  if (hours >= 8)
  {
    digitalWrite(UnitHrs08, HIGH);
    hours = hours - 8;
  }
  else
  {
    digitalWrite(UnitHrs08, LOW);
  }
  if (hours >= 4)
  {
    digitalWrite(UnitHrs04, HIGH);
    hours = hours - 4;
  }
  else
  {
    digitalWrite(UnitHrs04, LOW);
  }
  if (hours >= 2)
  {
    digitalWrite(UnitHrs02, HIGH);
    hours = hours - 2;
  }
  else
  {
    digitalWrite(UnitHrs02, LOW);
  }
  if (hours >= 1)
  {
    digitalWrite(UnitHrs01, HIGH);
    hours = hours - 1;
  }
  else
  {
    digitalWrite(UnitHrs01, LOW);
  }
}