I’ll call this pedal Pico MIDI because I’m using Raspberry Pi Pico for this. And it’s also of diminutive size ?. I recently posted a teaser, took me maybe a day or two to get that up and running from scratch without really knowing anything about MIDI. While I’d love to brag about this achievement, it turns out that this is a very simple affair.
So what’s the plan? The idea is to create a very small pedal that can send MIDI control commands and thus control various pedals that support MIDI. I have Boss RC500 looper and Digitech Whammy pedals that I could control. I got this idea while playing with the looper and seeing that it has a ton of control options.
To make a minimal working pedal, I’ll have a stomp switch that can toggle various options on my two pedals that I want to control. I also have a Digitech FS3X, a three button pedal which I cannot use with anything … doh … sometimes reading documentation pays off. Turns out that neither Whammy nor RC500 support FS3X, but I can make an extra input for my Pico MIDI and support it myself! In your face Digitech and Boss! Ha!
While I’m at that, maybe I could also support expression pedal???? When you DIY, the sky is the limit ?.
As usual – you can skip directly to the video and come back later for more details if you wish so.
Here’s the ToC:
- MIDI – Hardware Interface
- Interfacing with MIDI Devices
- Notes on Hardware Implementation
- How to Control our Pedals?
But let’s start simple. For this post I’ll cover some basic stuff. What the hell is MIDI, and how can I use Raspberry Pi Pico to send commands to my pedals. While I did say it’s easy, even for this intro post we’ll encounter quite a few new things.
By the end of this post I hope we can interface our Pico with the two pedals I have and send them MIDI commands and make them actually do something. No buttons, nothing fancy, just making sure we can pull this off – if I can’t send commands to my pedals no point in adding anything else.
MIDI – Hardware Interface
I’m not going to go into too many details, but I’ll point you to very useful resources. Sparkfun has a great set of articles on MIDI as well as Adafruit. MIDI protocol has been out there since 80’s and it’s de-facto standard for controlling anything to do with music – from your DAW to the lighting effects.
In essence we can use UART on our Pico to send MIDI commands. So from software perspective, we can send MIDI commands with 3 lines of MicroPython code. Turns out that the hardware is not much more complex. MIDI standard requires us to use an optocoupler, but because we’re only sending messages and optocoupler is part of the receiver we don’t even need that. All we need are a couple of resistors to limit LED current of the optocoupler that RC500 and Whammy already have built in.
If we wanted to receive MIDI messages, then we’d need an optocoupler as well. We’ll cross that bridge when we come to it, so for now – all we need is a Raspberry Pi Pico and a couple of suitable resistors.
That sounds too easy. Well, turns out the more complex part of this job is to deal with cables!
Interfacing with MIDI Devices
Well, Boss pedal has a TRS jack for MIDI, and Whammy has a 5-pin DIN jack. How about that? Turns out that 5-pin DIN jack is standard, and MIDI uses only 3 pins (well, that’s according to specification and if we don’t venture into power over MIDI territory). Clever people realized that TRS jack has 3 pins too and it’s way way smaller and thus more convenient to add to pedals.
Now, even though the TRS jack is standard now, because it did not use to be, there are 3 different implementations of it. In the schematic above I showed how to wire things up for Boss implementation, and that’s the same wiring scheme as in official MIDI doc. At some stage I’ll cover other options.
In order to support both Whammy and RC-500 I have to add DIN-5 jack as well (of course DIN would have 3 different options for 5 pin jack – we need 180o one – careful when you’re ordering cables and jacks):
Notes on Hardware Implementation
GPIO16 is UART output/tx pin on Pico. Here’s the pinout card for Pico. That part is simple. One possibly confusing thing is that on lots of MIDI interface diagrams pin 4 is connected to +5V. That was in the original MIDI specification back in the day. The updated version of the MIDI standard (from 2014) covers 3.3V levels.
The reason I went for 3.3V is that Pico uses 3.3V for it’s logical levels. If you recall there’s a diode of the optocoupler on the other side connected to pins 4 and 5 of the DIN connector, and as long as we can turn it on/off with sufficient current we’ll be good.
I actually used 10ohm and 47ohm resistors (I’m pretty sure I have 33ohm resistors somewhere … just could not find them). Even 220ohm resistors should work most of the time, I tried that out with RC-500 and it worked. Not having 10 or 33ohm resistors should not stop you from trying this out. It’s good idea to stick to the specification but for breadboarding this we should be fine with anything between 10 and 220ohms.
WARNING – even though you could use VBus to get 5V from Pico when it is connected to USB port. Do not use it for MIDI interfacing. Again, remember that pins 4 and 5 are connected to LED side of the optocoupler. In theory, you could end up with voltage that is over 3.3V on the GPIO16 pin and that might damage your Pico.
Oh yes, and at some stage we’ll want to use our Pico disconnected from USB port … so we’ll need to power it some other way … we’ll cross that bridge later.
Another note, I have hard wired DIN and TRS connectors. Not the greatest idea, but for today, it will suffice, and I’ll be connecting just one pedal at a time. For now let’s leave it at that, suffice to say that Pico has 2 UART ports ?.
Alright, I used Visual Studio Code when I played last time with Pico. I still want to use MicroPython for this, but I broke my Visual Studio Code and in the meantime the plugin I used became obsolete … well lots of things can happen in a year … it’s like a millennia in computer years.
I ended up using Thonny. I’ll tell you now, that program looks like time has stopped for it a while ago, but it works like a charm ?. Working software beats broken software 100 times out of 100.
I’ll use interactive console to setup Pico UART and send messages. The code is actually super simple:
from machine import UART, Pin
midi = UART(0, baudrate=31250, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17), invert=0)
Yep, that’s it for the setup. MIDI uses a clock rate of 31,250 bits per second hence the baud rate above, actually, all values are written down in MIDI spec. The first parameter 0 indicates which UART to use (there are 2) and Pins 16 and 17 are normally used for UART 0 on Pico.
With the above setup, we just need to write something out to that midi port now and voila, we are controlling our pedals. But what do we write out?
How to Control Our Pedals?
It’s simple to configure UART to send our commands, but now we need to figure out what commands to send. For that we need to understand what MIDI commands our pedals support.
Turns out that RC-500 supports Control Change commands but also Program Change commands (if you read manuals very carefully). And Whammy supports Program Change and continuous control commands (I think this is Control Change command, we’ll see if I’m right in a jiffy). RC-500 can also transmit stuff and supports MIDI start and stop messages.
I actually spent the most time figuring this out. All of the above took me no time, but this one required a bit of digging. And when you’re trying things out for the first time it’s hard to know if your hardware or your software is at fault.
Control Change Command
In the end it’s simple, for Control Change commands we’re sending 3 bytes: 1011nnnn 0ccccccc 0vvvvvvv. Well, why don’t you say so ? (it’s easy after having read reams of pages).
1011 indicates it’s a Control Change command, nnnn is the MIDI channel number (value is from 0-15 indicating channels 1-16). So 10110000 or 0xB0 is Control Change command for MIDI channel 1.
The second byte indicates controller number and values from 0-119 are supported (120-127 are some special values). RC-500 does not support all of those values, just CC#1-#31 and CC#64-#95. RC-500 allows us to assign up to 8 CC commands to various actions.
The third byte is value, from 0 to 127, for toggling on and off commands, 0 is off, 127 is on (turns out that for RC-500 we need to send off and then on values for it to detect that there was a toggle). For continuous mode, anything between 0 and 127 works – this might be what we need for controlling Whammy’s pedal position.
For RC-500 is not as simple though, when I say toggling. There is a configuration where you can indicate whether to use Toggle or Momentary option. Looks like it works sometimes and for some target actions it doesn’t. And some target actions have options – what it means when sending Minimum value (0) or Maximum value (127). It’s fun if you like figuring that stuff out … I would have preferred it if there was some proper documentation ?.
Program Change Command
Program change command consists of 2 bytes: 1100nnnn 0ppppppp.
Similarly to the control change, the first byte, first 4 bits: 1100 or 0xC indicate Program Change command, nnnn is MIDI channel, so 0xC5 is Program Change for MIDI channel 6 for example.
The 2nd byte indicates new program number, supporting values from 0-127. RC-500 supports messages values from 1-99 indicating memory locations 1-99. In order to send PC#1 command we need to send value of 0 for the 2nd byte over UART. So we’re sending 2nd byte with values 0-98 I believe. Don’t you love this 0-based vs 1-based index mind bending?
So when we talk about CC#1 for example, controller number 1 is sent to our MIDI device. If we talk about PC#1, program number 0 is sent to our MIDI device … this is messed up.
For Whammy, program numbers from 1-84 (or values from 0-83) should be supported. For example, if we send 0xC03E, that will send Program Change command over channel 1 with program number 63, which should be harmony octave-up/down in chords mode (phew, if you have trouble following this have some sympathy for me reading this in the documentation).
Now, sending Control Change command 11 with value 0 indicates toe up position (octave down in this case) and value 127 indicates toe up position. So, sending 0xC0 3E and then 0xB0 0B 00 should turn on harmonizer for octave down in chords mode. Did I get this right? Only one way to find out!
I only glanced over MIDI channel so far. For example Whammy pedal can be configured to listen to Omni channel (all channels, default option) or any of the channels 1-16.
For RC-500, would you believe it, you can also configure it to listen on Omni channel (default) or you can configure any of the channels 1-16.
Why would you care about this? Some pedals send MIDI commands through, this way you could chain MIDI devices and send commands to different devices over different channel. Well, this time around, we’ll send 0 value for channel and use omni channel on both RC-500 and Whammy.
Putting it all Together
As we’ve seen the hardware is simple. Software is going to be simple after we figure out all the commands we want to support. If you are going to use this MIDI pedal with RC-500 or Whammy just keep on following this series of posts.
In order to configure RC-500 you would want to have a look into “Boss RC-500 Parameter Guide”. Google it since pdf urls might change. It goes into minute detail of configuring MIDI. Or watch my video and I’ll cover at least part of this configuration.
For Whammy, look up Whammy user manual. I’ll cover some of it in the video.
If you want to use this as a basis to control a different pedal or a device, you would want to check few things before proceeding: what is the connector that you need – if it’s DIN 5-pin you’re fine, if it’s TRS – you need to check what type of wiring it uses (if it’s not Boss type, the above schematic won’t work, but I’ll cover other wiring options later).
After you figured out the wiring, you need to look up the manual of your device that you want to control. If the commands are Control Change or Program Change – I have them covered here. If not, you might need to review some of the links I posted above to get details what to do.
Commands Used in The Demo
In order to send a command over UART port we need to use write method. Here’s an example how to send CC#1 command with value 127:
The above lines sends 3 bytes to our MIDI device:
- B0 hex (that’s 10110000 binary) is Control Change with Channel 1
- 01 indicates controller number
- and 7F is the value 127.
Here are the commands I used in the video below:
cc_1_on = b'\xb0\x01\x7f'
cc_1_off = b'\xb0\x01\x00'
cc_4_on = b'\xb0\x04\x7f'
cc_4_off = b'\xb0\x04\x00'
pc_1 = b'\xc0\x00'
pc_22 = b'\xc0\x15'
pc_16 = b'\xc0\x0f'
pc_37 = b'\xc0\x24'
cc_toe_up = b'\xb0\x0b\x00'
cc_toe_down = b'\xb0\x0b\x7f'
cc_toe_15 = b'\xb0\x0b\x0f'
cc_toe_67 = b'\xb0\x0b\x43'
Commands pc_* are for Program Change commands. For RC-500, in the video, I used pc_1 and pc_22 to select memory locations 1 and 22. Watch the video to see how I assigned CC#1 and CC#4 to various functions on the looper.
For Whammy I used pc_1 and pc_22 to activate or bypass Whammy – 2 octaves up effect. And pc_16 and pc_37 to activate or bypass Harmony up 4th and up 5th effect.
For Whammy, CC#11 command controls position of the expression pedal. cc_toe_up and cc_toe_down are toe up and toe down position – doh! cc_toe_15 and cc_toe_67 are just for continuous control of the expression pedal position and I used that with 2 octaves up effect to get different pitch shift. (I did not calculate values correctly and in the video I named them cc_toe_16 and cc_toe_68 … oops).
Here’s a quick demo of what I covered here:
I hope you liked it, stay tuned for more.