«

»

Print this Post

Geek Spin – ATTiny44 Project Prototype

Some days you feel like working on projects to benefit humanity. The day I made this clearly wasn’t one of those days. A little over a year ago, I got into a troll war with my friend Mike Seese. The joke, similar to that of rick rolling, was to get each other to unexpectedly click a link to the Hatsune Miku version of the leekspin song. After several weeks of becoming beyond annoying, I decided to make an actual Hatsune Miku which would spin her leek and bobble her head to the techno version of the Levan Polka for his birthday.

The goal was to create a minature Miku which would perform perfectly in sync with audio coming from a portable music player (iPod or something) and NOT require a computer connection. I accomplished it by sending some creative control beeps out of the left channel of the stereo signal. Although I didn’t finish the project, I got pretty far with the prototype, so I decided to dig it out of the archives and share it with the world because it’s pretty entertaining!


(look how close I came to replicating the original!)

How did I do it? First off, I used servos. If you’re not familiar with them, I suggest you look up how servos work. Perhaps check out how to control servos with AVR microcontrollers. Basically, their position along a rotational axis is determined by the width of a pulse on a 20ms time window. Anyhow, if I only had 1 servo to control (i.e., leek only), I’d have controlled the servo directly with PWM signals in the left channel – no microcontroller needed, easy as pie, problem solved. However, since I needed to control two servos, I had to come up with something a bit more creative. Although I could have probably done this ten different ways, the way I chose to do it was using a series of pre-encoded leek spin and head bobble motions, triggered by control beeps in the left channel of the audio cable. (The right channel was patched through to the speakers.) Below is a diagram of what I believe I did, although I didn’t thoroughly document it at the time, so you might have to use your imagination if you decide to re-create this project.

The idea is that by sending bursts of sine waves, the circuit can rectify them and smooth them out to have them look to a microcontroller like a brief “high” signal. Each signal would tell the microcontroller to proceed to the next pre-programmed (and carefully timed) routine. With enough practice listening, watching, and tweaking the code, I was able to make a final version which worked pretty darn well!

LISTEN TO:MUSIC WITH CONTROL BEEPS (it’s a surprisingly fun listen)

A few technical details are that I used an ATTiny44a microcontroller (it may have been an ATTiny2313, I can’t remember for sure, but they’re so similar it’s virtually negligable). The servos I used were cheap (maybe $4?) from eBay. They looked like the one pictured below. The servo position was controlled by PWM, but I manually sent the pulses and didn’t actually use the integrated PWM in the microcontroller. I can’t remember why I did it this way – perhaps because it was so simple to use the _delay_us() and _delay_ms() functions? I also used an operational amplifier (if I remember, it was a LM741) to boost the left channel control signals rather than rectifying/assessing the left channel directly.

This is the video which I mimiced to create my prototype (note how the leek in her arm and her head move exactly the same as the prototype I made – score!)

For good measure, here’s the original song:

And how did I find out about this song? I actually saw it on the video below which was hosted on wimp.com. I thought the song was catchy, looked it up, and the rest was history. It’s worth noting that (perhaps to avoid copyright issues?) the key was shifted two half-steps up. I get a kick out of the way the girl waves her arm in the beginning, mimicking the leek :)

Here are some of the images I made which I printed, glued to foam board, and cut out with a razor blade. I’m not sure how useful they are, but they’re provided just in case.


… but sometimes Japan takes it a bit too far and things get awkward …

Below is the code I used. Note that PWM that controls the servos isn’t the integrated PWM, but rather a couple pins I manually pulse on and off to control the arm and head positions. Also notice how, in the main routine, I wait for the control beeps before continuing the next sequences.

// leek spin code - designed for ATTiny
// by Scott Harden, www.SWHarden.com

#include <avr/io.h>
#include <avr/delay.h>

void go_high(){
	// sets the arm to the highest position
	for (char i=0;i<5;i++){
		PORTA|=(1<<PA0);
		_delay_us(1400);
		PORTA&=~(1<<PA0);
		_delay_us(20000-1200);
		}
	}
		
void go_low(){
	// sets the leek to the middle position
	for (char i=0;i<5;i++){
		PORTA|=(1<<PA0);
		_delay_us(1900);
		PORTA&=~(1<<PA0);
		_delay_us(20000-1900);
		}
	}
		
void go_lowest(){
	// sets the leek to the lowest position
	for (char i=0;i<5;i++){ // takes 100ms total
		PORTA|=(1<<PA0);
		_delay_us(2300);
		PORTA&=~(1<<PA0);
		_delay_us(20000-2500);
		}
	}

void go_slow(char times){
	// does one slow leek down/up
	// beat is 500ms
	for (char i=0;i<times;i++){
		go_low();
		_delay_ms(10);
		go_high();
		_delay_ms(290);
		PORTA^=(1<<PA2);
		PORTA^=(1<<PA3);
	}
}

void go_fast(char times){
	// does one fast leek down/up
	// beat is 250ms
	for (char i=0;i<times;i++){
		go_low();
		_delay_ms(10);
		go_high();
		_delay_ms(15);
		PORTA^=(1<<PA2);
		PORTA^=(1<<PA3);
	}
}
void head_left(){
	// tilts the head to the left
	for (char i=0;i<5;i++){
		PORTA|=(1<<PA1);
		_delay_us(1330);
		PORTA&=~(1<<PA1);
		_delay_us(20000-1200);
		}
	}

void head_right(){
	// tilts the head to the right
	for (char i=0;i<5;i++){
		PORTA|=(1<<PA1);
		_delay_us(1500);
		PORTA&=~(1<<PA1);
		_delay_us(20000-1200);
		}
	}

void head_center(){
	// centers the head
	for (char i=0;i<5;i++){
		PORTA|=(1<<PA1);
		_delay_us(1400);
		PORTA&=~(1<<PA1);
		_delay_us(20000-1200);
		}
	}

void head_go(char times){
	// rocks the head back and forth once
	for (char i=0;i<(times-1);i++){
		head_left();
		_delay_ms(400);
		PORTA^=(1<<PA2);
		PORTA^=(1<<PA3);
		head_right();
		_delay_ms(400);
		PORTA^=(1<<PA2);
		PORTA^=(1<<PA3);
	}
	head_center(); // returns head to center when done
	_delay_ms(400);
	PORTA^=(1<<PA2);
	PORTA^=(1<<PA3);
}

int main(void) {
	while (1){
		DDRA=255; // set port A (servos) as outputs
		DDRB=0; // set port B (listening pins) as inputs
		
		go_lowest();head_center();// set starting positions

		while ((PINB & _BV(PB0))){} // wait for beep que
		PORTA=(1<<PA3);
		go_high();_delay_ms(1000);
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_slow(31); // tilt leek slowly 31 times
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_slow(31); // tilt leek slowly 31 times
		
		while ((PINB & _BV(PB0))){} // wait for beep que
		_delay_ms(200);
		head_go(16); // rock head 16 times
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_fast(68); // tilt leek rapidly 68 times
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_slow(24); // tilt leek slowly 24 times
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_fast(17); // tilt leek rapidly 17 times
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_slow(31); // tilt leek slowly 31 times
		while ((PINB & _BV(PB0))){} // wait for beep que
		go_slow(31); // tilt leek slowly 31 times
		
		while ((PINB & _BV(PB0))){} // wait for beep que
		_delay_ms(200);
		head_go(16); // rock head 16 times
		go_lowest(); // reset position
		PORTA=0;
	}
  return 0;
}

Finally, I’d like to take a moment to indicate one of the reasons this project is special to me. My wife, Angelina Harden, died one year ago today. This project was the last one she worked on with me. She died a few days after the video was taken, and in the process of moving out of our apartment I threw away almost everything (including this project). Although I never finished it, I remember working on it with Angelina – we went to wal-mart together to buy the foam board I used to make it, and she told me that I should make her head rock back and forth rather than just move her arm. I remember that, once it was all done, I let her sit in the chair in front of it and played it through, and she laughed nearly the whole time :) I’ll always miss her.

About the author

Scott W Harden

Scott Harden has had a lifelong passion for computer programming and electrical engineering, and recently has become interested in its relationship with biomolecular sciences. He has run a personal website since he was 15, which has changed names from HardenTechnologies.com, to KnightHacker.com, to ScottIsHot.com, to its current SWHarden.com. Scott has been in college for 10 years, with 3 more years to go. He has an AA in Biology (Valencia College), BS in Cell Biology (Union University), MS in Molecular Biology and Microbiology (University of Central Florida), and is currently in a combined DMD (doctor of dental medicine) / PhD (neuroscience) program through the collaboration of the College of Dentistry and College of Medicine (Interdisciplinary Program in Biomedical Science, IDP) at the University of Florida in Gainesville, Florida. In his spare time Scott builds small electrical devices (with an emphasis on radio frequency) and enjoys writing cross-platform open-source software.

Permanent link to this article: http://www.SWHarden.com/blog/2012-08-18-geek-spin-attiny44-project-prototype/

5 comments

  1. Carolyn Adams

    Just want you to know that I am thinking about you today as usual. I know this has been a really hard year for you and some of us too. Let meknow how schoolis going. Love always, Mrs A

  2. kevin

    Good project, I can see why your wife enjoyed it.

    I am almost a year into losing my dad, the best man at my wedding. It happened just a few days after my son was born, the first grandchild in the family… I wish they had had the opportunity to meet each other. I know how much I miss my father and how I think about him all of the time, especially when I really want to talk to him. I cannot imagine what you are going through. My heart breaks just thinking about it. You are in my thoughts and prayers. I love reading your blog, it is certainly one of the best out there.

    Keep your chin up, there are a lot of us cheering you on.

  3. Patricia

    Wow, who knew it was a leek???? Too cool. Thanks for getting that tune totally stuck in my head. Love the rollerblading girl. Amazing. Soooo glad to see you are back to your blog. We are proud of you – more than you will ever know. Also, we understand that it isn’t super easy coming home with all the memories. No need to ever explain. What a touching section…how you analyzed the things that are helping you heal the pain. We will always love and miss Angelina, too. She was one special young lady who totally loved you and thought you were amazing!

    Love you, Scott!! Keep the entries coming. I still can’t believe you are the same guy who we used to have to bribe to finish a book or write a paper. God sure has given you some amazing gifts and talents. Don’t take them for granted! Keep using them and totally impressing us :)

  4. Holly Minkowski

    That is a really cute project Scott! :-)

    I’m so sorry about your wife…. she was so beautiful, and from the pictures it seems she loved life and you a whole bunch.

    (now I’m in tears…oh my)

    I’m saying a little prayer for you, you seem so nice…and also very very smart!

    I also love uC programming and I simply adore the Atmel controllers.
    I like the Parallax Propeller a lot also. (PDIP and eight 32bit cores for just 8$ [160MIPS] Free IDE and GCC, who couldn’t like that chip?)

    Holly in Israel….

    Live long and prosper Scott, the world needs more nice geeks like you

  5. Williemae

    This site was… how do I say it? Relevant!! Finally I’ve found something that helped me.
    Thanks!

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>