Store

...Coming soon

Archives

Guitar Zero PS2

Home -> Guitar Zero PS2

How I Hacked My Guitar Hero Controller to Play Songs For Me

I’m normally a software guy and hacking my Guitar Hero controller seemed like a good way to learn/relearn about microcontrollers and electronics in general.

Step One – Figure out if it’s possible.GH Internal Wiring

So I opened up the controller. Pretty simple inside and not hard to figure out how everything is connected. 6 wires going out to the buttons, one each for the buttons and a final wire for ground. I played around with shorting each note to ground and verifying that the PS2 recognized these as button presses. The strum bar works similarly – it’s really just two buttons, one for down strumming, one for up strumming.

Here I'm shorting the strum-down button pins. The controller recognizes this as a regular down-strum.

Here I'm shorting the strum-down button pins. The controller recognizes this as a regular down-strum.

If I can short these connections with a wire, I can short them with a microcontroller. We’re good to go.

Step Two – Learn about microcontrollers.

At first I thought I would use a PIC microcontroller or a Basic Stamp since that seemed to be what everyone who uses microcontrollers for anything uses, but the more I read about PICs, the less I liked them. I won’t go into details, but it doesn’t seem like PICs are very suitable for complicated programming. Or simple programming.

Then I discovered Atmel AVR microcontrollers. While there isn’t a vast collection of books / websites / example projects dedicated to AVRs like there is for PICs, there is a decent-sized community, and a few really good example projects, so I decided to try out the AVR.

I purchased a POV (persistance of vision – LEDs that you wave back and forth so they spell something) kit from makezine.com / Lady Ada. Instructions for building it and soldering it together are on Lady Ada’s site, along with the source code, instructions for compiling the source code and instructions for putting it on the device. Pretty soon I had it programmed to pretend to play the first several hundred notes of “I Wanna Rock”, by treating the first 5 LEDs as the fret buttons and the last LED as the strum bar. This was a very simplified version of things, but the pieces were coming together.

GH POV Kit

My MiniPOV kit has no trouble nailing the first few power chords of I Wanna Rock

I also purchased the strangely named LED Micro-Readerboard kit and modified it to say different things. (source code for this one was somewhere on Evil Mad Scientist) I rigged it up with a small on/off switch and a gigantic button cell battery (the CR2447 – it gives a whole new meaning to “button cell”), and sent it to my mom as a christmas ornament. Hopefully it won’t burn the tree down.

These are really great projects for learning soldering, microcontrollers, programming, you name it, and they’re really reasonably priced. There are plenty of other great projects on both the Make website and Lady Ada’s. Collect them all.

Step Three – Fancy Looking Circuit Diagrams

First of all internally to the controller, each button probably consists of Vcc connected to a pull-up resistor (I strongly encourage you to read the linked article, it explains a lot) connected to the guitar’s microcontroller and a button which connects all this to ground. When you press the button, the signal goes low. When the button is not pressed, the signal is high. Here’s a sketch:

GH Fret Button

So I figured I would use a transistor for each button and one for the strum bar. With my microcontroller I could trigger the transistor for each button as needed. A better option would probably be to use opto-isolators to keep my circuit completely separate from the guitar’s. An even better option would probably be to use power from the guitar instead of my own power source, and just trigger the buttons directly. Below you can see my diagram for a hacked button. When my microcontroller (on the left) triggers the transistor in the middle of diagram, it’s just like pressing the button.

GH Hacked Button

Step Four – Buy Some Parts.

I settled on the Atmel Atmega168 AVR microcontroller. It’s roughly on par with the Apollo Guidance Computer used in the Lunar Excursion Module for landing on the moon. (This AVR can run faster but has less memory) Needless to say, Guitar Hero songs on expert are significantly more complicated than moon landings. The sole reason for choosing the Atmega168 was memory – the Atmega168 has 16Kb of program space. I knew this would be at least enough for one song.

I ordered a bunch of supplies from DigiKey and Mouser.com. Five Atmega168s, wires, resistors, LEDs transistors, ceramic resonators, etc. I also ordered an “In System Programmer” for the atmega168s (works for any AVR) – have to get your program on there somehow.

Step Five – Programming (What To Do While You Wait For Your Parts)

Microcontrollers are very tight on memory so I had to come up with an efficient way to describe a song. Basically I decided on a giant byte array of two-part instructions. First instruction – which fret buttons. In binary, 0b00011111 would be all the buttons (never seen that in a song yet), 0b00010001 would be green and orange, you get the idea. the second instruction would be the delay between that note and the next in milliseconds. Since I’m using bytes, the maximum wait is 255 ms, so I also came up with some supplemental instructions to handle issues like that – plenty of room for that since I only need 5 bits to describe the 5 buttons. To further save space I could possibly borrow 2 bits from the “instruction” and make the delay a 10-bit value. If memory gets tight, we can look into that. Below is the beginning of the definition for “Crossroads” on Guitar Hero 1.

#define G          0b00000001
#define R          0b00000010
#define Y          0b00000100
#define B          0b00001000
#define O          0b00010000
#define HAMMER     0b00100000
#define SAMENOTE   0b01111111

const uint8_t song[] PROGMEM = {
	G, 238,
	B, 238,
	Y, 238,
	B, 255,
	SAMENOTE, 102,

… you get the idea.

GH Note Chart - Crossroads

How did I arrive at these delays? See the note symbol at the top of the note sheet, next to the number 126? 126 beats per minute = .47619 seconds per beat. There is a 1/2 beat pause between the first and second notes – 238 milliseconds. There is a 3/4 beat pause between the 3rd note and the fourth – 357 ms.

Rather than deal with issues like how long to hold a given note, I just always hold each note until it’s time for the next one.

Step Six – Get it working.

So I hooked it all up on a bread board and after some basic debugging… It worked! Kind of!

Turns out timing is really important.

Below is a video of what everything looked like at this point…

So basically, timing has to be perfect. One possible solution is to add “Speed Up” and “Slow Down” buttons. when pressed they could cause the program to jump-ahead /wait-an-extra 20 ms or so. (so not actually speed up or slow down) This would allow for on-the-fly adjustment. Ideally, however, we want to just get the timing perfect.

Turns out you can extract a MIDI file from the game disc with a description of how the song is played with time differences down to the microsecond. I wrote a simple script to turn this midi into a header file in the format I described above – first byte is which buttons, second byte is how long to wait till the next note.

Even with that information, my microcontroller was a little off. Still haven’t figured out why that is, if I had an oscilloscope I could see how accurate my external resonator is.

I “solved” the remaining timing issues by inserting extra delays here and shortening some delays there.

Step Seven – Spit and Polish

I recreated the whole thing on a prototype board, soldered it all together, drilled some holes in the controller for buttons and switches and LEDs. It took me 3 prototype boards to get it all working. There’s soomething about those prototype boards from Radioshack – they suck. Eventually I ran out of Atmega168s. I had happened to order some ATTINY 861’s with my previous order so I modified all the code to work on that – which took about a day, unfortunately. I also gave up on the whole transistor thing and switched to powering my microcontroller from the guitar’s power supply and basically just sending a logic 0 to the guitar’s own microcrontroller when I want to press a button. I just couldn’t get a complicated circuit with multiple resistors and transistors to work on one of those crappy Radioshack prototype boards.

But this is a much better way to do it anyway. No need for an external power source, no need for 6 resistors and 6 transistors (1 for each button and the strum button).

GH Guts

Here’s a close up of the wires I soldered on to the guitar PCB. Note that I basically have 3 wires that are soldered to ground on the PCB. That’s a little redundant, obviously, but when I did the soldering I hadn’t fully understood the circuitry.

GH PCB

Microcontroller Close-up

GZ PS2 Exterior

All put together it looks pretty nice. An over-the-top on/off switch on the side and two indicator LEDs and a single button to press when it’s time to play the first note of “Bang Your Head”.

There’s still one giant elephant in the room here – the device has to be reprogrammed any time I want to make it play a different song. Obviously that totally sucks. Perhaps for revision 2 I’ll put some flash memory on the circuit board and hook up a dip switch for selecting different songs. It’s important on any project like this to accumulate a list of improvements to never get around to.

Source Code

Right here if you want it. It’s a little hacked together because it’s written for 3 different microcontrollers – ATTINY2313, ATMEGA168 and ATTINY861 – and design changes were made in between – the ATMEGA168 code, for example, signals buttons and strumming with by going high, the ATTINY861 code signals buttons and strumming by going low. The ATTINY2313 code is incomplete because those parts were only written for my MiniPOV proof of concept. I left the code for each microcontroller in there though so that I would at least have an outline if I switched back.

Also included in there is my script for extracting information from a MIDI file. Note that it doesn’t read a raw MIDI file, it reads a text version of the MIDI file. I found some random web site that would translate MIDI files into a list of text instructions… Here: http://midi.mathewvp.com/midiEditor.php. Click the “Show MIDI result as Text” box.