Hi everyone, I'm new here so I hope I'm getting this done right - please do let me know if this is in the wrong place and so on.
A bit of background, I'm trying to use Arduino to relay MIDI program change messages from a MIDI controller to some MIDI-controllable guitar effect pedals. Both sides are USB slave devices. To be exact, I am using:
- KMI Softstep: MIDI controller, sends MIDI PC and CC as a USB slave device
- Zoom MS60B: guitar effect pedal, can be controlled by MIDI PC as a USB slave device
- Source Audio HUB: guitar effect pedal, can be controlled by MIDI PC as a USB slave device and also forwards MIDI CC messages
What I want to do is this: when I press a button on my MIDI controller, it sends a MIDI PC by USB to the USB hub to the Arduino. The Arduino reads this messages, and sends it back out to everything connected to the USB hub. This means that the controller will also receive this message, but that doesn't matter. It seems to be the easiest way to get all the pedals to receive the same PC at once.
I have done this with my laptop and MidiOX, so in theory it should work. So I ordered an Arduino and a USB Host Shield and set off to give it a try. I'm using the UNO R3 and a Keyes USB Host Shield, which is an OEM but apparently has the same functions as the Arduino USB Host Shield. However, I seem to be hitting a rather steep learning curve here. Some googling and looking at other threads around here gives me some hints, but I can't seem to find exactly what I need, or at least I can't find enough information to help me understand what I need. I'm new to this, so I'm not sure if I'm searching for the correct keywords.
First question:
This is probably the most important thing I want to know - how do I monitor what my Arduino unit is doing? The only suggestion I've seen is to use Serial Monitor, but when I run that with my Arduino plugged into my laptop I don't see anything coming through the serial monitor window on my laptop. I don't think it's a connection problem since I can upload code, and my MIDI devices are able to run off USB power from the USB Host Shield. However, I don't know if I'm using serial monitor wrongly, or whether the MIDI messages are not coming in through the correct pin, or what. I'd like to be able to see if the MIDI messages are coming in.
Second question:
Does this outline seem feasible?
- Have a loop which continuously reads MIDI input from the USB host shield. I believe MIDI PC is two bytes long, does this mean I have to set two variables to read it? I'm guessing something like I check if the first byte is for PC, and if so, it reads the second byte and saves it as the program change number.
- Immediately send this same program change number out by the USB host shield.
I believe this should give me the result I need.
Third question:
What methods of reading and writing MIDI should I be looking at? There seems to be a few various ways from what I've seen so far. I'm getting a bit confused.
One thing first, since I'm using a USB Host Shield, I should NOT be using serial read or serial write right?
Other than that... for reading MIDI, I've seen the following options:
-
The Arduino MIDI library (Release Arduino MIDI Library v4.2 · FortySevenEffects/arduino_midi_library · GitHub) seems to have direct commands to read and write MIDI, but the examples are all for notes rather than PC messages, and I'm not sure how to find out what exactly these commands do.
-
MIDI Shield this one seems to be reading the midi byte directly, but can this be done with USB shield instead of MIDI shield?
-
USB-MIDI to Serial MIDI withUsb Host Shield - Success... But... - Audio - Arduino Forum
This part here looks like what I need, but I don't understand it!
void MIDI_poll()
{
byte outBuf[ 3 ];
uint8_t size;
if( (size=Midi1.RcvData(outBuf)) > 0 ){
//MIDI Output
Serial.write(outBuf, size);
}
if( (size=Midi2.RcvData(outBuf)) > 0 ){
//MIDI Output
Serial.write(outBuf, size);
}
}
Does outBuf[3] here indicate that the message is expected to have 3 bytes? So is this creating a variable that is 3 bytes long, saving incoming USB midi data to outBuf, then using serial.write to send out this data?
I would like to use something like this, but replace the Serial.write with some kind of USB output, for example, I was looking at the code from Lawrence Doss, the method used to send MIDI via a USB host shield is
byte Message[2]; // Construct the midi message (2 bytes)
Message[0]=0xC0; // 0xC0 is for Program Change
Message[1]=number; // Number is the program/patch
Midi.SendData(Message); // Send the message
In that case, could I just replace the contents of Midi.SendData() with outbuf instead of Message?
I would try that, but the problem is that when I try to compile this code, it tells me that "MIDI does not name a type". I'm not sure why. On the MIDI library page, it warns that it removes MIDI as an object, but I'm not sure what exactly this means. I'm confused because with the MIDI library, the text of "MIDI" turns orange like "byte" or "int", so I'd have thought it was recognized as a type...
Yeah I think that's all I need to ask for now. This is my first time messing with Arduino or C, I've done some basics of other languages so it's not too bad, but whenever I look around discussions I get lost in the jargon. Also, I haven't seen anyone try to receive and send MIDI via USB both ways, it's always either a converter, or using switches to send MIDI via either USB or 5-pin.
Thanks in advance for any help!