2008-05-04

Pedometer with Morse Interface

This project was inspired by the death of my current pedometer's battery. Being too lazy to find my box of LR44s buried somewhere in my junque box, I decided to implement my own pedometer. Longer term I have visions of storing biotelemetry into a serial EEPROM for later analysis (making it a more useful device than the current cheapy commercial unit), but this initial proof of concept is just a step counter.

The concept was scribbled in my notebook on the evening Ferry trip home for work last Monday, shortly after I noticed my commercial pedometer was dead. Unfortunately I didn't get a chance to actually work on the project until the weekend, but once I started it only took a few hours to get going - I'd had almost a week to design it in vivo.

Yeah, but Morse Code?

Using Morse Code as the interface was from the realisation that it was fairly easy to implement, consumed very little power and took only one drive pin (compared to the three required to charlieplex LEDs for a 6-pixel POV display - a future project no doubt). Usability might be a problem, but it is also a good excuse to drive me to learn CW properly, the numbers are easy and I think even complete CW novices would learn to read it quickly. No doubt such a device might be good for the vision impaired.

Hardware

The interface is simple, a Mercury switch as a footstep detector, a button which you can press to request the current count be squeaked out in Morse Code (through a piezo) or held somewhat longer to clear the count back to zero.

The Morse Pedometer

The brain is a ATtiny13V MCU, sourced from Futurlec. Power is from a CR2025 Lithium battery which was found on my desk and for which I just happened to have a bag of battery holders from a recent Rockby clearance. The same Rockby order also supplied the Hg switch, button, and the piezo. The only other component is a 100 nF decoupling cap across the MCU.

Smaller components could miniaturise the unit a lot, the piezo, battery and switch in particular are quite large, but an SMD tiny13 is available too.

Here is a video of the prototype being tested:

Prototype Under Test
Prototype Under Test
(5.878 Mbytes)

Software

The MCU spends most of its time sleeping powered-down. Asynchronous pin-change interrupts wake it for a footstep transition or the button. Footsteps are de-bounced before counting and have a lockout period to limit the transitions to physically likely frequencies (about 5 Hz max which is reasonable for human cadence rates). The counter is incremented, then straight back to sleep after toggling the piezo drive line (generates a quiet click). Button presses are debounced in a similar manner and then decided between a press and a longer hold, which drives either a display action or clearing of the counter.

The Morse Code is stored as 2 bits per symbol. This is a standard I've used in beacon code in the past, in fact I put the full code in there for handling char and word spaces even though it isn't used. I am considering adding an interactive menu so it might be needed in future. In the current application I actually only need one bit for each symbol and could use only 10 bytes (7 if packed) to encode the entire Morse table (for numbers; the spacing is constant). There is still a bit of ROM left so I could shrink the CW associated code and put in another feature that didn't need Morse, perhaps I2C support for data logging.

All the timing intervals and frequencies are set by #defines and are easily tuned to the user's preferences. The 800 Hz morse frequency is a bit low for efficient drive of the pizeo used, its resonant frequency is about 4 kHz. Lower frequencies are more traditional for CW, but higher ones sound cleaner because of the reduced harmonic content. I picked 15 WPM as a good beginners rate, but 25 might be better as you are tempted to count dits and dahs at only 15 wpm.

I did have a little stack-smash problem with the software that took some figuring out. I was simply running out of stack because of the number of frames I had in the execution trace. Some code revision fixed it, in particular moving the decimal magnitude array into ROM, originally I was creating it on the stack - all 10 bytes of it! I also reduced the size of some loop counters to save a bit more when they were pushed. I was at one point going a bit nuts though, I even compiled the same algorithm with gcc to prove it was OK on the "big machine". The experience made me investigate the standard toolchain utilities much more closely, in particular avr-nm and avr-objdump. Reading the assembled output of avr-gcc is always helpful in such a situation. The compiler is very good, but looking at what it generates I know I could do a little bit better by hand if I ever need to really squeeze more into a small device like the tiny13.

The source is here.

Battery Life

The two internal weak pull-ups probably dominate the current consumption. It takes about 90 uA sleeping, 1.3 mA while sounding. The CR2025 has a capacity of about 150 mAh so I'd expect about 2 months battery life with modest use. This could no doubt be improved.

2 comments.