News:

SMF for DIYStompboxes.com!

Main Menu

Arduino MIDI Switcher

Started by potul, November 04, 2015, 01:21:57 PM

Previous topic - Next topic

potul

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: http://www.banggood.com/ATmega328P-Nano-V3-Controller-Board-Compatible-Arduino-p-940937.html

-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: http://www.ebay.es/itm/MODULO-RELAY-RELE-5V-DE-2-CANALES-PARA-ARDUINO-ARM-PIC-AVR-DSP-RASPBERRY-PI-/261475911035?

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.

Connections:

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:




Software

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

-Mini USB cable
-Arduino IDE. you can get it from  www.arduino.cc
-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.   http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
MIDI Library: To send/receive MIDI messages. http://playground.arduino.cc/Main/MIDILibrary


#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
MIDI_CREATE_DEFAULT_INSTANCE();

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:
// http://arduinomidilib.fortyseveneffects.com/a00022.html
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
  value=EEPROM.read(number);
  //activate relay 1 if needed
  if (getBit(value,1))
   {
     digitalWrite(LED1,HIGH);
   }
   else
   {
      digitalWrite(LED1,LOW);   
   }
  //activate relay 2 if needed
  if (getBit(value,2))
   {
     digitalWrite(LED2,HIGH);
   }
   else
   {
      digitalWrite(LED2,LOW);   
   }

}

// This function will be called when the button1 was pressed 1 time.
void click1() {
  //toggle Relay1
  byte value;
  value=digitalRead(LED1)+digitalRead(LED2)*2;
  value++;
    if (getBit(value,1))
   {
     digitalWrite(LED1,HIGH);
   }
   else
   {
      digitalWrite(LED1,LOW);   
   }
  //activate relay 2 if needed
  if (getBit(value,2))
   {
     digitalWrite(LED2,HIGH);
   }
   else
   {
      digitalWrite(LED2,LOW);   
   }
} // 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))
  {
    setBit(value,1);
  }
  if (digitalRead(LED2))
  {
    setBit(value,2);
  }
  EEPROM.write(curr_program,value);
 
} // 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() {
  //digitalWrite(LED2,LOW);
} // 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++)
    {
      //EEPROM.write(i,i);
    }
   
    //Define button handling functions
    button1.attachClick(click1);
    button1.attachDoubleClick(doubleclick1);
    button1.attachLongPressStart(longPressStart1);
    button1.attachLongPressStop(longPressStop1);
    button1.attachDuringLongPress(longPress1);
    // 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
    MIDI.setHandleNoteOff(handleNoteOff);
    // And for PC message
    MIDI.setHandleProgramChange(handleProgramChange);
    // Initiate MIDI communications, listen to all channels
    MIDI.begin(MIDI_CHANNEL_OMNI);
    //Serial.begin(9600); //Set serial to 9600, only for debugging
   
}
void loop()
{
    // Call MIDI.read the fastest you can for real-time performance.
    MIDI.read();
    // 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
    button1.tick();
}

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);
}


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!

Mat

LC_legend

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

I have the same setup as you, pod hd500 to poweramp to cab. But i´m allways wanting more from the tone (don´t we all?) I get from the pod´s amp models. A while ago I built a dr. boogie wich i really like and i´m 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. I´m 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 wouldn´t 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 i´m 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?

potul

Hi

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.

Mat

If you

andersm

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.

potul

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?

Mat

potul

I just checked your amp.. if I'm not mistaken it can use the FS2 footswitch that is completely passive, so you should be ablt to control it.

andersm

Yes, the manual specifically suggests those passive switches and there's a wiring diagram on the rear panel of the amp.
I need to dig out my old midi controller but if I remember right it has a midi through. also the fx unit I was gonna buy has a midi out, would that work too?

potul

Great,

regarding your FX unit, it depends on what the midi out does. If it just sends PC message when you press buttons in it... it might not work. If it relays all incoming messages, or send PC messages every time the unit changes patch, it will work.

what FX unit is it? Maybe I can dig into the MID specs

andersm

I haven't bought it yet, but I would love to get the Line6 M5. Mostly because it's small, affordable and yet has midi.
I had another idea but this may make things more complicated. I need the M5 mostly for modulating and time based effects and therefore put it in the fx loop of the amp head. now, since the distortions of the M5 are not en par with the rest of the effects and I like the overdrive of my Laney best anyway - after all I chose that amp for a reason - I might still need a couple of stomp boxes before the preamp (noise gate and my electro harmonix metal muff, in cases when I have to play someone else's amp).

So what I basically need for that is a way to bypass a pre-fx loop via midi. Do I make any sense?
I could use a simple A/B switch box for that, but that means tapdancing again. Would be cool if I could just build an additional A/B switch in the same enclosure with the rest of the hardware.

by the way, I double checked, the floor board has a midi through, they just call it "share" for some reason but the manual says it's a through

fwbulldog

Thanks for posting this!  It's a huge head start.  I currently use a GCX Loop Switch to control my Blackstar Ht60.  It requires three momentary switches to select clean, OD1, OD2.  In my current setup this takes up three loops from my GCX.  I'd like to get these loops back for fx, and I'm looking for a cheaper alternative to the RJM Mini Amp Gizmo ($229 + cable). 

Your layout is fantastic and very easy to follow.  At first I did not understand the need for the 6N138 Optocoupler.  I did some research, and I'd like to pass on what I learned.

There is a great page that explains MIDI signaling, even down to the HW interface.  https://learn.sparkfun.com/tutorials/midi-tutorial/all.  Some people that come here might have a high level understanding of what MIDI does, but need some more background on how the signaling works if they're going to build this circuit.

You don't want to directly (i.e. electrically) connect an external voltage driver to your Arduino GPIO.  Voltage spikes (or current sinks) could damage the chip or cause ground loops, noise, etc.  Since MIDI uses a 5V circuit to transmit data, you need to isolate the signal from the UART on the Arduino.  This is accomplished with the 61N38 Optocoupler that potpul has selected.  This chip isolates the incoming 5V MIDI signal by using a LED/phototransitor circuit.  There is no electrical connection between the MIDI input and output.  It's optically isolated. 

The following schematic (from the MIDI spec), shows the diode and optocoupler.  The diode (D1) is connected between MIDI pins 4 and 5 to form the current loop.  Note that the direction of the diode is important.  The diode is there to prevent current from flowing the wrong direction.




Midi use connector pins 4 and 5 to create a 5V loop.  At the transmitter,Pin 4 is pulled up to 5V through a weak pull-up resistor.  Pin 5 is connected to the MIDI device transmit UART.   When the MIDI device wants to send traffic it outputs a logical 1 or 0 on the UART TX pin.  The website explains it very well.





"At the output, pin 4 is pulled high through a small resistor, and pin 5 is the buffered UART transmit line. On the input, these lines are tied to the anode and cathode of the LED in the opto-isolator. Since the UART output is high when not transmitting, both pins 4 and 5 will be at the same voltage, no current flows through the LED, thus it is not illuminated. When the LED is dark, the phototransistor is off, and the UART receives the voltage through the pullup, resulting in a logic one.
When the UART starts transmitting a byte, the start bit will pull pin 5 low, and current flows through the LED, illuminating it. When the LED is on, the phototransistor turns on, swamping the pullup, pulling the UART input to ground, and signaling a zero."

You can read about the MIDI out and through circuits there as well.   MIDI was designed to be a low-cost signaling interface, and it's pretty simple to implement if you understand what the reference circuit does.  I'm fine with this project being the end of my MIDI chain, so I don't really care about out and through. 

Since I need to switch three channels I'll have to use a four channel relay (http://www.banggood.com/3Pcs-5V-4-Channel-Relay-Module-For-Arduino-PIC-ARM-DSP-AVR-MSP430-Blue-p-983480.html).  I'm a little concerned about the 5V current draw of all four relays at the same time, so I may need to also build a 5V regulator circuit for separately powering the relays (as opposed to taking the 5V output from the Adruino board).  I'll be powering the box using my Voodoo Labs Pedal Power Iso 5.  No batteries involved. 

I'll probably have to experiment with the code to see what the minimum momentary pulse time is for the Blackstar and tweak the code for three outputs instead of two. 

Very cool project!  Thanks again. 

potul

Quote from: andersm on May 25, 2016, 01:21:19 PM
So what I basically need for that is a way to bypass a pre-fx loop via midi. Do I make any sense?
I could use a simple A/B switch box for that, but that means tapdancing again. Would be cool if I could just build an additional A/B switch in the same enclosure with the rest of the hardware.
you can do it, but if you want to do it properly you will need a different type of relay board. The one I posted is a simple spdt, for bypassing you should use dpdt. Still.. you could do it with an spdt if you are not concerned about true bypass.
Quote from: andersm on May 25, 2016, 01:21:19 PM
by the way, I double checked, the floor board has a midi through, they just call it "share" for some reason but the manual says it's a through
I don't think this would work. you need to pass the same midi messages to 2 different devices. This is usually done by using the midi through to daisy chain them. I don't think the midi through of the floor will output the messages generated by itself. You might need to look into the manual to clarify.
The ideal would be if the FX unit has a midi through. If not, we can implement a midi through from the arduino. It should not be complicated.

potul

Quote from: fwbulldog on May 26, 2016, 01:14:38 PM
Since I need to switch three channels I'll have to use a four channel relay (http://www.banggood.com/3Pcs-5V-4-Channel-Relay-Module-For-Arduino-PIC-ARM-DSP-AVR-MSP430-Blue-p-983480.html).  I'm a little concerned about the 5V current draw of all four relays at the same time, so I may need to also build a 5V regulator circuit for separately powering the relays (as opposed to taking the 5V output from the Adruino board).  I'll be powering the box using my Voodoo Labs Pedal Power Iso 5.  No batteries involved. 
you might want to check with both the relays and arduino spec sheet. 4 relays will draw something like 200mA. I don't recall how much the arduino regulator can handle. But I've had some bad experience in the past with relays and regulators, so having an extra one will not hurt.
Quote from: fwbulldog on May 26, 2016, 01:14:38 PM
I'll probably have to experiment with the code to see what the minimum momentary pulse time is for the Blackstar and tweak the code for three outputs instead of two. 

Very cool project!  Thanks again.
If you need more relays you might want to change the user interface. I decided to go cheap and use a single button, which works for 2 relays (ony 4 possible combinations). For 3 relays, that would be 8 combinations... you might want to consider a different way to manage it. Maybe adding 2 more buttons, one for each relay.

andersm

Quote from: potul on May 31, 2016, 01:57:40 AM
you can do it, but if you want to do it properly you will need a different type of relay board. The one I posted is a simple spdt, for bypassing you should use dpdt. Still.. you could do it with an spdt if you are not concerned about true bypass.

Hm okay, I have no experience on whether true bypass would really make a sound difference here.
You're of course right about the midi through of the board. Isn't the midi out of the fx unit meant to daisychain units though?


potul

yes if your FX unit has a midi out it might work.

fwbulldog

Quote from: potul on May 31, 2016, 02:08:44 AM

If you need more relays you might want to change the user interface. I decided to go cheap and use a single button, which works for 2 relays (ony 4 possible combinations). For 3 relays, that would be 8 combinations... you might want to consider a different way to manage it. Maybe adding 2 more buttons, one for each relay.

I've been thinking about it, and I don't think I need any buttons.  For my application, I need three program changes that momentarily grounds a relay.  Only one will ever be active at a time.  I don't need eight combinations, just three.   And since only one relay will ever be active at once, I think I can get away with just using the 5V output from the Arduino, same as you did. 

Some slight code changes from your application, shouldn't be too hard.


potul

up to you.

But if you don't have any button you will need to "hardcode" your presets. I would go for one button, and you cycle through your 3 channels when pushing it.

Remember to modify the code to make it momentary.


andersm

Okay, so while I'm waiting for the rest of my hardware to arrive, I came up with a way to organise the fx loops.
Since I found a relay board with 8 channels and can therefore use 2 switchable fx loops I brainstormed a bit.
The easiest way would have been to just hook up the 2 loops in line and use them for pre fx like noise gate and distortion (handy, as I always wanted an "automatic" noise gate that disappears whenever I play solo or clean sounds...
But then I thought about using one of the loops for an additional post fx unit that doesn't otherwise respond to midi, which means I would have to keep the signal paths discrete. Luckily, one way of achieving this includes a true bypass option. Which is something I wanted to have anyhow...

Basically what I'm doing is this: I put a manual (how is a FOOT switch ever manual?!) foot switch before each of the relays, which acts as a true bypass. the one after the first loop is a 4PDT that does the signal routing for me so pre and post signals don't mix up.

Now there are different scenarios in which I can use it.
Loop A will only work for PRE fx. I will probably put my noise gate here. I will then not true-bypass it and only use the relay-bypass for clean and solo sounds.

Loop B can now be used either for another PRE fx, like a Wah or be true-bypassed, as I don't like using the Wah in my metal band anyway ;)
If I true-bypass it though, and put a POST fx unit in Loop B, the unit will be active for the post fx loop that so far cointains only my Line6. So basically, if you put any fx unit in Loop B, the true-bypass button will actually let you route either the pre signal or the post signal through that Loop. I admit, it makes everything a tad complicated but it could lead to an intresting use of effects.

The downsides is: if you're not going to use Loop B at all, the only way to maintain true bypass for both pre and post signal would be to put a patch cable in the loop (or leave the post fx unit out of this box alltogether). I can live with that though, because for my use, it's not a question of needing to change that setup during a set, but rather whether I want to use them in principleor not; so I can prepare the routing before a set.

So, here's my diagram, a bit on the wonky side, but hey, I'm a dabbler in that. If you find any flaws, please do point them out.
I haven't wired in any LEDs here, yet, but they will be vital. Oh and I haven't bothered drawing in the obvious grounds connections.
I added a version with colour coded signal paths, too. If it doesn't work, by amazing coincidnce you can also use it as a tube map in London. Obviously for guitarists, the tube sounds better than the metro  :icon_mrgreen:

https://dl.dropboxusercontent.com/u/23918855/FX%20loop.jpg
https://dl.dropboxusercontent.com/u/23918855/FX%20loop%20plus%20colour%20coded%20signal%20paths.jpg


potul

I must admit you lost me.   ;D

I will review your diagrams tonight and will give you my feedback.

Mat

potul

#18
sorry but I don't undestand  the concept.

where would you connect POST FX IN and POSTFX OUT?
OUTPUT goes to the amp input, or to the power amp input (usually the return of the amp)?
loop B... is this going to be used before or after the amp pre-amp?
What is the purpose of the 4PDT?

Sorry to ask, but I want to understand what you try to achieve.

In addition,... you mentioned you have 8 relays.... but you are only using 2 in the schem. (you need 4 for the amp, right?, so you have 2 spare ones)


potul

Ok,... I think I got it... your coloured one helped... Please correct me if I'm wrong.

-You want 2 controllable independend loops via MIDI (A and B). You will put some FX there.
-You want to choose if LOOP B goes before the AMP, or in the FX loop of the amp.
-You added an extra swithc for truebypass of LOOPA.
-OUTPUT will go to the AMP INPUT (where you usually place your guitar)
-POST FX OUT goes to AMP RETURN
-POST FX IN goes to AMP SEND

If this is it, I think you overcomplicated... :). Or maybe not... and the issue is that I don't picture it.

If I'm not wrong, you can do the same with a 3PDT (or a 4PDT if you want LED)

Question: Do you need to switch on the fly the LOOP B from PRE to POST? Or is this something you could simply wire differently upfront before the show?