This week in class focused on an introduction to Arduino and electronics hardware, which for once are topics that I’m familiar with as an computer engineering major. In class we had to create an SOS signal using a blinking LED as well as controlling the breathing speed of an LED using a makeshift capacitive touch sensor. The first was pretty straight forward but the second assignment didn’t end up really working in the end as the values it provided to the Arduino kept jumping around which stopped it from fading the LED smoothly.

For my out of class project, I decided to build upon my previous project where I attempted to recreate the strum bar mechanism for a Guitar Hero controller. While I work on the mechanical aspects of building an entire controller from scratch, I thought this would be a good opportunity to test whether it was possible to interface an Arduino with a PC and have control my game of choice (Clone Hero). I bought a used PlayStation 2 guitar controller from a friend which was broken, which was perfect for this project as I planned to replace all the internal electronics anyways. Functionality-wise, I needed to emulate gamepad button presses, but also a analog input for the whammy bar, which changes the pitch of the notes depending on how hard you press it. After doing some research I found out that I needed a microcontroller that supported native USB for what I wanted, so I bought a clone of the Spark Fun Pro Micro and went from there.
I started by opening up the casing of the guitar controller to get a sense of how the circuitry worked. Using a multimeter, I was able to find the main ground for all the inputs, and used the continuity functionality to find which traces corresponded to which buttons by randomly poking and pressing the buttons until I heard a beep, indicating the button caused the circuit to close. The whammy bar was relatively easy to work with, due to it having its potentiometer exposed. Having found where I would need to solder to hijack the buttons and potentiometer, I mounted the Pro Micro to a piece of perfboard and then soldered wires and resistors to each of the input pins I would need. Before I started soldering into the guitar, I wrote some test code to confirm that grounding each of the input pins actually generated the correct button presses and that my PC recognized the Arduino as a USB gamepad (it did!). The final step was soldering the new wires into the correct positions on the PCB of the controller, which was definitely a test of my soldering skills as many of the solder joints were small and tightly spaced, which led to a lot of bridged inputs that had to be redone. I also added a micro USB to type B adapter to avoid putting strain on the microcontroller’s micro USB socket and also have the ability to remove the cable and swap it for a different length without having to open up the casing.
#include <XInput.h>
#define ORANGE_FRET BUTTON_LB
#define BLUE_FRET BUTTON_X
#define YELLOW_FRET BUTTON_Y
#define RED_FRET BUTTON_B
#define GREEN_FRET BUTTON_A
#define STRUM_UP DPAD_UP
#define STRUM_DOWN DPAD_DOWN
#define START BUTTON_START
#define SELECT BUTTON_BACK
const int orangePin = 2;
const int bluePin = 3;
const int yellowPin = 4;
const int redPin = 5;
const int greenPin = 6;
const int strumUpPin = 7;
const int strumDownPin = 8;
const int selectPin = 18;
const int startPin = 19;
const int whammyPin = 20;
const int starPin = 21;
int orangeState = HIGH;
int blueState = HIGH;
int yellowState = HIGH;
int redState = HIGH;
int greenState = HIGH;
int strumUpState = HIGH;
int strumDownState = HIGH;
int startState = HIGH;
int selectState = HIGH;
void setup() {
//configure all input pins input and enable the internal pull-up resistor
for (int pin = 2; pin <=8; pin++) pinMode(pin, INPUT_PULLUP);
pinMode(startPin, INPUT_PULLUP);
pinMode(selectPin, INPUT_PULLUP);
// instantiate xinput
XInput.begin();
}
void loop() {
//read button states (NOT applied due to pullup resistor input configuration)
int orangeState = !digitalRead(orangePin);
int blueState = !digitalRead(bluePin);
int yellowState = !digitalRead(yellowPin);
int redState = !digitalRead(redPin);
int greenState = !digitalRead(greenPin);
int strumUpState = !digitalRead(strumUpPin);
int strumDownState = !digitalRead(strumDownPin);
int startState = !digitalRead(startPin);
int selectState = !digitalRead(selectPin);
// publish button states to xinput
XInput.setButton(ORANGE_FRET, orangeState);
XInput.setButton(BLUE_FRET, blueState);
XInput.setButton(YELLOW_FRET, yellowState);
XInput.setButton(RED_FRET, redState);
XInput.setButton(GREEN_FRET, greenState);
XInput.setButton(STRUM_UP, strumUpState);
XInput.setButton(STRUM_DOWN, strumDownState);
XInput.setButton(START, startState);
XInput.setButton(SELECT, selectState);
}