Binary Wristwatch Project Writeup
I used to get the feeling that it wasn’t obvious enough that I really enjoy working with embedded systems. I decided to change that by designing a binary timepiece that is portable, easy to use, has long battery life, and has a very barebones “circuits and components” feel to it. After wearing the final product for about four months now, I feel like I was successful on all of those goals:
I’m pretty proud of this project; the clasp is a ribbon cable that doubles as the programming interface for the PIC microcontroller that drives everything. The time is displayed with superbright LEDs that are blinding at 15 mA, which means that I’m able to limit the power consumption considerably while still achieving a very readable display. The watch is powered by the (ever so common and useful) CR2032 lithium coin cell, which gives it an estimated battery life of 3 months depending on usage patterns (still doing research and testing on the average for this… 2 months in and I’m still running on my first battery : )
I like this watch so much that I decided to make some for a few friends of mine. From there, I figured that since I had gotten to a point where I could make them without too much difficulty, I might as well sell them to see if I could recoup how much I’ve spent on component testing and PCB fabrication The completed watch is available at my storenvy page.
The primary purpose of this project was to get some experience working with PIC MCUs for low power applications. I played with a 16F back in college in a microcontrollers class, but I have yet to use one since. I ended up using a PIC18F24J11 for this one. It contains an RTCC peripheral that can be calibrated and driven by an external crystal, enough GPIOs to drive the number of LEDs I want without having to introduce an external shifter, and a pretty attractive deep sleep mode that has just the right number of wake sources. Microchip makes a 28 QFN version of the chip, which is nice both for its small footprint and for the fact that I’ve been wanting to challenge myself a bit more lately with surface mount soldering.
For output, I have three sets of LEDs on the board: two for telling whether the time or date is being displayed and ten for actually conveying the numeric data. For ease of use, I added numbers to the silk screen in each LED column to denote which conveys 1, 2, 4, 8, and 32. I used superbright LEDs, which allows me to use pretty big current limiting resistors (16k). This keeps the power consumption of each LED very very low (<0.2 mA), which is vital for squeezing as much use as possible out of the 225 mAh you get with a CR2032.
For input, I’m using two push buttons. One is tied to the INT0 pin of the PIC, which allows it to be used as a deep sleep wake source. The second is tied to the Ultra Low Power Wake Up (ULPWU) pin, also a deep sleep wake source. ULPWU isn’t really designed to be used with a pushbutton (it’s more commonly used as a way of getting a periodic DS wake source keyed off of a discharging capacitor), but at the end of the day it can wake the chip from deep sleep when it sees a negative edge, which is good enough for me. One pushbutton is used to toggle between displaying the date, the time (hour & minute), or the seconds, and is also used to get the device to enter a low power state in which none of the LEDs are active. The second pushbutton is used to switch the watch into a set time/date mode, and can also be used to enable or disable a fun visual effect I added to the number display function.
The programming interface is handled through a set of 100 mil headers. I like to use a pickit 3 for binary loading, but anything that works with a PIC will work with that header. I decided that since I already need to have a header on the top of the board for programming, I could add a second header to the bottom that was not connected electrically to anything, which allows me to use a ribbon cable plugged into these two headers as a watch clasp.
I did all schematic design and layout in Eagle, the source for which is available on my github.
The software for this one is pretty straightforward. The biggest challenge was working out the configuration of the deep sleep wake sources, and working around the fact that whenever the chip entered DS, it shut down the debug session I had running through the pickit :/ The three wake sources I was using were all from different peripherals, each of which had slightly different quirks to them. My biggest concern for this project was power saving to extend the life of the CR2032 as much as possible, so the device is in deep sleep about 95% of the time. The RTCC chime wakes the chip either once per second or once per minute based on whether the D/T LED 1 Hz blink is enabled or disabled. If the watch is in “sleep” mode (no LEDs active), the watch will only wake from deep sleep on a pushbutton press. The pushbuttons are active low, so a negative edge wakes the chip from deep sleep and kicks off a timer. That timer is used both for debouncing and to differentiate between a press or a press and hold. The general purpose deep sleep persistent memory register is used to allow the device to go back into deep sleep after a press and hold of the pushbuttons without losing track of system state (whether it’s showing time, is in the “set hour” state, etc). I also added an effect to the update display function that was inspired by the “jackpot mode” I put in an old nixie clock project (necessary on that clock to keep unused cathodes from deteriorating). Everyone I showed the nixie clock to liked when the numbers cycled through all their values at the top of the minute, so I wanted to do something similar here. I settled on causing the display numbers appear as though they’re being shifted in from the left every time they update (with the exception of when displaying the seconds, because it’s hard enough to calculate those on the fly as is : ) I added the ability to enable or disable this feature with a pushbutton in case I ever get tired of it, but for now I like it.
The software was all written and compiled with Microchip’s MPLABx IDE, using the C18 compiler. It irks me that they feature lock some of the optimization after 30 days, but there’s more than enough space on an 18F to have to start worrying about code size for a project this simple. The source code is available on my github.
Overall, I am very happy with how this project went. I learned a decent bit more about how PICs work, got to interact with the ecosystem for an MCU vendor I have not yet worked with professionally, learned more about low power design, and got to add a few more fun toys to my garage. I definitely learned a few things in the process though. For one, the PIC is good for low power applications, but I was a fool at first to trust that the calibration capabilities of the RTCC peripheral would be sufficient to be able to clock the entire thing off the internal oscillator. Even with the peripheral’s calibration registers set to maximum values, the clock would gain or lose minutes per day, which is entirely unacceptable. To compensate for this, I added a high precision 32.768 KHz external oscillator that was used to clock the RTCC peripheral.
Another lesson learned: wearables flex. The only thing holding the battery to the board is the tension in the metal from the clips, so this became a huge problem with my first batch of hardware. I opted for a thinner board for that batch (0.8 mm) to make it lightweight, and used a pad for the negative side of the battery that was about half the diameter of the CR2032. Big mistakes. Since the clasp is attached directly to the board, if I turned my wrist in just the right way, it would cause the board to bow, which would disconnect the battery from the pad and reset the clock. Oy. Fixed by using a normal thickness pcb (1.2 mm) and a much larger pad for the battery.
Next lesson: there comes a time when you have to bite the bullet and make the order. I’m currently on rev four of the PCB, and there’s still stuff I’d like to change. I want to switch out the 100 mil headers with 2.00 mm headers so I can make the watch lower profile. I want to add a better way to distinguish between AM and PM when displaying the time. I want a clasp mechanism that still uses a ribbon cable, but that is adjustable. There will always be more features I want to add, but eventually, you just have to order the boards and start making them. Yes, there should be a minimum criteria to say that this board is something good enough to attach my name to, but that criteria should not be absolute perfection.
Another: potentiometers are my friend. I fiddled with the exact value of current limiting resistor to use for a while before finally choosing 16k. It’s a whole lot easier to hook up a potentiometer to the circuit and use that to dial the exact desired brightness than to switch between 8 different LEDs from a cabinet over and over.