Skip to content

Overengineering a clock

Like pret­ty much every­one who ever pulled apart their Nin­ten­do Game and Watch so they could beef it up with a speak­er and AA bat­tery hold­er scav­enged from a tran­sis­tor radio (that thing was awe­some), I was out­raged when Ahmed was arrest­ed. Luck­i­ly, now I’m an adult with some dis­pos­able income and a pen­chant for col­lect­ing cool gad­gets, so I was able to go home and start build­ing a movie-bomb-like clock pret­ty much imme­di­ate­ly.

I start­ed with a spare Arduino-com­pat­i­ble board (the love­ly lit­tle Freetron­ics Eleven) and a dis­play mod­ule I’d just picked up as an exper­i­men­tal addi­tion for my KSP con­trol pan­el. Had to order in a real-time clock mod­ule, but that gave me a cou­ple of days to get the first few com­po­nents hooked togeth­er on a piece of pro­to­board and the basics up and run­ning. This was the first time I’d tried using thin strips of board with head­er pins sol­dered on as ghet­to arduino con­nec­tions, and I like how they work for ad-hoc break­outs. The dis­play is an SPI device with a sep­a­rate RGB back­light, hence all of the ini­tial orange con­nec­tions. When the RTC arrived I was able to quick­ly bung it on the board and add a lit­tle bit of extra code to read time from it over an I2C con­nec­tion. In hind­sight I also should have hooked up the timer pin on the mod­ule, which gen­er­ates a pulse every sec­ond. But didn’t and am too lazy to go back and redo it now. At any rate, after that I had a clock that was able to show me the time.

Basic time-telling device. Not a bomb.

Then I need­ed some way to house it, with­out hid­ing all of the gory detail. So I snarfed some 3mm clear per­spex from the box of off­cuts at the Robots and Dinosaurs mak­er space, whipped up a quick set of mount­ing holes in LibreCAD (again, I’m get­ting good at design­ing and cut­ting the­se sorts of pan­els thanks to my work on my KSP con­trol board) and used the robod­i­no laser cut­ter to make a face­plate. Bolt­ed all of the pan­els in place, then used a cou­ple of small bits of wood clamped on to the bot­tom of the pan­el with screws to form a base to hold it upright.

Arguably a clock now. It sits on a shelf, and time can be deter­mined from some dis­tance. Hasn’t explod­ed yet.

I guess hav­ing a clock that shows the date and time is a rea­son­able place to stop. A rea­son­able, and very very bor­ing place to stop. So I kept going.

Start­ing sim­ple — that back­light can be pret­ty bright and annoy­ing. So I bought a light-depen­dant resis­tor, whacked it on in a cor­ner, and added some code to sam­ple the ambi­ent light lev­el and dynam­i­cal­ly adjust the LCD back­light. Full bright­ness dur­ing the day, down to almost as low as it can go when the lights are off. Much bet­ter.

For pow­er I used a spare 5V wall wart, again left over from a cou­ple of iter­a­tions of pow­er­ing my KSP con­troller. Poor fore­thought put the Arduino’s bar­rel jack too close to the base for use, but I had a spare one kick­ing around that I was able to screw on to the side of the pro­to­board, and run pow­er leads back to the Arduino.

I’ve had some ESP8266 mod­ules kick­ing around in my parts bin wait­ing for a rainy day for a while now. If you haven’t heard of the­se things yet, they’re amaz­ing. WiFi, very capa­ble micro­con­troller, can eas­i­ly inter­face with an Arduino or just as eas­i­ly be repro­grammed with the Arduino IDE, and cost well under $AU10 each. They require 3.3V, and more cur­rent than the Arduino’s onboard reg­u­la­tor can sup­ply. Luck­i­ly my dis­play also uses 3.3V log­ic, so I already had a 74HC4050 log­ic con­vert­er with some spare pins on my board. Just had to add a 3.3V lin­ear reg­u­la­tor and asso­ci­at­ed capac­i­tors, and my clock was now online. While I was doing that, I added a few head­er pins to the board, so I could eas­i­ly attach an FTDI cable to repro­gram the ESP8266, and it made the whole thing look more com­pli­cat­ed.

The pro­to­type board, clock­wise from top mid­dle: 4050 log­ic con­vert­er, LCD rib­bon con­nec­tor, RTC mod­ule, FTDI head­er, LDR, 3.3V reg­u­la­tor, ESP8266. Not shown: explo­sives.

I run an MQTT ser­vice on my home server. It’s a great mul­ti­pur­pose, mul­ti­de­vice mes­sage bus. My Open­HAB install inte­grates with it. My kodi media play­er pub­lish­es now play­ing info on it. My phone pub­lish­es (some) loca­tion data to it. I have a hand­ful of oth­er Arduino devices that send and receive infor­ma­tion across it using the fan­tas­tic pub­sub­client library. So I wrote a sim­ple client for the ESP8266 that joins my home net­work, and sub­scribes to a list of inter­est­ing top­ics on the MQTT bus. When­ev­er it receives any­thing it’s sub­scribed to, it pass­es it to main clock con­troller using a reg­u­lar seri­al con­nec­tion. Sud­den­ly I had a thing on the inter­net, with nary a buzz­word in sight.

One of the afore­men­tioned Oth­er Arduino Devices on my net­work is a lit­tle one-day project I knocked togeth­er last year. A remote tem­per­a­ture sen­sor con­sist­ing of an ATTiny84 con­troller, DHT22 temp and humid­i­ty sen­sor, and nRF24L01 low-pow­er radio trans­ceiver, pow­ered by a cou­ple of AAA bat­ter­ies. That sits out­side and broad­casts cur­rent temp and humid­i­ty data on MQTT, which most­ly just gets used to gen­er­ate nice graphs. Read­ing that to show cur­rent tem­per­a­ture on my clock was triv­ial. Then I added a small script on my server that polls local fore­cast infor­ma­tion from the BoM and broad­casts that a few times a day. On the clock side, I start­ed using icons from the free Meteo­cons weath­er icon col­lec­tion, down­scaled and hand-tweaked. They take up a fair bit of space, but stor­ing them in PROGMEM on the Arduino means I’ve got room for quite a few. This gave my clock cur­rent (ultra)local con­di­tions, and the dai­ly fore­cast. After run­ning this for a while I’m in the habit of check­ing it in the morn­ings instead of, you know, look­ing out­side.

Today’s fore­cast: no kaboom.

The space in the bot­tom left start­ed out just show­ing the text fore­cast pre­cis (which, inci­den­tal­ly, is won­der­ful­ly poet­ic; I’m hav­ing a hard time using it to accu­rate­ly choose an icon). But there’s so much cool stuff I want to know!

I use pub­lic trans­port all the time — my dai­ly com­mute to work is by train, and I use the bus stop around the cor­ner to get up to New­town a fair bit too. I also use Uber for occa­sion­al rides. The next log­i­cal step for me was radi­at­ing next depar­ture times for all of the pub­lic trans­port ser­vices I use. The eas­i­est is Uber, which has a super-sim­ple API to poll approx­i­mate pick­up time for a given loca­tion. I wrote a quick shell script that runs on my server, polls the Uber API every min­ute, and broad­casts pick­up times on MQTT. Now my clock knows how long I’ll wait for a ride.

I’ve run out of bomb-relat­ed cap­tions.

That pret­ty much brings me to the cur­rent sta­tus. Every now and then I tweak the code on the con­troller, adding new icons and try­ing to improve the way it decides which icon to show. I’m still pok­ing at the code required to trans­late the Trans­port Data Exchange info offered by Trans­port for NSW, but to be hon­est it was pret­ty dis­heart­en­ing to learn that they don’t offer real-time updates to plebs like me who’ll nev­er have more than one user for their project. Still think­ing about oth­er stuff to toss up in that space, but my recent exper­i­ments with CI for Arduino projects may lead to pub­lish­ing build results in the not too dis­tant future.

This was a real­ly fun project. Build­ing a clock was some­thing I’d want­ed to try for ages but nev­er quite got around to. I’ve wound up with a gen­uine­ly use­ful and hope­ful­ly inter­est­ing-look­ing object.

Like most of my oth­er Arduino projects, the code for this is online: https://bitbucket.org/pjhardy/smartclock . My local repos­i­to­ry is a cou­ple of revi­sions ahead of that but there’s not much inter­est­ing except for me com­plete­ly rear­rang­ing my local net­work after acci­den­tal­ly pub­lish­ing the WPA key. :/

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*