pilarm

I’ve always hated alarm clocks. I’ve tried electronic and mechanical clocks of all kinds, and every one either couldn’t wake me or made a revolting noise that I hated waking up to. I finally gave up the search and just built my own. “If you want something done right”, right? Right.

For me, the two critical features of an alarm clock are the nature of the alarm itself and its disarming method.

As for the alarm, I don’t believe any type of sound can both reliably wake me and not be horribly unpleasant. A light of some kind is the clear choice for pleasantness, but a suddenly-on bright light isn’t ideal. I decided to go for a simulated sunrise effect: a light coming on slowly, changing from dark to red/yellow to bright blue/white over several minutes’ time. More obnoxious light patterns and a noise of some kind could come into play afterward if the alarm isn’t stopped.

Disarming must be convoluted. I can, and unfortunately often have, switched off an alarm without really being awake and then fallen right back to sleep. The disarm should demand something much more than a single button press or switch throw, such that I have to actually be awake to operate it. And no “snooze” button. I have never understood the purpose of the snooze feature; why would you want to be jarred awake more than once? Oversleep without actually getting extra sleep? Brilliant.

The Raspberry Pi was the key enabler of this project. It’s cheap, small, low power, and silent. It has general purpose I/O built right in, and it has a composite video output which allows for a cheap little video monitor to be used:

Raspbian is my OS of choice for the Pi where a GUI is needed. It takes its sweet time booting, but this application is always-on. A full-blown desktop computer may seem a little overkill for an alarm clock, but these components are awful cheap, and doing the interface in software opens all possibilities and makes experimentation very easy. The cherry on top is the clock never needs to be set: it can keep itself synced to internet time servers.

For the light source, I chopped up a common RGB LED strip and mounted it in a box:

rgblightbox

PWM signals for controlling the light can be generated on the Pi’s GPIO, but not especially well. The Pi can produce only a single PWM output in hardware, so for the three outputs needed it would have to be software. Even if the Pi could properly generate the signals, I would still need to buffer them and step up the voltage to gate power switches on a separate board, so I just put a microcontroller on the power board itself:

On the near/left side you see the main 12-volt power supply and the connection to the Raspberry Pi’s GPIO header. The Pi provides the 3.3-volt supply for the microcontroller, 5-volt supply for the buffer/step-up to the FET gates, and I²C clock and data for control. On the far side, +12v is passed through and a total of four returns go through N-channel MOSFETs. Three are modulated for the RGB light, and one is a simple on/off for a piezoelectric beeper. For more details about the circuit and some of the design pains see this post.

The device acts on 4-byte messages comprised of a command and three parameters (some or all may be ignored depending on the command). The beeper can be switched on/off or pulsed, the light’s red/green/blue intensities can be set together, and persistent scaling factors for the three colors can be set (apparent brightness of the three LED colors varies a lot). Here is the firmware and a Python module for talking to it: pilarm_firmware.tar.gz.

The application and its interface are very simple (it’s just a clock, after all):

pilarmnice

The alarm can be toggled on/off with a key press, and the alarm time can be adjusted. When the alarm fires a random 6-digit code is shown, and to stop the alarm the code must be entered on the keypad without a mistake or significant pause:

pilarmdisarm

As for UI implementation, all that’s needed is a full-screen graphic area and the ability to render large text. A framework like Qt is too much; I don’t need dialogs, buttons, or anything like that. Pygame fits the job perfectly. In fact, the way the app reads key presses and runs color gradients over time on the light box, it’s closer to a game than an ordinary desktop application anyway.

I’m happy to say this effort was a complete success. I finally have an alarm which does its job without torturing me. If this seems like a hell of a long way to go just to build an alarm clock, well, now you know just how much I hate those things.