Tuesday, April 26, 2011

Word Clock, Part 1

This was probably my biggest, most ambitious electronics project I've done so far. (And also one of my first)
It was inspired by this:
http://www.instructables.com/id/A-Word-Clock/, which in turn was inspired by: http://blog.makezine.com/archive/2009/09/qlocktwo-clock-tells-time-with-word.html.  (I see that the guy who did the instructables clock has since done new version of it, it looks really nice.)

Anyway, here is mine:

My word clock. If I could have taken a picture that hid the flaws, I would have :)


(This is another retrospective post on an older project, that is also still a work-in-progress, so I'll try to post as much detail as I can from memory. Some of my reasoning for doing things a particular way might be long forgotten, for everything else, I plead temporary insanity)

I know a lot of people like details, details, details, so my plan for documenting this project is this: this post will be a high level overview, with maybe 3 or 4 future posts that will get into some specifics on some aspects. I've already started working on some schematics just for this blog. I don't currently consider it done, I have a couple flaws in it I want to fix, and some other features. Any feedback is appreciated.

Overview

It is a "word clock" that tells the time by illuminating a combination of words to "say" the time. So, for instance at 10:35 PM, it will display the words "TWENTY", "FIVE", "TO", "ELEVEN", and "PM". It has a "resolution" of five minutes, ie it only tells the time to the nearest five minute increment. The inspiration for the idea came from the posts I read, but the design and code is 100% mine.(excepting maybe sample code snippets here and there, since this was for personal use, I wasn't too strict about that). My design adds a few features too.

The basic features are:

  • Time of day
  • Current Temperature
  • Variable display intensity
  • RGB LED status/mode indicator
  • "Demo mode" <-- probably the most fun part of the project!
  • Recording/replay of the temperature for the past 24 hours.
  • "Heartbeat" light, the only light directly connected to the Arm chip, this was good for detecting code hangs, it's not really good for much else. 

I am debating adding a couple other features:
  • An "alarm", even though I don't plan to add a speaker, I could have it flash the whole array of LEDS
  • a "Night time" mode, where it automatically dims or turns off the display at night.

I learned a lot about electronics doing this project, one of the "flaws" mentioned above was that the power consumption seems higher than I think it should be, but I've never dug too deep into it. The linear voltage regulator at times gets too hot to touch. Also, I learned the hard way to have solid plans for physical construction, to not just think about how pieces would work together, but how the construction and assembly process would work. The thing is a royal pain put together.


Implementation Overview - Circuit

The clock runs off an AT91 Sam7 256, an  Arm7 TDMI processor from Atmel. I wrote the application in C using the Yagarto Arm tool-chain. There was some bootloader code in assembly I tweaked from samples. I tend to avoid assembly code, and this project was my first exposure to Arm assembly, it wasn't too bad.

No Arm chips I am aware of come in a DIP form-factor. So I used a "Header Board", by Olimex, sold here by Sparkfun in the US. The Sam7 256 is a 3.3 volt chip, and all I/O pins are 5 volt tolerant. Atmel's documentation in general is pretty good, this chip is no exception, so all in all it's a nice beginner's Arm chip.

In addition to the Olimex board,

  • An I2C "Backbone" that handled most of the intra-chip communication
    • I actually "bit bang" the I2C protocol over two general purpose I/O pins. When I started this project, I really had limited tools. All I had was a multimeter, not really usefull for debugging digital logic lines. Bit banging it allowed me to debug communications problems at a very low level, and do it in software.
  • A DS1337 real time clock chip for keeping time. 
    • It's capable of tracking the date too, but I don't use that functionality. It can also trigger interrupts at a set time, quite handy if I want to add the alarm feature I mentioned above.
    • I also connect this to a coin cell battery back up, so you don't loose the time when the clock is unplugged. This was a fun feat, since I had no idea how battery back-ups worked. I had the idea to connect the battery in paralle with the regulator power, with a couple diodes to prevent regulator current from try to "charge" the coin cell, and another diode to prevent the coin cell from powering anything but the RTC chip. I also put a cap in there, that will keep the clock going when you have to change the battery. In my experiments, it would keep it going for at least several hours.
  • A MCP23S18 I2C based 16 bit I/O expander from Microchip. 
    • Even though I had a decent amount of I/O pins free on the Arm chip, I decided to use this for button input, and to "cascade" interrupt lines from some of the other chips, partially just as an education experience. 
  • A TC74 I2C digital thermal sensor from Microchip.
    • It was very easy to use, I think I had code talking to the chip in less than 10 minutes. The down-side was that this particular chip reported in the nearest degree Celsius, and I wanted the clock to report in Fahrenheit. My scale doesn't feel linear, since I rounded each degree to the neared whole Fahrenheit equivalent in the display.
  • A 24C02 256 byte I2C EEPROM. 
    • I use this to store user settings/preferences, and a log of the temperature. I had plenty of on-chip flash to spare, but at the time, I was a little worried about wearing out the flash with frequent writes, or that I would introduce some infinite loop bug and fry my flash. The EEPROM chip was super cheap and replaceable if I fried it.
  • 3 TLC 5941 PWM LED drivers chips from TI.
    • These guys do the "heavy lifting" for controlling all the LEDS. They are cascaded and I simply bit shift in a configuration for each output, and feed it a driver PWM signal. This made it really easy to independently dim/fade each word in the display. 
    • This chip isn't I2C, but a custom protocol fairly documented. If I remember correctly, part of the protocol is actually SPI, but I bit banged the entire communication for the same reasons I did with I2C. This part required ALOT of trial and error. By the time I eventually got around to buying a logic analyzer, I had this working beautifully, but I hooked it up anyways to admire my handiwork.
    • I do suspect that my higher than expected power consumption stems from a possible electrical misconfiguration of these chips. When I get around to looking into it, it will be the first thing I test. The 5941 has "Dot correction" registers that are supposed to let you tweak to current limiting. I use those registers to control overall brightness of the display, so my "fix" for the current issue, may just be to cap a maximum value for that to keep current within a range I'm happy with.
    • I found during breadboard experiments that these chips seemed really sensitive to noise and fanout, so even with only 3 of them, I had to buffer the inputs. TI says up to 40 of these chips can be cascaded, I'd like to see that.
As usual, it is a rat's nest on a perf-board, but I'm pretty happy how relatively organized it turned out, considering that it's a pretty big circuit, I think I estimated over 500 solder points.

Check out the action shot here:


Implementation Overview - Physical

    The lettering layout grid was designed in Qcad.  I intentionally made sure the panel layout would fit inside a standard (American) 8.5" X 11" piece of paper, so I could print the lettering on transparencies myself. Here is  an early draft of the layout:

    I used this to plan the placement of 110 5mm LED's on a quarter inch thick piece of plywood, which I then secured with hot glue. (The hardest part of that was finding a time to the noisy drilling in my attic "man cave", I do most of my hobby work after my wife and kids go to bed :) )

    My original plan was to use "dividers" to prevent light from leaking between the words, I got some heavy posterboard and cut into strips that I fashioned into a grid. It looked like crap, and the LEDs I used had a pretty narrow illumination angle, so I scrapped that idea.

    Next, I designed the lettering itself and printed it, "white" letters onto a black background, on to a  transparency. The transparency was then covered with a plain piece of white paper, and a semi-transparent piece of plastic I cut out of a paper binder I bought at an office supply store. I wanted to have the letters obscured when they were not illuminated, so that they would seem to pop out. 

    The frame cut from some 1X4 poplar boards and stained black. (I would re-use that idea later when I did the Good Times timer). I then used a dremmel to cut a groove around the inside perimeter of the frame that would hold the "face" layers of the clock. This idea didn't work as well as I wanted, an I learned a lesson about testing feasibility of ideas before I progress too far with a design. I'm also not a great wood worker, I get impatient with it, which is odd, because I have considerable patience when it comes to diagnosing software problems. The miter cuts were awful and it does not fit together good enough. This made assembly hard, and you can see light leaking through the corners. I learned in the futures to go toward designs where the wood work does not need to be so precise.

    So there you have it. Like I said, more to come, I've got some schematics in the works, and I shot some video of it in action, stay tuned...

    Next time, I want to get into details on how I used some of the chips I mentioned in this post.

    --P


    No comments:

    Post a Comment

    I welcome you're thoughts. Keep it classy, think of the children.