Introduction: DIY Guitar Midi Controller (a.k.a. "Guitorgan")
Here's a weird one for all you MIDI enthusiasts out there. Somehow I got around to thinking about electronics and guitars at the same time, and it occurred to me that whenever you press a string against a fret you are making an electrical path between the two. The logical conclusion of this insight is that if you wire up all of the frets and strings of a guitar (yes I used a bass) to a micro-controller, you should be able to detect what notes are being fretted by testing the electrical conductivity between the frets and the strings! Combined with code to send MIDI messages and routed to a synthesizer, this creates a cool new way interface your guitar to your electronic setups. It's an alternative to hexaphonic pickup guitar synths that detects actual physical contact instead of processing signals.
I was pretty certain at that moment that I was on to something new, however this idea has been around for awhile, likely originating with the Guitorgan, which used this fret-detection method to drive an old school electric organ. It has also been perfected in a guitar called the Solange 6 from Industrial Radio. These professionally crafted instruments retail for $1500 to $4000 respectively.
Unfettered, I set out to make my own version of this synth for more to the tune of under $50. It turns out that, thanks the DIY friendly Arduino Mega, just about any guitar with metal strings can be converted to this setup if you're willing to modify the bridge, with a catch.
The catch is that we can only achieve partial polyphony (when you play more than one note at once). Achieving true polyphony requires completely different frets and make this project a lot more difficult.
Additionally, also understand that my current setup generates a lot of electrical noise when the instrument is plugged into an amp. I'm working on a different version that shouldn't have this issue. This setup is just the simplest hardware and code-wise to implement.
Step 1: Ingredients
To construct this monstrosity, you're going to need:
- A Sacrificial instrument
- Any guitar (or bass) with metal strings will work. I recommend a cheapo electric model, as they are very sturdy and the low action is great for this setup. You will need to modify your bridge though, on an acoustic you do not have to as the strings are already electrically isolated.
- Arduino Mega...for this setup we need a lot of inputs!
- Diodes (just your standard low-amp parts bin type)
- Plenty of 10K Ohm resistors
- A good length of Ethernet cable, 12ft+
- Quick setting, 5-min epoxy
- Superglue
- Soldering Equipment
- A fine point and fine solder (ideally leaded) are a must
- Drill and Bits
- A nice big breadboard
Step 2: Modify Your Guitar: Electrically Isolate Your Strings
Because the strings themselves are part of electrical circuits in this build, we need to make sure that there is no conductivity between them so the micro-controller knows which string is fretted. On an acoustic guitar this is not a problem, however electric instruments generally have their strings grounded in order to try and reduce noise. This is the exact opposite of what we want! You can test the conductivity between strings with a multi-meter, the resistance needs to be infinite.
The place where this happens is usually at the bridge, a metal piece at the base of the guitar that anchors down the strings. Examine your bridge and where the string makes contact with the metal. On mine, this was both at the strings anchors at the bottom of the bridge, and the metal saddle pieces that support the strings. Any metal surface that touches the strings needs to be coated in a non-conductive glue like epoxy or superglue.
For my saddle pieces, I was able to just apply a thin layer of superglue where the string rests.
Unfortunately, the string anchors at bridge could not be handled this way as the string and its end loop fit tightly into the base. I was able to fix this by getting out my drill and vastly over-boring these holes and filling them with epoxy. After it dried I then re-drilled the epoxy so it just fit the strings and the hole was "all glue". After re-installing my bridge and strings, my multi-meter showed no conductivity between the strings!
You will need to be creative for this step and figure out how to make you own instruments specific hardware non-conductive, though chances are it will involve drilling and glue.
Step 3: Modify Your Guitar: Solder Ethernet Wire to Your Frets and Strings
We're almost there with the modifications to the guitar. We will now solder on the wires that plug into our micro-controller. You will need two separate sections (or more) of Ethernet cable, ideally 6 ft or greater. Go ahead and strip all the wires at each end. One cable will be connected to the the frets, and the other to the strings. I only did 8 frets for this setup, but you can add more with more Ethernet cable.
Soldering to the strings is pretty straightforward. Make sure you have a nice bit of wire stripped, and then wrap it on the string after the saddle so it doesn't interfere with the vibrations. Then hit it with your iron and some solder, and the string should readily accept the connection.
The frets are a bit trickier to solder. In order to preserve play-ability of the guitar, we need to make these joints as smooth as possible, and also make the joint at the very end of the fret. Thin gauge leaded solder and a fine tipped iron make this a a lot easier, along with using a soldering stand to hold the wire against the fret. It also helps to pre-tin the edge of the fret and the tip of the wire. When doing this, the least amount of solder, the better!
Once you've got everything soldered, secure everything with tape so that the neck is playable, ideally with high contrast duct tape.
Step 4: Build the Circuit
The circuit setup I used in fundamentally the same as that used in touch keypads, basically a grid of overlayed wires with switches at the junctions. The micro-controller selectively energizes one axis of the grid, and then reads the voltage of each wire at the other axis to determine what connections are made. Instead of buttons, we use the fret to string contact as the switch.
For this setup, the powered axis of this grid is the strings. These will attach, through diodes, to your Arduino Mega Pins 4-9 (4-7 for me since I used a bass). You can verify the order once you get the code running.
The reading axis is the frets. Attach your fret wires to pins 22-29 (or higher if you have more frets), with a 10K Ohm resistor also connecting each wire to ground. This resistor, called a pull-down, ensures that charge does not build up in the string and cause a false reading when it is not activated as the wiring used acts as a capacitor. The controller won't work without these!
Putting it together:
The circuit isn't very complicated, it just involved a lot of wires doing the same thing. Use a nice big breadboard, and take advantage of the common ground rail for your pull down resistors. Definitely fasten the cable from the guitar to the breadboard securely. Also make sure you line up the frets to the pins in the right order, If they're reversed it's fine, you can change it in code, but you don't want them to be random!
Polyphony Limitations
The circuit and code is setup to recognize and play more than one fretted note at a time, however there are limitations due to the lack of segmented frets. Because the fret will conduct between strings, any chord scenario that frets strings adjacent to each other will cause all the strings to be part of the same circuit, resulting in the code reporting that all involved strings are playing the highest involved fret. For example, a major third interval, the two notes of a C chord, will be actually read as a fourth, the two fretted notes of an E Minor chord. If the fretted notes are far enough spaced apart, the note reading is correct.
Important Note:
The scanning method resulting in the strings rapidly (as fast as the micro-controller can go) being brought to voltage and back down to ground. On an electric guitar, this rapid cycling of voltage is picked up through the guitar pickups, resulting in a noticeable buzzing in the amp.
It's possible this could be filtered out somehow, but functionally this setup is not ready to be played at the same time the guitar is plugged into an amp. I am working on an alternative method using an array or different resistor values for the frets instead, and this could potentially fix the problem.
Step 5: Arduino Code
Here is the code you will upload to your Arduino Mega. It's available on my Github too. There's really not much to it, basically a nested loop to scan the frets and an array to keep track of what notes are being signaled.
Notice that our Arduino is sending MIDI messages over serial, and I do not have an actual MIDI port setup. This is handled by using a Serial-Midi device converter in software which I'll get to next. There are guides out there for hooking up a MIDI port if you want, it's not too difficult.
An important aspect is that the chosen note to play after the fretboard has been scanned is the highest registered fret, as fretting a note actually closes two (or more) circuits.
Pay attention to the DEFINE values and the arrays that define the pin values and string offsets. These are easily changed around. Notable BASENOTE sets the pitch of the whole instrument starting at the lowest string. 28 is E2.
//Midi_Guitar, Guitorgan Style //Michael Niemi, <a href="https://github.com/mvniemi/midi_guitar"> https://github.com/mvniemi/midi_guitar </a> #define NUM_STRINGS 4 #define NUM_FRETS 8 #define VELOCITY 100 #define noteON 145 #define noteOFF 129 //This is where you pick what note you want your lowest string to start at #define BASENOTE 28 //Set up for standard tuning of fourths int stringOffsets[] = {0,5,10,15,19,25}; //This is for my bass, add more pins for a 6 string int stringPins[] = {4,5,6,7}; int fretPins[] = {22,23,24,25,26,27,28,29}; int currentNote[NUM_STRINGS]; // void setup() { //Serial to send midi commands over Serial.begin(115200); //Initialize read pins for (int i=0; i< NUM_FRETS; i++){ pinMode(fretPins[i], INPUT); } // Initialize write pins? for (int i=0; i< NUM_STRINGS; i++){ pinMode(stringPins[i], OUTPUT); digitalWrite(stringPins[i], LOW); currentNote[i]=0; } } void loop() { //Scan Strings: We will scan down the neck string my string and set // the note as the highest detected fret // Currently setting the note after each string instead of after all strings for (int i=0; i < NUM_STRINGS; i++){ //Turn String High digitalWrite(stringPins[i], HIGH); //Set current note to zero int newNote=0; for (int k=0; k < NUM_FRETS; k++){ if (digitalRead(fretPins[k]) == HIGH){ newNote=k+1; } } //Turn String Low digitalWrite(stringPins[i], LOW); if (newNote != currentNote[i]){ MIDImessage(noteOFF, (currentNote[i]+stringOffsets[i]+BASENOTE), VELOCITY); if (newNote != 0){ MIDImessage(noteON, (newNote+stringOffsets[i]+BASENOTE), VELOCITY); } currentNote[i] = newNote; } // delay(); } } void MIDImessage(int command, int MIDInote, int MIDIvelocity) { Serial.write(command);//send note on or note off command Serial.write(MIDInote);//send pitch data Serial.write(MIDIvelocity);//send velocity data }
Step 6: Software
If we incorporate a hardware MIDI port into this setup, it can be directly plugged into a MIDI interface, and the serial commands directed through it. However I don't have such hardware, but we only need a couple pieces of software to solve this problem.
The Arduino Mega, when connected to your computer through USB, will send raw MIDI messages through the COM port. We need some software to read this serial signal and represent it as a MIDI device on your computer, which is done by The Hairless MID-Serial Bridge
Additionally, if you are using Windows, you need another program to create a "virtual MIDI loopback cable", it's called loopMID.
Once you've created a MIDI port in loopMIDI, and then connected it to your Arduino's serial port with Hairless, you should be able to receive MIDI commands into your DAW or whatever you're using to generate sounds!
Step 7: How Does It Play???
Without any sort of expressive modulation usually found on instruments (how hard you pluck a string or strike a key), this MIDI controller is truthfully a "digital" instrument. Notes are either on or off, with nothing in between. So it's best described as "experimental".
Combined with the nature of the string-fret switching interface, using this setup with MIDI instruments that expect modulated, expressive control can be a bit chaotic. You must be extra precise with your fretting in order to not "glitch" your notes. I haven't read up much on Guitorgans, but I'm guessing they are less forgiving than a normal guitar with your technique. I'm considering introducing some sort of filtering in the code that would allow a "grace period" when a note is disengaged before the OFF midi command is sent, which might help things out.
One solution to this is to use virtual instruments with strong aspects of attack and decay, meaning the sound takes a little while to build up and drop off, and that some expression is already built in.