Can anyone give me a few pointers for midi input receiving program changes?

Hi there,

can anyone point me in the right direction to read midi input program changes?

I have been searching around on the net for midi input examples but they are all reading note on off midi messages.
This kind of throws me as i am not brilliant at programming yet i could do with some tutorial or example code to read
program changes and switch on leds just something simple enough to get my head around.

I am not sure which is easiest for eg. using the midi.h header library or not. I havent really found much info on that in terms of
using snippets of code from that library header file.

cheers

In the Examples directory of the Arduino 1.0.3 IDE is a directory called MIDI which contains a sketch named MIDI_Input. It doesn't do anything staggeringly useful but it does read midi messages and it looks specifically for Program Change messages. Start with that and change it as needed.

Pete

I have a sketch here that decodes MIDI:

http://arduino.cc/forum/index.php?topic=100382.0

i can see your decoder does everything yet i dont really want to use it and all the other features that i will not be using.

I just want to understand code to decode program change 0-12 on channel 1 and the result of each program change turning on a led.

i managed to get it reading the midi message as it flashes led on pin 13 on incomingbyte but i cant get individual leds on pins 11 and 12 etc so that when i press program change 00 on my foot controller led pin 12 comes on and then i press program change 01 led pin 11 comes on.

just something as basic as that. i will have to post code later but thats what i am after just something simple and easy to understand at first.

cheers

i have just got 3 program changes working to switch 3 leds on. slowly but surely getting there and understanding abit more.

i am sure the code could be optimised, but i am wondering how to go about turning off each led when receiving the same midi message...basically like a stomp switch on/off with the same program change?

for eg. Program change 1 switch on led, receive another Program change 1 switch led off?

my code is this so far...any suggestions?

byte statusByte; //first data byte
byte dataByte; // second data byte
byte channel = 192; //program change channel 1


void setup(){
      
  Serial.begin(31250);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  
}

void checkMIDI(){

  do{
    
  if (Serial.available())
  {
  statusByte = Serial.read();//read first byte
  dataByte = Serial.read();//read next byte
  
  
    if (statusByte == channel)
    {
    
    if (channel == 192 & dataByte == 0)  //channel should really be progchange and databyte should be labelled progvalue or patchvalue
    {
    digitalWrite(13,HIGH);//turn on led
    }
    
    if (channel == 192 & dataByte == 1)
    {
    digitalWrite(12,HIGH);//turn on led
    }
    
    if (channel == 192 & dataByte == 2)
    {
    digitalWrite(11,HIGH);//turn on led
    }
   }
 }
}
  while (Serial.available() > 16);//when two bytes available
}

void loop(){
  
  checkMIDI();
  delay(100);
  
}
  if (Serial.available())
  {
  statusByte = Serial.read();//read first byte
  dataByte = Serial.read();//read next byte

You are only certain you have one byte available, not two.

i am sure the code could be optimised, but i am wondering how to go about turning off each led when receiving the same midi message...basically

If it is on, turn it off and vice-versa. eg.

  if (digitalRead (13) == LOW)
    digitalWrite (13, HIGH);  //turn on led
  else
    digitalWrite (13, LOW);  //turn off led

thanks for the reply. i think i realised earlier what i needed to do. instead of using the program change use control change as it has 2 data bytes after the status byte? so first data byte to turn on and second data byte to turn off?

might have gotten confused with a few projects for midi functionality.

kh602: thanks for the reply. i think i realised earlier what i needed to do. instead of using the program change use control change as it has 2 data bytes after the status byte? so first data byte to turn on and second data byte to turn off?

might have gotten confused with a few projects for midi functionality.

No the first data yet is the controller number and the second is the controller value. In that code as you are always checking for one of the same bytes put that check in an if statement that includes all the other checks.

How do you go about grouping the LEDs to an if statement to switch switch off rather than individually like I have done in my code so far?

I tried declaring them as something like

define LED1 13

define LED2 12

define LED3 11

Int leds[3] {LED1, LED2, LED3}

Then at the end of all the if statements use

Else digitalWrite(leds[3] {LED1,LED2,LED3} = LOW);

Is that the kind of grouping/check you mean to simplify the if statements?

It sort of worked, LEDs switched on but were dimm and they would go low When the same Program change data was pressed again.

I saw this bit of code else where and thought I would try using it. It might Not be exact but it was that kind of layout of code.

Thanks for replying

I meant this bit of code:-

if (statusByte == channel)
    {
    
    if (channel == 192 & dataByte == 0)  //channel should really be progchange and databyte should be labelled progvalue or patchvalue
    {
    digitalWrite(13,HIGH);//turn on led
    }
    
    if (channel == 192 & dataByte == 1)
    {
    digitalWrite(12,HIGH);//turn on led
    }
    
    if (channel == 192 & dataByte == 2)
    {
    digitalWrite(11,HIGH);//turn on led
    }
   }
 }
}

Could be simplified by grouping in an outer if statement

if (statusByte == channel)
    {
   if( channel == 192) { 
    if (dataByte == 0)  //channel should really be progchange and databyte should be labelled progvalue or patchvalue
    {
    digitalWrite(13,HIGH);//turn on led
    }
    
    if (dataByte == 1)
    {
    digitalWrite(12,HIGH);//turn on led
    }
    
    if (dataByte == 2)
    {
    digitalWrite(11,HIGH);//turn on led
    }
   }
 }

That could be simplified even further to

if (statusByte == channel)
    {
   if( channel == 192) { 
    if (dataByte < maxData)  //channel should really be progchange and databyte should be labelled progvalue or patchvalue
    {
    digitalWrite(pins[dataByte] ,HIGH);//turn on led
    }   
   }
  }

if you define an array ‘pins’ with a list of pin numbers for data bytes.

This bit is wrong

if (Serial.available())
  {
  statusByte = Serial.read();//read first byte
  dataByte = Serial.read();//read next byte

you need to ensure there is the full message in the buffer first

if (Serial.available()>=3)
  {
  statusByte = Serial.read();//read first byte
  controlerByte Serial.read();
  dataByte = Serial.read();

Note that the status byte contains both the command and the channel number. The channel number is in the least significant nibble ( four bits ) and the command in the upper four bits. You can separate them using the bitwise and function.

 channelNumber = statusByte & 0xF;
command = statusByte & 0xF0;

kh602:
How do you go about grouping the LEDs to an if statement to switch switch off rather than individually like I have done in my code so far?


digitalWrite(leds[3] {LED1,LED2,LED3} = LOW);

You can’t do it like that. An array of LED numbers can be set up which you iterate through. Something like this:

const byte numPins = 3;
const byte pins [numPins] = { 5, 6, 7 };

void setup ()
  {
  for (byte i = 0; i < numPins; i++)
    pinMode (pins [i], OUTPUT);
  }  // end of setup

void loop () { }

cheers for the bits of code. I will try some of this later on today.

How does the array know what midi data is assigned to an LED pin out of the array list rather than me specifying if receiving this midi byte switch this led on and so forth?

kh602: cheers for the bits of code. I will try some of this later on today.

How does the array know what midi data is assigned to an LED pin out of the array list rather than me specifying if receiving this midi byte switch this led on and so forth?

Simply by the order the numbers are in, in the array. The first entry in the array is the led that comes on when data byte zero is received. If you do not want to start from zero then subtract an offset value from the data byte inside the square brackets of the array.