Arduino Keytar

Created by: Mario Scala
 
 
Description: Using the idea of a "cigar box guitar", I took the body of one of these "guitars", inserted the Arduino brain into it and programmed it to produce certain notes based on where the strings were touching the frets, making an Arduino-ized version of a keytar.  I also included a small knob on the keytar which acts as a "whammy-bar" for the guitar, bending the notes depending on how much it's turned.



*The "pitches.h" library is used as a reference for basic note progression and how I could bend each note.  Can be found at: http://arduino.cc/en/Tutorial/Tone 
#include "pitches.h"

int buttonPin = 1;
int buttonState = 0;
int buttonPin2 = 0;
int buttonState2 = 0;
int buttonPin3 = 3;
int buttonState3 = 0;
int potPin = 4;
int potValue = 0;

void setup (){
  Serial.begin(9600);
}
void loop ()
{
  potValue = analogRead(potPin);
  buttonState=analogRead(buttonPin);
  buttonState2=analogRead(buttonPin2);
  buttonState3=analogRead(buttonPin3);
//reads the value of strings 1-3 and the potentiometer, the values change when you press down on a different fret

  if(buttonState>=500 && buttonState<=525) //buttonState is the first string
  {
    int note = NOTE_E1; //if the value of the resistors is between the values, this note will be played
    potValue = map(potValue, 0, 1023, -8, 8);
    if (potValue>= -3 && potValue<=3)
    {
      tone(2, note);
      delayMicroseconds(potValue); //if the potValue is between the numbers, the "int note" will be played
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);  //if the potValue is not equal to any of the numbers in the previous "if", 
      //the potentiometer will change the pitch of the note, creating a "note-bending" effect. 
    }
  }
  else if (buttonState>=670 && buttonState<=690) //checks for next resistor value
  {
    int note = NOTE_F1;
    potValue = map(potValue, 0, 1023, -8, 8);
    if (potValue>= -3 && potValue<=3)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState>=760 && buttonState<=775)
  {
    int note = NOTE_FS1;
    potValue = map(potValue, 0, 1023, -10, 10);
    if (potValue>= -4 && potValue<=4)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState>=810 && buttonState<=825)
  {
    int note = NOTE_G1;
    potValue = map(potValue, 0, 1023, -10, 10);
    if (potValue>= -4 && potValue<=4)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState>=845 && buttonState<=860)
  {
    int note = NOTE_GS1;
    potValue = map(potValue, 0, 1023, -10, 10);
    if (potValue>= -4 && potValue<=4)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState>=870 && buttonState<=885)
  {
    int note = NOTE_A1;
    potValue = map(potValue, 0, 1023, -12, 12);
    if (potValue>= -5 && potValue<=5)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState>=890 && buttonState<=970) //anything from around fret 7 and up will be one tone
  {
    int note = NOTE_E4;
    potValue = map(potValue, 0, 1023, -150, 150);
    tone(2, note+potValue);
    delayMicroseconds(potValue);
  }

  else if(buttonState2>=680 && buttonState2<= 695) //buttonState2 is the second string
  {
    int note = NOTE_A1;
    potValue = map(potValue, 0, 1023, -10, 10);
    if (potValue>= -4 && potValue<= 4)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=810 && buttonState2<= 825)
  {
    int note = NOTE_AS1;
    potValue = map(potValue, 0, 1023, -12, 12);
    if (potValue>= -5 && potValue<= 5)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=865 && buttonState2<= 885)
  {
    int note = NOTE_B1;
    potValue = map(potValue, 0, 1023, -14, 14);
    if (potValue>= -6 && potValue<= 6)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=900 && buttonState2<=915)
  {
    int note = NOTE_C2;
    potValue = map(potValue, 0, 1023, -14, 14);
    if (potValue>= -6 && potValue<= 6)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=920 && buttonState2<= 935)
  {
    int note = NOTE_CS2;
    potValue = map(potValue, 0, 1023, -16, 16);
    if (potValue>= -7 && potValue<= 7)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=940 && buttonState2<= 946)
  {
    int note = NOTE_D2;
    potValue = map(potValue, 0, 1023, -18, 18);
    if (potValue>= -8 && potValue<= 8)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=947 && buttonState2<= 958)
  {
    int note = NOTE_DS2;
    potValue = map(potValue, 0, 1023, -18, 18);
    if (potValue>= -8 && potValue<= 8)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState2>=960 && buttonState2<= 1000)
  {
    int note = NOTE_A4;
    potValue = map(potValue, 0, 1023, -300, 300);
    tone(2, note+potValue);
    delayMicroseconds(potValue);
  }
  else if(buttonState3>= 680 && buttonState3<= 700) //ButtonState3 is the third string
  {
    int note = NOTE_D2;
    potValue = map(potValue, 0, 1023, -20, 20);
    if (potValue>= -9 && potValue<= 9)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState3>= 812 && buttonState3<= 825)
  {
    int note = NOTE_DS2;
    potValue = map(potValue, 0, 1023, -22, 22);
    if (potValue>= -10 && potValue<= 10)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState3>= 875 && buttonState3<= 885)
  {
    int note = NOTE_E2;
    potValue = map(potValue, 0, 1023, -24, 24);
    if (potValue>= -11 && potValue<= 11)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState3>= 905 && buttonState3<= 915)
  {
    int note = NOTE_F2;
    potValue = map(potValue, 0, 1023, -26, 26);
    if (potValue>= -12 && potValue<= 12)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState3>= 922 && buttonState3<= 938)
  {
    int note = NOTE_FS2;
    potValue = map(potValue, 0, 1023, -30, 30);
    if (potValue>= -14 && potValue<= 14)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState3>= 940 && buttonState3<= 949)
  {
    int note = NOTE_G2;
    potValue = map(potValue, 0, 1023, -32, 32);
    if (potValue>= -15 && potValue<= 15)
    {
      tone(2, note);
      delayMicroseconds(potValue);
    }
    else{
      tone(2, note+potValue);
      delayMicroseconds(potValue);
    }
  }
  else if(buttonState3>= 951 && buttonState3<= 999)
  {
    int note = NOTE_C5;
    potValue = map(potValue, 0, 1023, -400, 400);
    tone(2, note+potValue);
    delayMicroseconds(potValue);
  }
  else
  {
    noTone(2); //if none of the above values are met (ie, no strings pressed down), this stops the Arduino from producing more sound
  }

}


Extended Description: The Arduino  keytar code may look complicated but at least 60% of it is just a repeating line. Let's start at the top.
We declare our variables. I decided to use "buttonPin" because it's the variable name I used when I was learning how to use push-buttons, and that's essentially what the strings and frets serve as. A push-button, when pressed down, simply completes the circuit. Pressing the string down on the fret completes that circuit. So we assign the names of the strings and the potentiometer (which is the whammy-knob) and what pins they attach to. The strings are attached to wires that feed into the breadboard. They're connected to 2200 ohm resistors and in that same row as the resistor, connected via another wire to the pin. 
Now let's look at the loop code, the part that assigns notes to specific values. We declare that the buttonState, buttoState2, or buttonState3 reads the value of the pin once it completes the circuit (or touches the fret). 
                              
The string of resistors runs from a positive lead in the breadboard and down the neck of the guitar. The resistors are soldered together to ensure a connection is present. A third wire is soldered from the interlocking resistors to the fret. This is where our values will come from. The resistance going through the resistor can now be detected in the fret, giving us something to measure for our value. So, when we touch the string to the fret, the Arduino can detect the value that runs through the resistors.
In short, the value of ohms running through the resistors changes as you touch frets that are further down the neck. We tell the Arduino to measure this value, giving us the numbers in our code, like "if(buttonState>=900 && buttonState<=910" for example. The "delayMicroseconds" command will tell the Arduino how long to wait before producing the tone again. Making it delay in microseconds will make the tone sound constant as if there were no breaks in it. If we press down on a fret and the value is anywhere between these numbers, we go on with the code and play the note that we assigned to it. If no frets are pressed down (or specifically, if no value requirements are met) then, based on the code, no sound will be produced.

The value of a given resistor is pretty much constant across the fret, meaning that it will be close to the same for all strings. This means that over 60% of this code is simply repeating and changing the variable names and a couple of other numbers to create a wide range of notes across all strings and frets. 

Problems: I didn't have many problems but I did have a couple that were a pain trying to deal with. I would say that between 70-80% were a result from building the actual keytar. The most frustrating part of building the keytar was soldering a wire from the resistors running down the neck of the keytar to the frets. At first it seemed that the music wire was too thick to soleder a wire to so I tried wrapping magnetic wire around it and then soldering that wire to the resistors. Well, it turned out that I didn't burn the coating off the magnetic wire enough so it wasn't conductive at all. I then removed all of the wire and decided to just try to solder regular wire to the music wire again. This time it actually worked and ended up turning out great.
 
Another major problem I had was the third string playing the same notes as the second string. After an hour of trying to figure out if it was the code or the wiring I found out that the third string was making contact with the second string at the head of the guitar, causing it play whatever the second string did.
 
The only other problem I ever had was when measuring the current in the resistors when I pressed a string down on the fret. As I put more and more frets on, any fret from around #7-14 started having inconsistent values. To fix this, I decided to assign any fret from that number on to produce the same note, but instead it would be a note with a high frequency that could be manipulated very easily from the "whammy-knob".
 
Things i would like to change: If I had more time, I would like to make an easier way to hold to strings in place. The bolts and knobs that were in the head of the guitar ended up working but were finicky when it came to holding strings in place. If I could redo it, I would want to put in newer bolts and maybe change the way they hold the strings in to make it less of a hassle.
 
Another thing I would change is the speaker. The speaker isn't as loud as I would have liked and if I had more time I would want to put in a higher quality speaker.

One of the most important things I would like to add is a battery so that you don't have to hook up the guitar to a computer to power it, along with a strap bolted onto the guitar so you could walk around and play without any limitations. 
Comments