Step 9: Prototyping the Display, Time Setting, and Seconds

Now that we have the base program for running a binary clock, the know-how to read from potentiometers, and are experts in using ammeters, it's time to put it all together! It may look like a rat's nest of cables and components, but you shouldn't have any issues if you follow along step-by-step.

In the following video, I use the reset switch on the Uno to start our program from the beginning (time 00:00). You can see the seconds counting on the analog meter which unfortunately has a max value of 50, not 60 (but we can open it up and swap out the background if desired). Regardless of what the meter reads, it "ticks" 60 times per minute. After a full minute, we see the time change to 00:01, and the analog meter resets. I later switch into time setting mode (this is when the orange LED at the top center turns on), at which point you can see the seconds reset to 0. I set the time to 16:59, and the moment I turn time setting mode off (the orange LED at the top center turns off), the seconds on the analog meter start to count up again. I then wait another minute, at which point the time changes to 17:00.

The Final Code
  Cwik Clock v1.0 - Prototyping the Display
  Author: Dennis Cwik
  Date: July 23, 2012
  This program is the controller for a binary clock, with LEDs
  attached to digital pins 0 through 10, 12, and 13. 2 potentiometers
  connected to A0 and A1 control the hours and minutes respectively,
  and only when A2 is pulled high. When A2 is pulled high, an LED on
  pin A5 will light up to tell the user that they are in time set mode.
  Finally, pin 11 is used with PWM to show the seconds on an analog
  This example code is in the public domain.

// This can be modified for debug purposes to make a minute go by quicker.
int ONE_SECOND = 1000; // measured in milliseconds
int DELAY_BETWEEN_LOOP_CALLS = 200; // measured in milliseconds

// I didn't come up with this, it's from the arduino documentation
unsigned long MAX_UNSIGNED_LONG = 4294967295; // = (2 ^ 32) - 1


// 1st column of LEDs
int PIN_MIN1 = 0;
int PIN_MIN2 = 1;
int PIN_MIN4 = 2;
int PIN_MIN8 = 3;

// 2nd column of LEDs
int PIN_MIN10 = 4;
int PIN_MIN20 = 5;
int PIN_MIN40 = 6;

// 3rd column of LEDs
int PIN_HOUR1 = 7;
int PIN_HOUR2 = 8;
int PIN_HOUR4 = 9;
int PIN_HOUR8 = 10;

// PWM on the analog meter to display seconds.
int SEC_OUTPUT_PIN = 11;

// 4th column of LEDs
int PIN_HOUR10 = 12;
int PIN_HOUR20 = 13;

// the last time the seconds in the time were incremented
unsigned long m_lastTick;

// used to tell us if we're setting the time or not
boolean m_inTimeSetMode = false;

// the time
byte m_second;
byte m_minute;
byte m_hour;

* Mandatory setup routine for Arduino, is run once at the very beginning.
void setup()
  // using one of the analog inputs as output
  // initialize the pins used for outputting time
  pinMode(PIN_MIN1, OUTPUT);
  pinMode(PIN_MIN2, OUTPUT);
  pinMode(PIN_MIN4, OUTPUT);
  pinMode(PIN_MIN8, OUTPUT);
  pinMode(PIN_MIN10, OUTPUT);
  pinMode(PIN_MIN20, OUTPUT);
  pinMode(PIN_MIN40, OUTPUT);
  pinMode(PIN_HOUR1, OUTPUT);
  pinMode(PIN_HOUR2, OUTPUT);
  pinMode(PIN_HOUR4, OUTPUT);
  pinMode(PIN_HOUR8, OUTPUT);
  pinMode(PIN_HOUR10, OUTPUT);
  pinMode(PIN_HOUR20, OUTPUT);
  // initialize clock variables
  m_lastTick = 0;
  setTime(0, 0, 0);

* Mandatory method for Arduino, it's called continuously after setup().
void loop()
  // see if we're setting the time, or letting time flow normally
  if (m_inTimeSetMode)
  // now that the time has been updated, show the time
  // arbitrary delay so that we're not processing away 100% of the time,
  // an act of power saving

* A helper method to set m_hour, m_minute, and m_second.
void setTime(byte newHour, byte newMinute, byte newSecond)
  m_second = newSecond;
  m_minute = newMinute;
  m_hour = newHour;

* This method keeps track of the logical flow of time. If enough time has
* passed since the last time it was called, m_second, m_minute, and m_hour
* will be updated appropriate. This takes into account that millis() rolls
* over roughly every 50 days.
void tick()
  unsigned long now = millis();
  unsigned long msElapsed;
  // first we need to find out how much time has passed since the last time we
  // called tick()
  if (now < m_lastTick)
    // gasp, either we've succeeded in travelling back in time, or millis() wrapped around!
    msElapsed = (MAX_UNSIGNED_LONG - m_lastTick) + now;
    msElapsed = now - m_lastTick;
  // for each second that has passed (hopefully just 1, unless our code is really laggy),
  // add 1 second to the time, and increase the minutes & hours if necessary
  for (int i = 0; i < msElapsed / ONE_SECOND; ++i)
    m_lastTick = m_lastTick + ONE_SECOND;
    if (m_second == 60)
      m_second = 0;
      if (m_minute == 60)
        m_minute = 0;
        if (m_hour == 24)
          m_hour = 0;

* This method uses PWM to display the m_second on an analog meter connected
void displaySeconds()
  analogWrite(SEC_OUTPUT_PIN, map(m_second, 0, 59, 0, 255));

* This method reads the m_minute, converts it to binary, and displays
* it on the appropriate LEDs (those being PIN_MIN*).
void displayMinutes()
  byte ones = m_minute % 10;
  digitalWrite(PIN_MIN1, ones & B1);
  digitalWrite(PIN_MIN2, ones & B10);
  digitalWrite(PIN_MIN4, ones & B100);
  digitalWrite(PIN_MIN8, ones & B1000);
  // division is kind of expensive, but we'll assume the compile optimizes this for us :)
  byte tens = m_minute / 10;
  digitalWrite(PIN_MIN10, tens & B1);
  digitalWrite(PIN_MIN20, tens & B10);
  digitalWrite(PIN_MIN40, tens & B100);

* This method reads the m_hour, converts it to binary, and displays
* it on the appropriate LEDs (those being PIN_HOUR*).
void displayHours()
  byte ones = m_hour % 10;
  digitalWrite(PIN_HOUR1, ones & B1);
  digitalWrite(PIN_HOUR2, ones & B10);
  digitalWrite(PIN_HOUR4, ones & B100);
  digitalWrite(PIN_HOUR8, ones & B1000);
  byte tens = m_hour / 10;
  digitalWrite(PIN_HOUR10, tens & B1);
  digitalWrite(PIN_HOUR20, tens & B10);

* This method reads the values from the 2 potentiometers, converts them to
* mimnutes and hours, and sets m_minute and m_hour to the associated values.
void getTimeFromPots()
  // read the potentiometers
  int hourSensor = analogRead(HOUR_INPUT_PIN);
  int minuteSensor = analogRead(MIN_INPUT_PIN);
  // scale the sensor readings (from 0 to 1023) to the appropriate
  // scale (0 to 23 for hours, 0 to 59 for minutes)
  setTime(map(hourSensor, 0, 1023, 0, 23), map(minuteSensor, 0, 1023, 0, 59), 0);
  // we set the last tick to now, because when we set m_inTimeSetMode to false,
  // many seconds could have passed since the last one, and the time would jump ahead
  m_lastTick = millis();

* This method checks CLOCK_MODE_SWITCH_PIN to see if it's HIGH. If it is,
* it means we're now in clock set mode (m_inTimeSetMode is set to true), and
* turns the CLOCK_MODE_LED_PIN on.
void checkMode()
  m_inTimeSetMode = (analogRead(CLOCK_MODE_SWITCH_PIN) > 512);
  digitalWrite(CLOCK_MODE_LED_PIN, m_inTimeSetMode);
The analog second meter is beautiful. Great aesthetic on this thing, and great attention to detail. Well done.
<p>Could anybody help? It's not working... my power cable has a light on it when its on and as soon as I plug this in it goes off so maybe its shorting? I have no idea but here's some pictures just in case there is anything glaringly obvious...</p>
<p>It's really hard to tell from pictures. I'd recommend trying 2 things.</p><p>First, try and see if you've accidentally shorted out 2 rows together. Either look for basically zero resistance between rows (if you don't have a volt meter, you can hook up an LED with a resistor and power source, and see if you can light up the LED by connecting it across 2 rows).</p><p>Next, make sure the chip is functioning properly. If you have spare supplies, build the same circuit on a bread board and make sure it still functions as expected. The biggest risk is having heat destroy the chip, so make sure all of your soldering is done with the chip off of the board.</p><p>If after these 2 things you're still having no luck, it's the painful process of figuring out where your circuit strays from the design.</p><p>Good luck!</p>
<p>Trying to find a similar enclosure but I don't know what I'm looking for, what was it originally? Love this clock btw! Have slowly mastered the circuit just trying to get hold of all the stuff and hopefully mine will turn out half as good as yours </p>
<p>Any store like a RadioShack or Fry's should have &quot;project boxes&quot; (just ask for enclosure for hobby circuitry), it's just a matter of what size and shapes they have. I really lucked out in terms of finding a compact box, and one with the angled front.</p><p>Glad to hear the circuit part went well, and good luck with finding the right box!</p>
<p>Hi again! slowly getting together all the stuff to get started (verrrryy slowly i know) gonna leave the enclosure till i know how big i'm going to make it! As for the analog meter, I'm finding that voltmeters are cheaper than uA ammeters for whatever reason, as the voltage of the circuit is alternating between 0 to 5V could I use a 5V voltmeter without the 100k ohm resistor? would that work? Thanks again! </p>
<p>Sorry for the late response. I'm not sure how a voltmeter reacts with no load. I haven't touched arduino in a while, but you'd probably have to set the pin to high impedence to make it work with just the volt meter. In theory it should work.</p><p>On the other hand, resistors are so cheap, you could throw a resistor with very high resistance (eg, 10K ohm or even larger if you want) on there so that current will be very low, thus reducing heat, and then hook up the voltmeter in parallel with the resistor.</p><p>The 5V voltmeter should work just fine. However, if for some reason the digital pin doesn't supply 5V (eg, maybe it only supplies 4.5V), you could get a smaller voltmeter, like 1V, use 2 resistors of appropriate resistance in series, and measure the voltage drop across one. For example, have the 2 resistors add up to 10K ohm, and together they drop the entire 4.5V. To drop 1V on one of the resistors, it must be (1V / 4.5V) * 10K ohm = 2.2K ohm. That means the other resistor must be 7.8K ohm (ie, 10K ohm - 2.2K ohm). Hook the 2 resistors up in series, and hook the voltmeter up in parallel with the 2.2K ohm resistor. If this isn't making any sense, do a quick search for &quot;voltage division series&quot;.</p>
<p>Had been sitting on these parts since the Instructable was posted. Finally got around to doing it. I used the extra Led to change the clock to an AM/PM 12 hour clock. Basically any time over 12 hours like 15:00 shows 3:00 with the PM light on. Also changed the hour &quot;0&quot; to display as 12. I really learned some things about programming using time. Very fun instructable. Had a heck of a time sourcing the meter, but got lucky on Ebay and found a domestic source, although its milliamps instead of microamps, was able to change the resistor to match the output.</p>
This is really nice work. I love how the analog meter makes it look like retro lab equipment.&nbsp; I am definitely going to make one.&nbsp; I just hope it comes out as nice as yours!&nbsp; I haven't read all of this yet so excuse me if you already mentioned this..<br> <br> Its pretty easy to take the front plastic off analog meters like that and print out your own scale at home. We do it all the time at work to convert 5v meters to Torr meters for vacuum equipment. Play with the design a little and use some nice paper and they look like you purchased them.
I had considered printing my own scale and even painting the tip of the needle red or bright orange, but was afraid of making it look too amateur. The one I bought looked really clean. It also had a metal background, and the stripe that goes across is this unpainted silver finish that I really grew fond of. Although it is a bit weird that the scale only goes to 50.
The analog meter adds a real charm to it. I've thought about building a binary clock for a while, but I wanted something different. I'm going to go find an analog meter right now.
Thanks! I really feel the analog meter is the eye-catcher of the whole clock but wasn't as easy as I thought it would be to get. I bought one from a 3rd party seller on amazon and took many weeks to ship. In the meantime I really wanted to finish the project so I went to a local electronics shop where I found the meter I eventually used in the final product (the one in the pictures), however they only had a single unit in that current range. I hope you have better luck than I did finding an elegant meter!
Is the one led in the left column a dummy?
Yes, the top left LED indicates whether you're in time setting mode while the one below it is completely for show and is not wired up to anything. It'll never light up.
Simply great. I really enjoy the aesthetic of it; has that industrial appeal.
Where did you get this enclosure? I think it looks pretty cool and I would like to get one for a different kind of clock i'm making.
I got it at Fry's Electronics (in store, not online) for roughly $10. FYI, the holes for the screws are not pre-threaded so you've got to be a bit careful not to strip them or start them at a bad angle.
Cool, thanks
Hello <br> <br>I am wanting to use LEDs for the seconds instead of an analog meter. However, I need 7 LEDs for such thing. How would I go about this? Some sort of shift register IC just for the seconds part? Multiplexing? <br> <br>What would you recommend? <br> <br>Also, do you think rotary encoders would be better for adjusting since you can keep turning them?
Oh, and in case it wasn't obvious, its because I havent got enough pins on my UNO R3. :)
I had bookmarked this page for later when I needed more pins as it details using a shift register: <br>http://arduino.cc/en/Tutorial/ShiftOut <br> <br>Another option is to use a column with 6 LEDs: <br>o &lt;-- 32 <br>o &lt;-- 16 <br>o &lt;-- 8 <br>o &lt;-- 4 <br>o &lt;-- 2 <br>o &lt;-- 1 <br> <br>I actually didn't know about the rotary encoder, so thanks for bring that to my attention. I personally like the fact that the knobs stop at the minimum and maximum values using potentiometers, but one benefit of the rotary encoder is that you could set its current reading to the current time when going into time setting mode (ie, toggling the time setting switch wouldn't change the time to whatever you left the knobs at last).
EXCELLENT! Nicely done!

About This Instructable


68 favorites


Bio: I'm a software development engineer by day, and a geek by night.
More by cwik: Cwik Clock v1.0 - An Arduino Binary Clock
Add instructable to: