Tuesday, February 16, 2010

Dot Matrix Arduino Clock

The great adventure that is building clocks continues.  Points of interest in this build is that it was the first chance I got to play with the dot matrix display I picked up over winter break, and it's the first time I've soldered and used a surface mount package (albeit I soldered it to a DIP breakout board so that I could plug it into a breadboard; I know, very meta).

Video Introduction:

This clock displays all of its values in binary, which means that each row, from bottom to top, is worth one, two, four, eight, 16, and 32, and as each LED is lit, you add them together to get the final value.  From left to right is the current month, current day of the month, hour (twelve hour based with PM indicator top center), minutes and seconds.  There is currently no way to set the time short of plugging the board into a computer over a serial port to talk to the ATMega, but since these clocks rarely last longer than a few weeks, this isn't of much concern.  Feel free to add buttons to set the date and time manually.

The time is kept by a DS3232, which is a very cool chip in that it has a built in temperature sensor, which it uses to compensate the crystal to try and keep better time, and the crystal itself is built into the package, which is an advantage since I'm using this on a breadboard, and crystals don't seem to like the stray capacitance on the boards that much.  This chip is quite a bit more expensive than the DS1307 I've usually been using for these projects, but both use the same address over I2C, so replacing one with the other is simply a matter of connecting the correct pins.

Also new in this project is a time lapse video of start to finish!  This is me assembling all of the parts on a pair of breadboards, as well as me writing all of the source code to get it running.  Total work time was approximately two hours, with a break in the middle which was edited out.  Enjoy!

Parts list:
  • ATMega168 (or any other AVR) running the Arduino bootloader ($4.32 Digikey)
  • 16MHz crystal + 2 22pF caps or ceramic resonator ($0.54 Digikey) I skimped and just used a 16MHz crystal I salvaged by itself.
  • 10k resistor for reset ($0.064 Digikey)
  • push button for reset ($0.23 Digikey)
  • DS3232 ($7.63 Digikey)
  • SOIC to DIP breakout board ($4.17 Digikey - This is for a SOIC-24 instead of the SOIC-20 that the DS3232 is, but it is the exact same board, except that they cut off the last four pins for you, and charge a dollar extra)
  • Backup time keeper parts:
    • 100Ω resistor ($0.064 Digikey)
    • 1N914 diode ($0.16 Digikey)
    • 2 100k resistors for high impedance voltage divider ($0.064 Digikey)
    • 2 10F >2.5V super caps ($3.54 Digikey)
  • 8 bit linear LED driver ($1.86 Digikey)
  • 2.2k resistor ($0.064 Digikey) This is Rext for the LED driver, which sets it to draw 10mA per pin.
  • 5 1k resistors ($0.064 Digikey) Limits current drawn from the ATMega, and delivered to the base of the transistors
  • 5 2N2222 (or 2N3904) NPN transistors ($0.33 Digikey)
  • 1 5x7 LED dot matrix - common cathode row, common anode columns (I sourced locally for $2.95 at Halted) ($3.83 Digikey)

  • There is no way to set the clock as is.  I have a separate piece of code hacked together where you can send a DS3232 or DS1307 the current date and time over the serial port.  This code is unfortunately not of release quality, so consider setting the clock a challenge for the student.
  • The DS3232 2ppm is way overkill for a freakin wall clock like this, so feel free to replace it with a cheaper RTC such as the DS1307, which happens to require no software modifications, since they both use the same I2C address and register mapping.
  • The DS3232 features are sorely underutilized.  Realize that it has two time of day alarms, which you might possibly be able to put to good use, if you felt so inclined.
  • The two 100kΩ resistors in parallel with the super caps are meant to swamp the very much higher, but unpredictable internal leakage resistance of each cap such that neither drifts above its rated voltage of 2.7V after being charged for an extended period of time.  The super caps have easily kept the DS3232 running for several days without power, and this could be improved by powering down some of the DS3232 subsystems (32kHz square wave, slower temperature conversions, etc).
  • I didn't bother noting all of the pin numbers for the LED driver, so refer to the source code and datasheet for where to connect the DATA, CLOCK, LATCH, and OUT0 - OUT6 pins.  I also didn't bother drawing in all of the tedious power and ground connections for all of the ICs, so read the datasheet (which you should be doing for the fun of it anyways, right?) and figure out where to apply power and ground.
  • Yes, that is a hair on the schematic. We're all sad about that misfortune on my part.
Source code.


  1. nice time lapse. Reminds me I still have to log my time over a period of one week at some point. Maybe next week.

    I know I've said these things before, but every time you do one of these projects it makes me feel good about having switched majors ^^;

  2. I wouldn't call a circuit using the naked chip plus bootloader an "Arduino" project in the full sense.

    I'm not an Arduino basher myself, but I think those guys are down on using the whole general prototyping board for small (and permanent?) projects. The ATMega168 was $4.32, yes I suppose he could have squeezed by with some kind of $2 chip ...

  3. I think I would chose to call any item using an Arduino boot loader as a Arduino project. Imagine calling something a C or Assembler project.

    By the way there are Microchip Arduino's out there. I can imagine a Linux one as well. I am of the opinion that it is a proper noun denoting a tool chain.

  4. My parts arrived today, will post a link to the finished article once I get it done.

    PS: I ordered the wrong atmega168 package, i think you need robots to mount it, will have to source another from somewhere.

  5. @DoghouseDean: Good to hear! You really can mount those surface mount chips by hand, it just takes a little finesse.

  6. started to make this and have it built.But the code is not working because the coding language has change and am having troubles trying to fix the code as I am not use too it.
    it just seems to be " Wire.send(0x00); " line that I can not get to work