Simple Vypyr Foot Switch
Possibly I’m a little old-fashioned, but I have this concept of what a guitar amplifier foot switch should look and work like, and the current offerings of amplifier controls just don’t fit that expectation. My mind just sees something more like an old Fender or Vox foot switch. I’m not talking about distortion pedals or Wahs here – just a simple amplifier foot switch.
One of the regular contributors on the Peavey Vypyr Forum (nullvalue) recently posted a project where he used an Arduino to make an amplifier switch for his amplifier. Looking at his example I realized that it would be rather simple to make a foot switch more to my liking with readily available components.
Thinking about how I would go about this, I came up with a project in three phases. The first phase would be a simple two button switch that would let me change amplifier presets. The idea here being that if I wanted to change between a clean amp and over-drive I could just use two different presets.
The second phase would be to replicate the foot pedal that nullvalue created, with a more complex display and the ability to select multiple functions for the switches from the foot pedal. The third phase would be to create a pedal that would interact with the Vypyr, allowing the use of factory presets and options that are usually limited to controlling the amplifier using Peavey’s Sampara II footswitch.
This blog will take you through my experiences building the first phase of this project.
This phase has a few material requirements. The first is a switch box with a couple of switches. My thought was that the best way to make this like an amplifier foot switch would be to actually use an amplifier foot switch. I purchased a VOX VFS-2 second-hand from the local music store for about $20.00. This gave me a case and two switches to work with.
The next item I needed was some way to create and transmit MIDI siginals that the Vypyr needs for communication. This is really simple to do using an Arduino. These are small control computers that are often used in science projects and simple robotics built by high-school kids. In the previously mentioned project built by nulvalue, he used an Arduino Duemilanove. These can be easily found for around $20.00. However, I wanted to make sure that my solution fit inside a smaller package so I chose to use an Arduino Micro instead. The Micro is much smaller, but performs the same functions. These cost around $25.00, but can be found for $10.00 or so if you shop carefully.
BOM:
- Arduino Micro
- Case
- 2 on/off switches (these were in my case)
- 2 1/8 watt 330K Ohm resistors
- 1 1/8 watt 220 Ohm resistors
- 9 volt battery holder Model 270-325 | Catalog # 270-325
- Prototyping Board Radio Shack xxx-xxx
- DIN-8 Socket Digi-key CP-7080-ND but a CP-1238-ND would work better
- 4X 4-40 machine screws and nuts for mounting the breadboard
- Some 1/8” styrene for PC board standoffs.
Aside from wire and solder, two 330K resistors, one 220 Ohm Resistor, and a prototyping board to solder things together with the only other item that I needed was a MIDI socket and a battery holder. I ordered a couple of these from digi-key. I chose to order the eight-pin DIN version of the socket because of my plans for phase II and III of this project; however a DIN-5 socket would work just as well at this point. Phase I uses batteries or a stomp-box power supply for power and only transmits TO the vypyr so the other MIDI lines are not needed.
Quite honestly, the most difficult part of this project was drilling the holes for the MIDI connector and mounting the hardware inside of the case. The MIDI socket needs a 5/8” hole drilled in the chassis. The next difficulty was measuring the location for the holes properly. I did not do this very well, but things worked out for me regardless.
You may notice that the chassis that I am using has a largish rectangle cut out of the face of the foot switch. This will be used in phase II of the project when I add an LCD display to the foot pedal. You should also note in the front view of the box that there is a large hole in the center. This is to allow me to connect the Arduino to my computer to change the functionality of the footswitch by tweaking the program on the Arduino.
If you have not used an Arduino before you are in for a nice surprise. There is a very good (FREE) development environment that you download onto your PC that lets you write programs and instructions for the Arduino to execute. Once you have the instructions worked out, you simply connect the Arduino to your computer using a USB cable and download the new personality to the device. It will execute the code that you have written even after you have disconnected it from your computer. All it needs is a power source and your instructions will be executed. You should be able to spot the USB connector at the end of the Arduino in the accompanying pictures.
One of the cool things about this approach is that if you should decide that you want the Arduino to do something different (possibly a foot controller for Guitar Rig 5 or ReValver?) you can make a few simple changes to the coding and use the device for some other purpose.
Once the parts were collected, I fitted the bread boards to the Arduino and drilled holes in the chassis to attach it. This also let me know where I was going to need to drill holes for the MIDI socket as well as an access hole to allow me to plug in the USB without having to open the chasis.
I first soldered the battery clip for a nine volt battery so that it could supply power to the Arduino. On my revision 3 board this goes to the third (+) and fourth (-) pins on the right side with the reset switch facing up. You may want to check the pin-outs if you use an Arduino Micro like I did. Some of the revisions have a slightly different pin-out. I actually had to build this twice as I used a pin-out for an earlier version of the controller.
Next, I soldered the leads for the MIDI port. MIDI pin 4 goes to a 220 Ohm resistor, then to the 5 volt output (not the unregulated voltage that the battery connects to). MIDI pin 5 connects to the TX pin on the Arduino. MIDI pin 2 (the outside center pin) goes to the ground on the Arduino.
Hey! We’re half way there. To wire the switches in, we will connect to digital pins 1 and 2 on the Arduino. Wires from these pins take two directions. Solder one leg of a 330K resistor and one leg from a switch to the respective digital pin (one for each switch). On the other side of the resistor run a wire to ground. This will make sure that the sensing pin reads zero volts (ground) when the switch is open instead of a floating value. When the switch is closed the resistor keeps the current from flowing straight to ground, but pulls the Arduino digital pin up to full voltage.
That’s it for the soldering. At this point the switch box can be assembled and is ready to load our program and become a Vypyr amplifier footswitch.
Imagination Time
Before we get into the software for the foot switch, you may have noticed that this project did not connect to a lot of the pins on the Arduino. These are very capable devices. They have thirteen digital ports that can be used to sense switches or turn LEDs on and off. We only used two of these, so potentially we could have added another eleven switches to our box. They also have six analog ports, each of which could be connected to a variable pedal like a Wah or volume control. A lot more can be done by adding just a few components to the project that was built in Phase I of this blog.
This gets me to the theme of this effort, which is “Whatcha’ Wanna Du?” Using the Vypyr MIDI implementation information that has been collected by multiple Vypyr Forum users, we can make this little switch box du quite a lot. I have chosen to use the simple case of selecting presets, but this is a simplification to make it easier to understand what is going on. The program will drive an LED to indicate switch position if that is desired. To enable this, LEDs with current limiting resistors can be connected to pin 4 and pin 13.
There are two example programs at the bottom of this blog. Depending upon if the switches are momentary switches (only closed while the button is being pushed) or are on/off switches (on when you press it the first time, off when you press it the second time). With the appropriate program loaded into the Arduno IDE (Development Environment), connect the Arduino to the computer and upload the program.
Code Example for on/off switches:
For micro, on an Uno change references to Serial1 to Serial
/* VypyrPedal1 This example code is in the public domain. */ // constants won't change. They're used here to // set pin numbers: const int button1Pin = 2; // the number of the pushbutton pin const int button2Pin = 3; // the number of the pushbutton pin const int led1Pin = 4; // the number of the LED pin const int led2Pin = 13; // the number of the LED pin // Variables will change: int led1State = HIGH; // the current state of the output pin int led2State = HIGH; // the current state of the output pin int button1State; // the current reading from the input pin int button2State; // the current reading from the input pin int lastButton1State = LOW; // the previous reading from the input pin int lastButton2State = LOW; // the previous reading from the input pin // the following variables are long's because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long lastDebounceTime = 0; // the last time the output pin was toggled long debounceDelay = 50; // the debounce time; increase if the output flickers void setup() { pinMode(button1Pin, INPUT); pinMode(button2Pin, INPUT); pinMode(led1Pin, OUTPUT); pinMode(led2Pin, OUTPUT); // disable pull-up resistors on pin switches digitalWrite(button1Pin, LOW); digitalWrite(button2Pin, LOW); // read the state of the switch into a local variable: int reading1 = digitalRead(button1Pin); lastButton1State = reading1; int reading2 = digitalRead(button2Pin); lastButton2State = reading2; // set initial LED state digitalWrite(led1Pin, led1State); digitalWrite(led2Pin, led2State); Serial1.begin(31250); } void loop() { // read the state of the switch into a local variable: int reading1 = digitalRead(button1Pin); int reading2 = digitalRead(button2Pin); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading1 != lastButton1State || reading2 != lastButton2State ) { // reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: // if the button state has changed: if (reading1 != button1State) { button1State = reading1; // only toggle the LED if the new button state is HIGH if (button1State == HIGH) { led1State = HIGH; patch(1); } else { led1State = LOW; patch(2); } } if (reading2 != button2State) { button2State = reading2; // only toggle the LED if the new button state is HIGH if (button2State == HIGH) { led2State = HIGH; patch(3); // noteOn(5,1); //PLAY WORKS // noteOff(5); } else { led2State = LOW; patch(4); // noteOn(5,12); // noteOff(5); } } } // set the LED: digitalWrite(led1Pin, led1State); digitalWrite(led2Pin, led2State); // save the reading. Next time through the loop, // it'll be the lastButtonState: lastButton1State = reading1; lastButton2State = reading2; } //MIDI COMMANDS void patch(int instrument) { Serial1.write((byte)0xC0); Serial1.write((byte)instrument); } void controller(int controller, int value) { Serial1.write((byte)0xB0); Serial1.write((byte)controller); Serial1.write((byte)value); } void noteOn(int key, int vel) { Serial1.write((byte)0x90); Serial1.write((byte)key); Serial1.write((byte)vel); } void noteOff(int key) { Serial1.write((byte)0x90); Serial1.write((byte)key); Serial1.write((byte)0x00); }
Code Example for MOMENTARY switches:
For micro, on an Uno change references to Serial1 to Serial
/* /* SimpleVypyrPedal2 * Note: On most Arduino boards, there is already an LED on the board connected to pin 13, so you don't need any extra components for this example. This sketch is for a two button pedal with momentary switches. This example code is in the public domain. */ // constants won't change. They're used here to // set pin numbers: const int button1Pin = 2; // the number of the pushbutton pin const int button2Pin = 3; // the number of the pushbutton pin const int led1Pin = 4; // the number of the LED pin const int led2Pin = 13; // the number of the LED pin // Variables will change: int led1State = LOW; // the current state of the output pin int led2State = LOW; // the current state of the output pin int button1State = LOW; // the current reading from the input pin int button2State = LOW; // the current reading from the input pin int lastButton1State = LOW; // the previous reading from the input pin int lastButton2State = LOW; // the previous reading from the input pin int Button1Feature = 0; // feature turned off be default int Button2Feature = 0; // feature turned off be default // the following variables are long's because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long lastDebounceTime = 0; // the last time the output pin was toggled long debounceDelay = 50; // the debounce time; increase if the output flickers void setup() { pinMode(button1Pin, INPUT); pinMode(button2Pin, INPUT); pinMode(led1Pin, OUTPUT); pinMode(led2Pin, OUTPUT); // set initial LED state digitalWrite(led1Pin, led1State); digitalWrite(led2Pin, led2State); //disable internal pull-up resistor digitalWrite(button1Pin, LOW); digitalWrite(button2Pin, LOW); //open MIDI connection using TX pin Serial1.begin(31250); } void loop() { // read the state of the switch into a local variable: int reading1 = digitalRead(button1Pin); int reading2 = digitalRead(button2Pin); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading1 != lastButton1State || reading2 != lastButton2State ) { // reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: // if the button state has changed: if (reading1 != button1State) { button1State = reading1; // only toggle the LED if the new button state is HIGH if (button1State == HIGH) { if (Button1Feature == 0) { Button1Feature = 1; led1State = HIGH; patch(1); } else { Button1Feature = 0; led1State = LOW; patch(2); } } } if (reading2 != button2State) { button2State = reading2; // only toggle the LED if the new button state is HIGH if (button2State == HIGH) { if (Button2Feature == 0) { Button2Feature = 1; led2State = HIGH; patch(3); // noteOn(5,1); //PLAY WORKS // noteOff(5); } else { Button2Feature = 0; led2State = LOW; patch(4); // noteOn(5,12); // noteOff(5); } } } } // set the LED: digitalWrite(led1Pin, led1State); digitalWrite(led2Pin, led2State); // save the reading. Next time through the loop, // it'll be the lastButtonState: lastButton1State = reading1; lastButton2State = reading2; } //MIDI COMMANDS void patch(int instrument) { Serial1.write((byte)0xC0); Serial1.write((byte)instrument); } void controller(int controller, int value) { Serial1.write((byte)0xB0); Serial1.write((byte)controller); Serial1.write((byte)value); } void noteOn(int key, int vel) { Serial1.write((byte)0x90); Serial1.write((byte)key); Serial1.write((byte)vel); } void noteOff(int key) { Serial1.write((byte)0x90); Serial1.write((byte)key); Serial1.write((byte)0x00); }
NOTES and Suggestions:
- I used a Radio Shack 276-150 prototyping board to solder this all together. This was not a good choice. It is single sided and does not have plated through holes. Soldering on it was a miserable task. Use a better prototyping board.
- I used patch wires from my solderless breadboard as wire when soldering the project together. These wires to not hold up very well when they are moved around. Better wire would have made this go a lot better. I ended up doing a lot of debugging and rework from broken wires.