Posts Tagged ‘guitar’
You just gotta love the title, eh?
Recently I’ve been working on modding my guitar, in particular add some flashing LEDs to the guitar innards. I’ve got another project on the go too, but I’ll save that for a later post when I’ve finished it.
Anyway, the effect I wanted was to have the LEDs flash in time with the music I play, or rather in time to my strumming, and then I thought it would be good to follow the loudness peaks from my guitar pickups. In a sense I’ve built an audio meter that’s using the guitar output as an input and the LED array brightness as an audio meter indication.
I used an AVR ATTiny85 as part of the circuit, though you don’t need anything as big as this, it’s just that I had a few in my spare parts box; you can easily fit the program into an ATTiny25. All you need in the microchip is essentially an ADC (Analog to Digital Counter/Convertor).
I’ve also used a simple l0w voltage audio power amplifier, an LM386N-1, to boost the signal from the pickups to the ADC on the ATTiny.
Essentially what happens is, the signal from the guitar pickups gets amplified by the LM386 by 20, feeds it to the ATTiny which counts up to convert the analog signal into a digital one. This signal is tracked over time to find out a moving average. If the signal rises 30% above the average it’s considered a peak so the ATTiny goes through a flash cycle and turns on the LED circuit. Now, because the LED circuit has multiple LEDs on it, it would draw too much current through the ATTiny, and so instead the pin on the ATTiny drives a simple NPN transistor to turn on the current flowing through 8 LEDs.
So, how do you go about building one of these for your own guitar?
Well, I’ll assume you already know about how to program an AVR ATTiny microprocessor. If not, you can check out the excellent startup tutorial at IMakeProjects.com web-site.
The circuit and code itself was based on a part of the circuit and code I found at Negative Knowledge. One point to notice is that the LEDs are connected in parallel, usually a no-no, but in this case all the ultra blue LEDs are of the same specification. Usually what happens is one of the LEDs would draw more than its maximum current, be the only one turned on, and blow, repeated over and over until you have none left. With the same specification LEDs it’s more likely all will be well.
Also, one thing that caused no end of trouble, was making sure all the -ve/GND connections were made. Both the ATTiny’s and LM386’s GNDs were connected together, as well as linking the guitar signal’s -ve/GND connection at pin 2 of the LM386. If you don’t do that, you’ll have loads of fun with awful hum when you play guitar, or worse, a lovely high pitch squeal … or maybe nothing at all
The circuit is easy enough to put together on a piece of stripboard. You just have to make sure that you make it all small enough to fit inside your guitar casing!
In fact, one of the biggest problems I had was fitting everything inside the cramped space inside my Custom Telecaster. So much so, I had to connect the battery via a plug socket on the outside of the guitar, just near to the audio jack output. It seemed like a shame to drill a hole in the guitar, but I’d gone so far that nothing was going to stop this LED flasher from working!
Once the circuit is in place, I made sure I had a simple startup routine in the code to flash the LEDs twice. I made sure I did this so that I had a visual indication that the circuit was up and running. Without it I wouldn’t have known if I’d trapped the 5V cable when screwing the scratchplate back on (yes, I did this), or if the battery was dead (yes, I did this too), or any other problem during installation.
Also, when putting the scratchplate back on the guitar, you really, really, really need to watch out how those wires underneath are sitting. Make sure they all sit in there nice and snug …
… after all, you don’t want to break a ground connection halfway through your first gig with the guitar, do you? (like what I did … ho hum!)
LEDs, even ultra bright ones, have a small viewing angle, so keep this in mind when placing them. I simply put the LEDs on a small piece of stripboard, stuck them to the bottom of the casing inside the pickup cutout, with the LEDs themselves bent into slightly different angles so that the audience would see a little of the LEDs no matter what their viewing angle was. Also, to help add some more light difusion, I added some tissue paper to difuse the bright lights to a strip rather than individual bright spots.


The code is simple enough:
// Based on Lightstrip Controller // by Adam Greig, 2008-06-04 // CC BY-SA-NC 3.0 #define F_CPU 8000000UL // 8MHz #include <util/delay.h> #include <avr/interrupt.h> #include <avr/io.h> // The LED circuit is connected to PB4 on the ATTiny85 #define LEDS 4 // Some helper MACROS #define SET |= #define CLR &=~ #define TOG ^= //Converge - how fast the average will converge to the current value. Default: 10 #define CONVERGE 10 //Peak - what multiple of the average will be considered a peak. Default: 1.3 #define PEAK 1.3 //Store duty cycle, background average, current result, difference between result and average. volatile unsigned char duty; volatile unsigned char avg; volatile unsigned char result; volatile signed char diff; int main(void) { // set LEDS pin to output DDRB SET (1 << LEDS); PORTB = 0x00; // flash the LEDs twice to signify we're on PORTB SET (1 << LEDS); _delay_ms(1000); PORTB CLR (1 << LEDS); _delay_ms(1000); PORTB SET (1 << LEDS); _delay_ms(1000); PORTB CLR (1 << LEDS); //Initialise registers. Note that the compiler optimises each to an integer, so the 0s just make life easier. ADMUX = (0<<REFS0) | (1<<ADLAR) | (1<<MUX1) | (1<<MUX0); ADCSRA = (1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); DIDR0 = (0<<ADC0D) | (0<<ADC1D) | (0<<ADC2D ) | (1<<ADC3D); //Initialise ADC, ignore first result ADCSRA SET (1<<ADSC); while( ADCSRA & (1<<ADSC) ) {} // reset the ADC ADCSRA SET (1<<ADIE); ADCSRA SET (1<<ADSC); sei(); // infinite loop -- all the work is done in the ADC interrupt routine while (1) {} return 1; } // interrupt routine for when the ADC gets a result ISR(ADC_vect) { result = ADCH; //Find the difference and converge the average diff = result - avg; avg += diff / CONVERGE; // Determine if it's a peak, // and if so turn the LEDs if( result > avg * PEAK ) { duty = (100*result)/avg; } else { duty = 0; } //Execute the duty cycle if (duty != 0 ) { PORTB SET (1 << LEDS); } for( int j=0; j<duty; j++ ) { asm( "nop\n\t" "nop\n\t" "nop\n\t" :: ); } PORTB CLR (1 << LEDS); for( int j=100; j>duty; j-- ) { asm( "nop\n\t" "nop\n\t" "nop\n\t" :: ); } // and set it off again ADCSRA SET (1<<ADSC); }
So, there you have it. A flashing LED audio meter for your guitar pickups. If you have any questions, just ask!
[All files are released under Creative Commons BY-SA-NC 3.0]