DIY Stompboxes > Digital & DSP

Arduino MIDI Switcher

(1/17) > >>

Hi Everyone,

Long time no post in the forum, but recently I finished a little project that I think can be interesting for someone, so I've decided to post it here.
It's basically a MIDI switcher for an amp. So, a device that can receive MIDI messages (ie, from your MIDI foot controller) and control your amp channel, reverb or other characteristics that can be changed via the normal footswitch.

It's really something I don't need now, because I only use my amp (Peavey Bandit) as a power amp and I feed it with my POD, but one friend was in need of one and I decided to give it a try.
In addition, I just had in my drawer a recently purchased Aruino nano asking for a project...

The device

Device features:

-DC Jack compatible with BOSS PS
-MIDI IN. This is where we will receive the messages. I have a placeholder for MIDI OUT as well, but I didn't implemente it yet (my thought is to do a MIDI through, just relaying what comes in)
-Stereo jack.  In my case, the Bandit uses a stereo jack to control 2 things, amp channel and booter. You will need to adapt this to your amp needs.
-Push button. Used to configure presets and save them.

How does it work?:

The Arduino stores in Non Volatile Memory all the presets, one for each MIDI Program.
In each preset, you can configure what relay is on/off of the two. These will control your amp.
When a Program Change MIDI message is received, it activates/deactivates the appropriate relays based on the presets stored.
In order to change a preset, first you need to send the PC MIDI message, then push the button multiple times until you reach your desired setup. Every time you push, the device cycles through all combinations. When you are happy with it, you need to push for a long period (more than 1 second), and it will be stored and ready for next time you send the same PC MIDI message.

Tecnical details:

The MIDI switcher has 2 main parts:

-Arduino nano: All the Arduion power in a small package.

I bought it here, really cheap:

-Relay module: It has 2 relays. We can connect them as Normally Closed or Normally Open, depending on your needs.

I bought this one from ebay, but you can get similar ones from multiple places:

In order to put the small amount of external components needed for the prouject, I used a perfboard PCB I had laying aroung.
Here you have the design:

As you can see... small part count. Only 3 resistors and one diode, and one optocoupler. BTW, the diode is the one in vertical, with the cathode in pin 2 of the opto.

SW1: Momentary Push button, normally open. If you have a differnt type of button, you will need to adapt the software. The pins is configured with and internal pullup, so no extra resistor is required.
SW GND: This one goes to the other pin of the pushbutton.
RELAY1 & RELAY2: these will go to the relay module In1 and In2.
FOOT1 & FOOT&: For future use. Explained later.
MIDI IN 4 & 5: These go to the MIDI IN jack.
MIDI OUT 2,4,5: You can skip these, only for future use.
9v(BAT): Power in from DC jack. It can be up to 12v
GND(BAT): Ground from DC jack.
RELAY PWR: Relay power (5v). It gets connected to Vin
RELAY GND: Relay module ground.

You will need to adapt the way you connect the relay to the amp, as this depends on the amp. Look for the footswitch schematic, and try to replicate it with the relays.
In my case (Peavey Bandit) it goes like this:

Sleeve: Common, it goes to the central pin of each relay.
Ring: To one of the outer pins of Relay 1.
Tip: To one of the outer pins of Relay 2.

Here you have it in a sweet box.... whenever I have time I will move it to a better enclosure. But this one works great :)

Guts shot:


And, here you have the code. You will need:

-Mini USB cable
-Arduino IDE. you can get it from
-Depending on the arduino you buy, you might need an extyra driver. Check with the vendor.
-Extra libraries you will need to install:
Onebutton : To control events based on button pushes.
MIDI Library: To send/receive MIDI messages.

--- Code: ---#include <OneButton.h>
#include <EEPROM.h>
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
#define LED1 11 //set pin for Relay1
#define LED2 10 //set pin for Relay2
#define SW1 12  //set pin for button

byte curr_program;  //current PC value

// Setup a new OneButton on pin 11. 
OneButton button1(SW1, true);

// -----------------------------------------------------------------------------
// This function will be automatically called when a NoteOn is received.
// It must be a void-returning function with the correct parameters,
// see documentation here:
void handleNoteOn(byte channel, byte pitch, byte velocity)
    // Do whatever you want when a note is pressed.
    // Try to keep your callbacks short (no delays ect)
    // otherwise it would slow down the loop() and have a bad impact
    // on real-time performance.

void handleNoteOff(byte channel, byte pitch, byte velocity)
    // Do something when the note is released.
    // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.

void handleProgramChange(byte channel, byte number)
  //do something when receiving PC messages
  byte value;
  curr_program=number; //stores the PC number for later
  //read preset value from EEPROM;
  //activate relay 1 if needed
  if (getBit(value,1))
  //activate relay 2 if needed
  if (getBit(value,2))


// This function will be called when the button1 was pressed 1 time.
void click1() {
  //toggle Relay1
  byte value;
    if (getBit(value,1))
  //activate relay 2 if needed
  if (getBit(value,2))
} // click1

// This function will be called when the button1 was pressed 2 times in a short timeframe.
void doubleclick1() {
} // doubleclick1

// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  //save preset
  byte value=0;
  if (digitalRead(LED1))
  if (digitalRead(LED2))
} // longPressStart1

// This function will be called often, while the button1 is pressed for a long time.
void longPress1() {
  //Serial.println("Button 1 longPress...");
} // longPress1

// This function will be called once, when the button1 is released after beeing pressed for a long time.
void longPressStop1() {
} // longPressStop1

// -----------------------------------------------------------------------------
void setup()
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(SW1, INPUT_PULLUP);
    //write inital presets, only for debugging.
    for (int i=0;i<128;i++)
    //Define button handling functions
    // Connect the handleNoteOn function to the library,
    // so it is called upon reception of a NoteOn.
    MIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function
    // Do the same for NoteOffs
    // And for PC message
    // Initiate MIDI communications, listen to all channels
    //Serial.begin(9600); //Set serial to 9600, only for debugging
void loop()
    // Call the fastest you can for real-time performance.;
    // There is no need to check if there are messages incoming
    // if they are bound to a Callback function.
    // The attached method will be called automatically
    // when the corresponding message has been received.

    // Call button tick to check button status

byte setBit(byte &store, byte bitn) { //bit 1 is right-most
      store |= (1 << (bitn - 1)); //set bit 5 to '1'.

byte clearBit(byte &store, byte bitn) {
      store &= !(1 << (bitn - 1));
bool getBit(byte store, byte bitn) {
      byte b = (1 << (bitn - 1));
      return (store & b);

--- End code ---

Pending topics:

There are some improvements pending. When I have the time I will implement them:

1- Take the LEDs outside of the box. When I have the definitive box, I will simply remove the red LED from the module, and plug in 2 new LEDs that will be visible from the outside.
2- MIDI through: The ideas is to conncet the MIDI OUT and modify the software to simply output everything that comes from MIDI IN. This way you can daisy chain it with another MIDI device you need to control
3- Footswitch IN: I have left 2 FOOT1 and FOOT2 connections reserved. The ideas is to connect the current amp footswitch. With this and a routine to detect rising/falling edges, I plan to be able to  still use the footwitch at the same time as the MIDI Switch.
4- Find a catchy name for it. :)

I hope this will be of interest for someone. If you plan to build one and need help, don't hesitate to contact me.

Have a nice DIY day!


Wow! Congratulations on the project and detailed write-up!  Im looking for something like this but with a little twist.

I have the same setup as you, pod hd500 to poweramp to cab. But im allways wanting more from the tone (dont we all?) I get from the pods amp models. A while ago I built a dr. boogie wich i really like and im having great fun plugging it in the loop of the hd500. I also have a Harley Benton (or Joyo) american sound wich i really like with the same setup (these are based on tech21 charater series). Both of them sound and feel analog and IMHO sound more pleasant to the hear at any given volume. Im also planning to build two more pedals to work as preamps (azabache and humble from ROG)

This got me thinking: what if i could send a ProgramChange from the hd500 to an arduino module that would store presets and change these pedals On and Off? They wouldnt even have to be in the form of pedals. They could be in a single enclosure and work as channels on a head.

Your project looks perfect for this, but im wondering if it could have at least two more channels... at least :icon_twisted:
Also, could it store presets? When we change presets on the hd500 it sends PC message over midi (up to 64, i think). If the arduino could match the same preset would be GRWEAT.

what do you think? is it possible?


In fact, the project  as it is with some modifications can be adapted to your needs esasily.

-Presets: This functionality is already there. The on/of combinations (for channel/reverb, etc...) are stored in the arduino. The POD only sends PC messages.

-Control loops intead of amp channel: In order to do this, you only would need to change the type of relays. My project is using SPDT relays, while you would need DPDT. In the arduino world these are usually called "signal relays"

-More channels: If you need more than 2 channels, some things need to be done:

1-Adapt the software to deal with more outputs. A change in the logic to store presets is required as well.
2-You will probably need another type of "programming" interface... now with only one button works well for 2 channels (only 4 combinations), but if you double this, you go to 16 combinations. I would probably have one button per channel.

BTW, the project you described is also one I've had in my head for a long time.... If you want to go on with it let me know and I can try to help you as much as possible. I can do the programming for you, as I'm familiar with the software.


If you

Brilliant, I have been looking for this for ages!
Since I'm a bloody noob in dyi midi things, please forgive me if I ask silly questions.
Basically, I play a Laney Ironheart head, which has a 4 switch stompbox via midi cable (although the amp has no actual midi), but alternatively can be toggled by 2 foot switches with 2 buttons each (one is lead vs clean and clean vs crunch, the other toggles reverb and boost, through a stereo 1/4" jack). I only really need to toggle clean vs lead, given the music I play.
So I do get this right? with this and my trusty old rfx midi buddyI could simultaneously switch patches on my multi fx and toggle amp channels, right?
I may need some guidance but this is precisely what I was looking for.

Yes, that's the idea. Being able to change your amp channel through midi.

A couple of things to consider:

-If you want to control your FX and the midi switcher at the same time you need to send the same program change to both devices. Does your FX unit have a "MIDI through"?

-You need to check that your amp is not using some sort of digital control. Is the jack footswitch simply a couple of  switches and LED? or is there some electronics in?



[0] Message Index

[#] Next page

Go to full version