Sound Activated LEDs in Embroidery Using an ATtiny85

I love embroidery and electronics! This project’s goal was to create sound activated, embroidery embedded LEDs using an ATtiny85! My first step was to find a schematic and code that worked! I found on Technoblogy, a great resource for Arduino & AVR projects. I tested it out on a breadboard, successfully! I like to use ATtinys because you can program them with Arduino code and Sparkfun’s AVR programmer make it very easy!

Then I decided on an image to stitch. I figured a ferris wheel with ten seats worked perfectly, as the project uses ten LEDs. I digitize my images using SewArt, by S&S Computing. SewArt is awesome because it allows me to design unique embroidery files (PES for Brother machines) that incorporates textures.

Once my image was stitched with my Brother SE-400, I pressed it into an embroidery hoop so the fabric was taught and ready for placing components. Prior to hooking everything up I milled little PCBs for the resistors and ATtiny to sit on, making connections more secure and easy to solder. The end result looks a little messy. As much as I love sewing with conductive thread, wiring and soldering is much faster!

The components are as follows:

10 LEDs (they don’t have to be blue!)

2 10K resistors

1 2.2K resistor

1 uf Capacitor

1 Electret Microphone (I recycled mine from a fancy birthday card)


Power (3–5 volts)

The schematic was imperative in hooking the LEDs up correctly. The original project uses an LED bargraph, but you can use standard breadboard LEDs instead! This involves charlieplexing, which is essentially controlling multiple LEDs with very few pins. This project is using 4 pins from the ATtiny to control the LEDs, while the 5th usable pin is reserved for the capacitor and microphone.

/* ATtiny85 Sound Level Meter

David Johnson-Davies - - 1st January 2016
ATtiny85 @ 1 MHz (internal oscillator; BOD disabled)

CC BY 4.0
Licensed under a Creative Commons Attribution 4.0 International license:

volatile int Display = 0;

// Display **********************************************

int LogBar (unsigned int x) {
x = x | x>>1;
x = x | x>>2;
x = x | x>>4;
x = x | x>>8;
return x;

// Interrupt **********************************************

volatile int Row = 0;

// Interrupt multiplexes display
int Data;
Row = (Row + 1) % 5;
DDRB = 0; // Make all pins inputs
if (Row == 0) Data = (Display & 0xC0)>>3 | (Display & 0x20)>>4;
else if (Row == 1) Data = Display & 0x18;
else if (Row == 3) Data = Display>>8 & 0x03;
else if (Row == 4) Data = (Display & 0x03) | (Display & 0x04)<<1;
else { Display = LogBar(ReadADC()); return; } // When Row=2 read ADC
PORTB = (PORTB | Data) & ~(1<<Row); // Take row low
DDRB = DDRB | Data | 1<<Row; // Make row an output

// Analogue to Digital **********************************

unsigned int ReadADC() {
static int Read;
unsigned char low,high;
ADCSRA = ADCSRA | 1<<ADSC; // Start
do ; while (ADCSRA & 1<<ADSC); // Wait while conversion in progress
low = ADCL;
high = ADCH;
Read = max(Read>>1, high<<8 | low); // Add delay
return Read;

// Setup **********************************************

void setup() {
// Turn off Timer/Counter1 and USI to save 0.12mA
PRR = 1<<PRTIM1 | 1<<PRUSI;
// Set up Timer/Counter0 to generate 625Hz interrupt
TCCR0A = 2<<WGM00; // CTC mode
TCCR0B = 3<<CS00; // /64 prescaler
OCR0A = 24; // 625 Hz interrupt
TIMSK = TIMSK | 1<<OCIE0A; // Enable interrupt
// Set up ADC
ADMUX = 2<<REFS0 | 0<<REFS2 | 11<<MUX0; // Internal 1.1V ref, ADC0 vs ADC1 x20
ADCSRA = 1<<ADEN | 3<<ADPS0; // Enable, 125kHz ADC clock

void loop() {

The end result is very fun, resulting in a silly interactive embroidery piece you can hang on your wall!