How do you test the MIDI output? 1st Timer!

Hi all.

First timer here (both on forum and Arduino projects)

I using an Arduino Nano to try to build a MIDI footswitch for my ancient Electrix Repeater hardware looper. I just want to be able to play stop and shift loop numbers with my feet, so just starting with a simple 4 button to begin with. As far as i am aware - all i need to do is to program the Arduino to send MIDICC messages of a certain value/velocity and MIDI channel.

I've built lots of breadboard/stripboard/pcb stuff before, so am happy that i've built the breadboard for this correctly. To test it, i plugged the MIDI out of the project to the midi in of the repeater but there is no function from the project.

I then tried to see if it was outputting MIDI at all using a program called MIDI-OX and a usb to midi lead, plugging either/or the MIDI out and IN into my laptop, but there is no output.

I have added the correct drivers for my Nano, and am using a MIDI library for the sketch aswell.

I am using this code i found on a youtube video for a Line 6 M5, but was told that i could change the Midi.sendProgramchange to Midi.sendcontrolchange. According to the attached MIDI spec table, i think that is what i need to do.

Could anyone suggest what to look for in the code or connections?

Line6_M5_program_change_version1.ino (987 Bytes)

I'm sorry but that Fritzing wiring-diagram is really impenetrable - its much much easier to
read a circuit schematic diagram done in standard form using standard symbols.

Your code should have been in code tags like this:

#include <MIDI.h>

const int buttonOne = 2; 
const int buttonTwo = 3;
const int buttonThree = 4;
const int buttonFour = 5;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  Serial.begin(31250);
pinMode(buttonOne,INPUT);
pinMode(buttonTwo, INPUT);
pinMode(buttonThree,INPUT);
pinMode(buttonFour, INPUT);

}


void loop() {
  
if(digitalRead(buttonOne) == HIGH) {
  delay(10);  
   if(digitalRead(buttonOne) == HIGH) {
     MIDI.sendProgramChange(0, 1);
     delay(250);
   }
}

if(digitalRead(buttonTwo) == HIGH) {
  delay(10); 
   if(digitalRead(buttonTwo) == HIGH) {
     MIDI.sendProgramChange(1, 1);
     delay(250);
   }
}

if(digitalRead(buttonThree) == HIGH) {
  delay(10); 
  if(digitalRead(buttonThree) == HIGH) {
    MIDI.sendProgramChange(2, 1);
    delay(250);
  }
}

if(digitalRead(buttonFour) == HIGH) {
  delay(10); 
   if(digitalRead(buttonFour) == HIGH) {
     MIDI.sendProgramChange(3, 1);
     delay(250);
   }
}
}

MarkT:
I'm sorry but that Fritzing wiring-diagram is really impenetrable - its much much easier to
read a circuit schematic diagram done in standard form using standard symbol

Oh I agree - didnt realise Fritzing was a thing! Ok..I will draw out a diagram.

I'm not seeing any difference between your code and mine - what are code tags?

UPDATE

The Tx LED is blinking when i push down any of my switches...does that mean its working to an extent?

dpiddy81:
Oh I agree - didnt realise Fritzing was a thing! Ok..I will draw out a diagram.

I'm not seeing any difference between your code and mine - what are code tags?

I posted your code in code tags so people could see it - have you read the "how to post" thread(s) at all?

UPDATE

The Tx LED is blinking when i push down any of my switches...does that mean its working to an extent?

Post a clear circuit diagram if you want people to understand your circuit and figure things out - we can't see
if you've implemented the standard MIDI circuit easily.

Normally you'd test a MIDI interface on a MIDI device, as its a non-standard baudrate for anything else.

MIDI-OX is what I normally use for a quick test so that's o.k. Your picture is almost impossible to read but I can't see the normal resistors in a MIDI OUT circuit.

Have you tried any of the examples from MIDI.h to check if your connections are o.k.?

Your code seems to be missing a MIDI.begin().

Steve

MarkT:

#include <MIDI.h>

const int buttonOne = 2;
const int buttonTwo = 3;
const int buttonThree = 4;
const int buttonFour = 5;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
 Serial.begin(31250);
pinMode(buttonOne,INPUT);
pinMode(buttonTwo, INPUT);
pinMode(buttonThree,INPUT);
pinMode(buttonFour, INPUT);

}

void loop() {
 
if(digitalRead(buttonOne) == HIGH) {
 delay(10);  
  if(digitalRead(buttonOne) == HIGH) {
    MIDI.sendProgramChange(0, 1);
    delay(250);
  }
}

if(digitalRead(buttonTwo) == HIGH) {
 delay(10);
  if(digitalRead(buttonTwo) == HIGH) {
    MIDI.sendProgramChange(1, 1);
    delay(250);
  }
}

if(digitalRead(buttonThree) == HIGH) {
 delay(10);
 if(digitalRead(buttonThree) == HIGH) {
   MIDI.sendProgramChange(2, 1);
   delay(250);
 }
}

if(digitalRead(buttonFour) == HIGH) {
 delay(10);
  if(digitalRead(buttonFour) == HIGH) {
    MIDI.sendProgramChange(3, 1);
    delay(250);
  }
}
}

http://https://photos.google.com/search/tra/photo/AF1QipOTzbV2--3QLX7TUNQ3AlKgEmsi51RkNgfiEjQ

Here is a link to a hand drawn schematic - i'm dyslexic, so this took me ages to draw...please be kind and ask if any of it is unclear. (i couldn't figure out how to embed the picture)

i'm dyslexic, so this took me ages to draw..

I am dyslexic too, but I am not sure why that should hinder you drawing diagrams.

couldn't figure out how to embed the picture

You figured it out in the first post?

The link to your diagram does not work.

Sorry about that...

Looks o.k. provided you have the correct pins on the Din socket. Have you put the MIDI.begin() in your code yet?

Steve

slipstick:
Looks o.k. provided you have the correct pins on the Din socket. Have you put the MIDI.begin() in your code yet?

Yes, but it results in an error. Where is it supposed to go? I've not seen it in any other example of MIDI controller code

I'm interested in that. Can you link to the examples of MIDI controller code have you seen that use MIDI.h but don't have a begin() ? Maybe I haven't really needed it in my MIDI programs.

All the example programs that you automatically got when you installed the MIDI.h library seem to have a version of it somewhere in setup().

Steve

slipstick:
I'm interested in that. Can you link to the examples of MIDI controller code have you seen that use MIDI.h but don't have a begin() ? Maybe I haven't really needed it in my MIDI programs.

All the example programs that you automatically got when you installed the MIDI.h library seem to have a version of it somewhere in setup().

Steve

Being dyslexic as I am I would just try reversing pins 4 & 5 over, as that is a mistake I sometimes make.

Going back to your first post you said:-

I just want to be able to play stop and shift loop numbers with my feet, so just starting with a simple 4 button to begin with. As far as i am aware - all i need to do is to program the Arduino to send MIDICC messages of a certain value/velocity and MIDI channel.

Then why in your code are you sending program change messages when you want to send control messages?

In fact why are you using the MIDI library anyway?
Are you aware that if you want to send something to channel 1 in MIDI, in the code this corresponds to channel 0?

This code is what you had but sends control messages and not program messages and doesn't use the MIDI library.

const int buttonOne = 2; 
const int buttonTwo = 3;
const int buttonThree = 4;
const int buttonFour = 5;

// Arduino pin assignments
#define midiChannel (byte)0

void setup() {
  Serial.begin(31250);
pinMode(buttonOne,INPUT);
pinMode(buttonTwo, INPUT);
pinMode(buttonThree,INPUT);
pinMode(buttonFour, INPUT);

}


void loop() {
  
if(digitalRead(buttonOne) == HIGH) {
  delay(10);  
   if(digitalRead(buttonOne) == HIGH) {
     midiSend(0xB0, 0, 1);
     delay(250);
   }
}

if(digitalRead(buttonTwo) == HIGH) {
  delay(10); 
   if(digitalRead(buttonTwo) == HIGH) {
     midiSend(0xB0, 1, 1);
     delay(250);
   }
}

if(digitalRead(buttonThree) == HIGH) {
  delay(10); 
  if(digitalRead(buttonThree) == HIGH) {
    midiSend(0xB0, 2, 1);
    delay(250);
  }
}

if(digitalRead(buttonFour) == HIGH) {
  delay(10); 
   if(digitalRead(buttonFour) == HIGH) {
     midiSend(0xB0, 3, 1);
     delay(250);
   }
}
}

void midiSend(char cmd, char data1, char data2) {
  cmd = cmd | char(midiChannel);  // merge channel number
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
}

Now what we have to clear up is exactly what controller messages you need to send. The numbers in your original code which I have left untouched for the moment are not correct so don't expect the code to work just yet. The ERMIDI picture you posted has just the beginning of the Loop select messages. You need to post more of that so we can see the full story.

dpiddy81:
https://www.arduino.cc/en/Tutorial/BuiltInExamples/Midi#code

Doesn't use MIDI.h. Has the MIDI commands hard coded using Serial.write().

There's nothing stopping you from doing that as in Grumpy_Mike's latest code but it would be easier just to put the MIDI.begin() in setup().

Steve

slipstick:
There's nothing stopping you from doing that as in Grumpy_Mike's latest code but it would be easier just to put the MIDI.begin() in setup().

I've tried this, but it just gives me errors

OK - I have posted it, so from what i understand is I need control change messages...
85 - Play
87 - Stop
96 - loop up
97 - loop down
and they all need to be at velocity 65 to work?

So i'm assuming the code for this part is
if(digitalRead(buttonOne) == HIGH) {
delay(10);
if(digitalRead(buttonOne) == HIGH) {
midiSend(0xB0, 0, 1); // is this the declaration of note number and velocity?
delay(250);
}
}

Thanks for all the help so far!

and they all need to be at velocity 65 to work?

No. Controller messages that are either on or off need to be 0 or 127. Where it says 64 - 127 you should be using 127

You managed to miss vital point in that table, namely the loop number select and the headers to make sense about what all those numbers mean. Selecting a loop number looks like a two controller message affair, but I can’t be sure because the table is cut off too soon.

I've tried this, but it just gives me errors

Compile errors? If so you should copy and paste them into a reply along with the code you are trying to run. The error messages actually tell you where the compiler gave up, and from that you can probably work out what is wrong.

By the way the code you are starting from is crap, I just copied the structure for the time being. It needs some work on it to make it easy expandable.

Grumpy_Mike:
No. Controller messages that are either on or off need to be 0 or 127. Where it says 64 - 127 you should be using 127

You managed to miss vital point in that table, namely the loop number select and the headers to make sense about what all those numbers mean. Selecting a loop number looks like a two controller message affair, but I can’t be sure because the table is cut off too soon.

Attached

The order in the MIDI spec table is -> default - PC - CC - Value

repeater midi.pdf (196 KB)

Thanks for that. This is more complected than you thought. What that code would actually do, if it were correct, would be to simply select a loop for each button you pushed. It wouldn't play the loop, so you wouldn't know if the code had "worked"

So what you have to work out is what you want each of those push buttons to do, just in terms of function.

Then you need to write code that will do that function when a button becomes pressed, not just is pressed, and maybe what it does when it becomes unpressed. This sort of thing is known as a state change detection, there is an example of this in the IDE under File -> Examples -> 02.Digital -> StateChangeDetection. In involves remembering ( in a variable ) the last state you read from a pin and comparing it to the current state of a pin. If these two are the same nothing has changed. If these two are different then the current state of the pin has changed and you need to do something.

Note that each pin you need to monitor like this will need its own last state variable.

So start with one button, and I suggest it triggers the playing of a loop. When it becomes HIGH then send a play message, which is CC number 85 with a value of 127.

midiSend(0xB0, 85, 127);

When it becomes LOW send a CC 85 message with a value of 0.

midiSend(0xB0, 85, 0);

That will not stop the loop it will just put the unit into a state where it can accept another start.

Then add a second button for stopping the loop this is just like the start only you use CC number 86.
See how you get on with that.

If you have trouble then post your code and say what happens.

By the way you should be able to pick up something from the code I posted on the MIDI-OX, you should see it spewing out messages when a button is held down, which illustrates why you need a state change detection.