Drive by Clock

Martin's Drive by Clock


Photo Album

Videos

Huh? Why?

A long while ago I had a phone that had a nice bright LED that would light before it rang. Even when the phone was way off on the far edge of my peripheral vision I found myself reaching for it before I heard it. Shortly thereafter I noticed that when I got an IM or email I wouldn't notice it, even with the little screen animation. It seems that on screen animations don't attract my attention much anymore.

So was born the initial idea. A bright LED that's designed to only be on for very specific occasions. The "Drive by clock" part got added later when I found that I constantly had people stopping by my cubicle asking me for a "few minutes" and still couldn't get anything done. I wanted to record those "drive bys" chess clock style.

Final product overview

The Drive by Clock is a box that has 4 buttons, 2 large ones on top and two smaller ones on the side. There's 4 multi color LEDs on the front. The top has a pair LED bars and a pair of 8 segment LED numbers. Additionally, since this used a USB port, I ended up putting 3 more USB ports on the back.

Brief Tech Overview:

Phidget USB LED controller

Phidgets sells a bunch of electronics interface kits like servo and stepper motor controllers and things. Among them is a USB 64 LED controller. While this initially seemed overkill for what I was looking for (one or two lights) I eventually realized I might be able to extend my plans.

That's how I ended up being moving to having a whole bunch of LEDs on it. Just a count:

So, that's 50 LEDs all together. But, I can display all sorts of neat information. I've got room for growth if I wanted it.

USB joystick

I wanted some form of input for the chessclock like functionality for tagging my time vs. drive by coworker's time. I actually pondered this for a while. Of course I could have used my keyboard or mouse, but that's no fun. Some additional input method would make it entertaining, but another USB mouse or keyboard wouldn't be any different and would make coding around it a pain. That's when the idea of a joystick came to me. USB joysticks are cheap and would probably be easy to hack into this. It was. I just coopted a few of the standard buttons and soldered wires onto the correct spots on the board and attached hard buttons.

USB Hub

I think by now you see where this fits in here and doesn't require much discussion.

Python Code

Here's where it gets fun and useful.

pygame

Python has numerous interfaces for reading joystick inputs. Pygame is the one I was most (though not very) familiar with. I went with it. It turns out to have been very easy because in addition to the easy handling of joystick events, it also had a good basic event loop with handling that I could easily make use of.

Controlling the Phidgets LED controller

This one lead to a lot of pain. First, I had to get the C library for the LED driver working. But, it's buried in with all the rest of the phidgets driver code. So, I had to build it all. This was so long ago, that i don't even remember all the pain involved, but it took me quiet a while. Testing took quite a while and I got to dive into some low level C code which I haven't done in quite a while. Initially I was pondering writing this whole thing in C, but the reminder of he low level C made me realize I didn't want to go to that level.

Second, after I decided to write in Python, I had to figure out how to interface. I had found several python modules that claimed to interface to the Phidgets libraries. But, I realized that they were all for the other Phidgets controllers, not the LED one. After a brief attempt at writing the C interface for the LED library, I decided on ctypes.

Ctypes is basically a generic interface for all C libraries. It lets you load up a precompiled library and then make calls directly into it from python. It automatically does type conversions as required. My python ctypes interface is about 60 lines of code.

Dbus

Dbus is just a message passing system used by many things, including Pidgin. I was rather amused that googling "dbus" alone yielded many tutorials, several of which featured pyton already. This was a good sign that I would be able to find what I needed. And I mostly did, except for how to make the dbus required mainloop and the pygame loop run side by side. Until I found the code that gave me this snippet:
import gobject
import thread

        dbus_loop = gobject.MainLoop()
        gobject.threads_init()
        thread.start_new_thread(dbus_loop.run, ())
The gobject.threads_init() is the part that didn't seem to ever be adequately explained. All it does is tell the python gobject to that it should release the GIL when it's not need (and people still try to tell me "Oh, the GIL isn't so bad!" Bullshit it's not). Anyway, the basic point is that once you've told gobject to release the GIL when it's not needed, you can shove the main loop into its own thread and have it do things for you.

Final Notes

While I had a great time building this, I've learned a bit since starting it. The most annoying thing is that since I started it, the world of open source, cheap and easy to find USB connected hardware has expanded a lot. Were I to rebuild this now, I would most likely do it based on the Arduino hardware platform.


No comments available

Add comment