Guitar Tuner

Guitar Tuner r2

Revision 2 is described in the following log entry:

  1. Strobe Guitar Tuner r2 Design Changes

The hardware source files are available on Github.

My original notes on revision 1 are below.

Guitar Tuner r1

Background

I found this guitar tuner design while reading the MAKE blog, and decided it would be interesting to make my own version of it.  I needed a guitar tuner anyway, and building one is way more fun than buying one.  In this project I learned how to solder surface-mount components by hand, and how to use the AVR’s sleep modes.

The tuner is based on the stroboscopic effect.  A strobe tuner works by extracting information from the movement of the guitar string itself rather than the sound the string produces.  Most tuners do audio analysis, but they have the disadvantage of being imprecise and sensitive to noise.  They are also harder to build because they require an audio input module and and the firmware needs to do frequency analysis on the audio signal.

The strobe tuner simply generates a pulse waveform on two LEDs, so that they light up at the frequency at which the string is supposed to vibrate.  If the string is vibrating at the same frequency that the LEDs are flashing, then the LEDs always flash when the string at the same point in its vibration envelope.  If the string is out of tune, then the string will be at different locations in its vibration every time the LEDs flash.  It will look like there’s a line of light travelling up and down the vibration envelope; the line travels slower as the string’s vibration frequency approaches the frequency at which the LEDs are flashing, and stops moving when the string is perfectly in tune.

Here is a video showing the tuner in action:

In this video I didn’t understand the principle behind having two LEDs.  If you look for commercial strobe tuner videos on Youtube you’ll see that the LEDs generate two light lines on the string instead of just one, and the lines stop  moving relative to each other when the string is in tune.  Having two lines moving back and forth makes it easier to see the lines moving especially on strings with a small vibration envelope, such as high-frequency steel strings.  I have changed my code to generate two lines instead of the one shown in the video above.

Components

I used the following parts:

Part Number
Quantity Description Price (C$/unit) Component*
ECS-80-18-4 1 8 MHz crystal (18 pF load capacitance) 0.66 X1
UMK105CG220JV-F 2 22 pF 50 V capacitors (for crystal) 0.037 C1, C2
LMK212F106ZG-T 1 10 µF 10 V capacitor (for power supply) 0.17 C3
APG1608SURKC/T 2 320 mcd, 20 mA clear red LEDs 0.23 D1, D2
MCR10EZHF56R0 2 56 Ω, 1/8 W resistors 0.046 R1, R2
ATTINY84-20PU 1 AVR ATtiny84 DIP microcontroller 3.29 IC1
1-390261-3 1 DIP-14 socket 0.17 IC1**
BH600 1 16 mm coin battery holder 1.28 +/-
CR1632 1 3 V lithium coin battery 1.22
SS-10-16NP-LE 1 SP6T rotary switch with off position 4.38 SW1
PC55 1 3×4.5″ copper-clad PCB 2.95

* The component’s label on the PCB layout.

** I soldered a DIP socket to the board so that I could pull the microcontroller out to reprogram it.  One could solder the CPU directly to the board..

The prices listed are those given by DigiKey on March 7, 2010.  The components add up to $14.75, although price breaks will decrease the cost a little bit and the PCB can produce two or three tuner circuit boards.  Other ways to decrease the price would be to use a cheaper microcontroller (e.g. the ATtiny28L in QFP format at $1.71) and finding a replacement for the switch.

If I made another tuner I would switch to a 20 mm lithium battery because they are much cheaper than 16 mm batteries and have significantly higher capacity (e.g. a CR2032, at $0.31).  When I bought the parts I thought the battery holder was going to be mounted on the top of the board, so I decided to use a 16 mm battery to save space.  I mounted the battery holder on the board’s underside, which obviated the holder size issue.  Then I gave up since 16 mm batteries are so hard to find and just clipped the leads from a 3x AA battery pack to the power input terminals.

Circuit

I didn’t understand the load capacitance thing for the crystal, so I copied an Arduino circuit, which specifies 22 pF capacitors for a crystal with 18 pF load capacitance.  I don’t think it really matters, since the formula for calculating the capacitor values has pretty arbitrary variables for input and parasitic capacitances.

The circuit is unregulated and runs and whatever voltage the battery outputs.  The microcontroller can take 1.8 to 6.0 V, but the LED resistors are calibrated for 3 V.  A higher voltage will result in brighter LEDs at the cost of increased current consumption and possibly decreased life span (the LEDs are rated for 20 mA and the microcontroller outputs are rated for 40 mA, but the LEDs are running at a 25% duty cycle so I’m not sure how big the risk of damage is).

At 3 V, running at 1 MHz, the device consumes about 2 mA when active and less than 250 nA when turned off.

Code

I programmed the microcontroller with an AVRISP-mkII programmer, using a method similar to this.  I set the fuses to use a 3-8 MHz external crystal with a 4.1 ms start-up time, and to divide the clock frequency by 8 (thus the microcontroller runs at 1 MHz; this reduces the microcontroller’s current draw significantly).

The code is very simple.  Click on the following link to see the C source:

http://code.google.com/p/strobeguitartuner/source/browse/trunk/main.c

I know of one non-trivial bug in the device.  If the rotary switch is set to contact 1 and it is turned to the non-connected area between contacts 1 and 2 for more than 150 ms, then the system will turn off and won’t wake up until the switch is turned back to contact 1.  I’m not sure how to fix the problem without setting the microcontroller to wake up when the switch changes to more positions, but that increases the device’s current draw by up to a couple orders of magnitude.  I decided that the problem isn’t significant enough to worry about.

As of this writing, the code compiles (with -Os passed to gcc) to 750 bytes of program memory and 11 bytes of data memory.  It should work fine on any AVR microcontroller with at least 1 KB of program memory and 8 I/O pins (plus the crystal input).