MIDI Code not working. HELP!

Help! My Arduino MIDI code is not working, and you all know much more about it than I do. Please help me to fix it! Also, any other suggestions for my code would be helpful. (Not all of this code was written by me. I used some code written by others in my program. I used no copyrighted coding, however.)

I want to use this for a player piano. I know that it is incomplete. I will write more code when I have more capital for parts.

Compiling for Arduino UNO.

Code is attached and below.

Code:

#include <MIDI.h>
#include <ShiftRegister74HC595.h> //Adds Shift register library to Arduino.
int numberOfShiftRegisters = 1; //Sets number of daisychained shift registers.
int serialDataPin = 2; //Sets pin for serial data on the arduino.
int clockPin = 3; //Sets pin for clock signal on the arduino.
int latchPin = 4; //Sets pin for latch pin on the arduino.
int OEPin = 5; //Sets pin for Output Enable control.
int MRPin = 6; //Sets pin for Master Reclear control.
ShiftRegister74HC595 sr (numberOfShiftRegisters,serialDataPin,clockPin,latchPin); //Prepares communication with Shift Register according to settings above.
MIDI_CREATE_DEFAULT_INSTANCE();

void setup(){
pinMode (OEPin, OUTPUT); //Sets Output Enable pin on Arduino to an output.
pinMode (MRPin, OUTPUT); //Sets Master Reclear pin on Arduino to an output.
digitalWrite (OEPin, LOW); //Ties Output Enable pin LOW. Can also provide GND for Shift Register.
digitalWrite (MRPin, HIGH); //Ties Master reclear pin HIGH. Can also provide 5V for Shift Register.
MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
// OMNI sets it to listen to all channels.. MIDI.begin(2) would set it
// to respond to notes on channel 2 only.
MIDI.setHandleNoteOn(HandleNoteOn); // This is important!! This command
// tells the Midi Library which function you want to call when a NOTE ON command
// is received. In this case it's "MyHandleNoteOn".
MIDI.setHandleNoteOff(HandleNoteOff); // This command tells the Midi Library
// to call "MyHandleNoteOff" when a NOTE OFF command is received.
sr.set(0,LOW); //This section sets all notes to their off state.
sr.set(1,LOW);
sr.set(2,LOW);
sr.set(3,LOW);
sr.set(4,LOW);
sr.set(5,LOW);
sr.set(6,LOW);
sr.set(7,LOW);
}

void loop() {
MIDI.read(); // Continuously check if Midi data has been received.

// MyHandleNoteON is the function that will be called by the Midi Library
// when a MIDI NOTE ON message is received.
// It will be passed bytes for Channel, Pitch, and Velocity
void HandleNoteOn(byte channel, byte pitch, byte velocity) {
if (note == 60){
sr.set(0, HIGH);
}
else if (note == 62){
sr.set(1, HIGH);//turn on led
}
else if (note == 64 ){
sr.set(2, HIGH);//turn on led
}
else if (note == 65 ){
sr.set(3, HIGH);//turn on led

}
else if (note == 67 ){
sr.set(4, HIGH);//turn on led
}
else if (note == 69 ){
sr.set(5, HIGH);//turn on led
}
else if (note == 71 ){
sr.set(6, HIGH);//turn on led
}
else if (note == 72 ){
sr.set(7, HIGH);//turn on led
}

// MyHandleNoteOFF is the function that will be called by the Midi Library
// when a MIDI NOTE OFF message is received.
// * A NOTE ON message with Velocity = 0 will be treated as a NOTE OFF message *
// It will be passed bytes for Channel, Pitch, and Velocity
void HandleNoteOff(byte channel, byte pitch, byte velocity) {

if (note == 60){
sr.set(0,LOW);//turn on led
}
else if (note == 62 ){
sr.set(1,LOW);//turn on led
}
else if (note == 64 ){
sr.set(2,LOW);//turn on led
}
else if (note == 65 ){
sr.set(3,LOW);//turn on led
}
else if (note == 67 ){
sr.set(4,LOW);//turn on led
}
else if (note == 69 ){
sr.set(5,LOW);//turn on led
}
else if (note == 71 ){
sr.set(6,LOW);//turn on led
}
else if (note == 72 ){
sr.set(7,LOW);//turn on led
}
}

Error:

C:\Users\Family\Desktop\MIDI_Player_Piano_sketch_1\MIDI_Player_Piano_sketch_1.ino: In function 'void setup()':

MIDI_Player_Piano_sketch_1:20:24: error: 'HandleNoteOn' was not declared in this scope

MIDI.setHandleNoteOn(HandleNoteOn); // This is important!! This command

^

MIDI_Player_Piano_sketch_1:23:25: error: 'HandleNoteOff' was not declared in this scope

MIDI.setHandleNoteOff(HandleNoteOff); // This command tells the Midi Library

^

C:\Users\Family\Desktop\MIDI_Player_Piano_sketch_1\MIDI_Player_Piano_sketch_1.ino: In function 'void loop()':

MIDI_Player_Piano_sketch_1:43:60: error: a function-definition is not allowed here before '{' token

void HandleNoteOn(byte channel, byte pitch, byte velocity) {

^

MIDI_Player_Piano_sketch_1:100:1: error: expected '}' at end of input

}

^

exit status 1
'HandleNoteOn' was not declared in this scope

Thanks for any help you can give me!!!!!

MIDI_Player_Piano_sketch_1.ino (3.78 KB)

You're trying to define your handler functions INSIDE the loop() function. That's not allowed. Try completing loop() with a } immediately after the MIDI.read().

If you use AutoFormat (Ctrl-T) in the IDE it shows things like that up clearly. And please read How to use this forum - please read. - Installation & Troubleshooting - Arduino Forum to see how to ask questions and how to post your code correctly.

Steve

You can do this very easily using the Control Surface library:

Getting started with Control Surface and MIDI input

[color=#434f54]// Include the library[/color]
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]Control_Surface[/color][/b][color=#434f54].[/color][color=#000000]h[/color][color=#434f54]>[/color]
 
[color=#434f54]// Instantiate a MIDI Interface to use[/color]
[b][color=#d35400]USBMIDI_Interface[/color][/b] [color=#00979c]midi[/color][color=#000000];[/color]
 
[color=#434f54]// Instantiate a shift register as output for the LEDs[/color]
[b][color=#d35400]SPIShiftRegisterOut[/color][/b][color=#434f54]<[/color][color=#000000]8[/color][color=#434f54]>[/color] [color=#000000]sreg[/color] [color=#434f54]=[/color] [color=#000000]{[/color]
  [color=#000000]10[/color][color=#434f54],[/color]       [color=#434f54]// Latch pin (ST_CP)[/color]
  [color=#00979c]MSBFIRST[/color][color=#434f54],[/color] [color=#434f54]// Byte order[/color]
[color=#000000]}[/color][color=#000000];[/color]
 
[color=#5e6d03]using[/color] [color=#5e6d03]namespace[/color] [color=#000000]MIDI_Notes[/color][color=#000000];[/color]
 
[color=#434f54]// Create an array of LEDs that listen to MIDI Note messages, turning on and off[/color]
[color=#434f54]// the LEDs connected to the eight output pins of the shift register[/color]
[b][color=#d35400]NoteValueLED[/color][/b] [color=#000000]leds[/color][color=#000000][[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#000000]{[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]0[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]C[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]// LED pin, address (note number, channel, cable)[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]1[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]D[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]2[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]E[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]3[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]F[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]4[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]G[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]5[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]A[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]6[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]B[/color][color=#434f54],[/color] [color=#000000]4[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
  [color=#000000]{[/color][color=#000000]sreg[/color][color=#434f54].[/color][color=#d35400]pin[/color][color=#000000]([/color][color=#000000]7[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]note[/color][color=#000000]([/color][color=#000000]C[/color][color=#434f54],[/color] [color=#000000]5[/color][color=#000000])[/color][color=#000000]}[/color][color=#434f54],[/color] [color=#434f54]//[/color]
[color=#000000]}[/color][color=#000000];[/color]
 
[color=#434f54]// Initialize the Control Surface[/color]
[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [b][color=#d35400]Control_Surface[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]
 
[color=#434f54]// Update the Control Surface[/color]
[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [b][color=#d35400]Control_Surface[/color][/b][color=#434f54].[/color][color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]

By default, the shift registers are driven by the SPI bus. I'd strongly recommend to keep this, as it's much faster than using "shiftOut" on other pins. If you do have a valid reason not to use the SPI pins, you can use the "shiftOut" version, ShiftRegisterOut instead of SPIShiftRegisterOut.

If you want to use a hardware serial port instead of MIDI over USB, you can use HardwareSerialMIDI_Interface.

Pieter

Slipstick, I tried what you said, using Ctrl + T. I now have another error message. by the way, thanks for the tips on proper formatting and the like. This was my first forum post, and I simply did not know.

Here is my revised code:

#include <MIDI.h>
#include <ShiftRegister74HC595.h>  //Adds Shift register library to Arduino.
int numberOfShiftRegisters = 1; //Sets number of daisychained shift registers.
int serialDataPin = 2; //Sets pin for serial data on the arduino.
int clockPin = 3;  //Sets pin for clock signal on the arduino.
int latchPin = 4;  //Sets pin for latch pin on the arduino.
int OEPin = 5; //Sets pin for Output Enable control.
int MRPin = 6; //Sets pin for Master Reclear control.
ShiftRegister74HC595 sr (numberOfShiftRegisters, serialDataPin, clockPin, latchPin); //Prepares communication with Shift Register according to settings above.
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode (OEPin, OUTPUT);  //Sets Output Enable pin on Arduino to an output.
  pinMode (MRPin, OUTPUT);  //Sets Master Reclear pin on Arduino to an output.
  digitalWrite (OEPin, LOW); //Ties Output Enable pin LOW. Can also provide GND for Shift Register.
  digitalWrite (MRPin, HIGH); //Ties Master reclear pin HIGH. Can also provide 5V for Shift Register.
  MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
  // OMNI sets it to listen to all channels.. MIDI.begin(2) would set it
  // to respond to notes on channel 2 only.
  MIDI.setHandleNoteOn(HandleNoteOn); // This is important!! This command
  // tells the Midi Library which function you want to call when a NOTE ON command
  // is received. In this case it's "MyHandleNoteOn".
  MIDI.setHandleNoteOff(HandleNoteOff); // This command tells the Midi Library
  // to call "MyHandleNoteOff" when a NOTE OFF command is received.
  sr.set(0, LOW); //This section sets all notes to their off state.
  sr.set(1, LOW);
  sr.set(2, LOW);
  sr.set(3, LOW);
  sr.set(4, LOW);
  sr.set(5, LOW);
  sr.set(6, LOW);
  sr.set(7, LOW);
}

void loop() {
  MIDI.read(); // Continuously check if Midi data has been received.
}



// MyHandleNoteON is the function that will be called by the Midi Library
// when a MIDI NOTE ON message is received.
// It will be passed bytes for Channel, Pitch, and Velocity
void HandleNoteOn(byte channel, byte pitch, byte velocity) {
  if (note == 60) {
    sr.set(0, HIGH);
  }
  else if (note == 62) {
    sr.set(1, HIGH);//turn on led
  }
  else if (note == 64 ) {
    sr.set(2, HIGH);//turn on led
  }
  else if (note == 65 ) {
    sr.set(3, HIGH);//turn on led

  }
  else if (note == 67 ) {
    sr.set(4, HIGH);//turn on led
  }
  else if (note == 69 ) {
    sr.set(5, HIGH);//turn on led
  }
  else if (note == 71 ) {
    sr.set(6, HIGH);//turn on led
  }
  else if (note == 72 ) {
    sr.set(7, HIGH);//turn on led
  }

  // MyHandleNoteOFF is the function that will be called by the Midi Library
  // when a MIDI NOTE OFF message is received.
  // * A NOTE ON message with Velocity = 0 will be treated as a NOTE OFF message *
  // It will be passed bytes for Channel, Pitch, and Velocity
  void HandleNoteOff(byte channel, byte pitch, byte velocity) {

    if (note == 60) {
      sr.set(0, LOW); //turn on led
    }
    else if (note == 62 ) {
      sr.set(1, LOW); //turn on led
    }
    else if (note == 64 ) {
      sr.set(2, LOW); //turn on led
    }
    else if (note == 65 ) {
      sr.set(3, LOW); //turn on led
    }
    else if (note == 67 ) {
      sr.set(4, LOW); //turn on led
    }
    else if (note == 69 ) {
      sr.set(5, LOW); //turn on led
    }
    else if (note == 71 ) {
      sr.set(6, LOW); //turn on led
    }
    else if (note == 72 ) {
      sr.set(7, LOW); //turn on led
    }
  }

Here is my error:

C:\Users\Family\Desktop\MIDI_Player_Piano_sketch_1\MIDI_Player_Piano_sketch_1.ino: In function 'void setup()':

MIDI_Player_Piano_sketch_1:23:25: error: 'HandleNoteOff' was not declared in this scope

   MIDI.setHandleNoteOff(HandleNoteOff); // This command tells the Midi Library

                         ^

C:\Users\Family\Desktop\MIDI_Player_Piano_sketch_1\MIDI_Player_Piano_sketch_1.ino: In function 'void HandleNoteOn(byte, byte, byte)':

MIDI_Player_Piano_sketch_1:45:7: error: 'note' was not declared in this scope

   if (note == 60) {

       ^

MIDI_Player_Piano_sketch_1:75:63: error: a function-definition is not allowed here before '{' token

   void HandleNoteOff(byte channel, byte pitch, byte velocity) {

                                                               ^

MIDI_Player_Piano_sketch_1:101:3: error: expected '}' at end of input

   }

   ^

exit status 1
'HandleNoteOff' was not declared in this scope

Darn- I still don't have the formatting right... Oh, well. I'll try again next time I need to upload code, I guess.

Sorry about my first couple of posts. I managed to fix some errors just by adding extra brackets, but more are showing up. This time, I was able, with your help, to fix some of the "HandleNoteOn" and "HandleNoteOff" errors. Now, however, I am experiencing problems with the "note" variable. Also, I think my formatting may be alright now. we'll see.

Code:

#include <MIDI.h>
#include <ShiftRegister74HC595.h>  //Adds Shift register library to Arduino.
int numberOfShiftRegisters = 1; //Sets number of daisychained shift registers.
int serialDataPin = 2; //Sets pin for serial data on the arduino.
int clockPin = 3;  //Sets pin for clock signal on the arduino.
int latchPin = 4;  //Sets pin for latch pin on the arduino.
int OEPin = 5; //Sets pin for Output Enable control.
int MRPin = 6; //Sets pin for Master Reclear control.
ShiftRegister74HC595 sr (numberOfShiftRegisters, serialDataPin, clockPin, latchPin); //Prepares communication with Shift Register according to settings above.
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode (OEPin, OUTPUT);  //Sets Output Enable pin on Arduino to an output.
  pinMode (MRPin, OUTPUT);  //Sets Master Reclear pin on Arduino to an output.
  digitalWrite (OEPin, LOW); //Ties Output Enable pin LOW. Can also provide GND for Shift Register.
  digitalWrite (MRPin, HIGH); //Ties Master reclear pin HIGH. Can also provide 5V for Shift Register.
  MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
  // OMNI sets it to listen to all channels.. MIDI.begin(2) would set it
  // to respond to notes on channel 2 only.
  MIDI.setHandleNoteOn(HandleNoteOn); // This is important!! This command
  // tells the Midi Library which function you want to call when a NOTE ON command
  // is received. In this case it's "MyHandleNoteOn".
  MIDI.setHandleNoteOff(HandleNoteOff); // This command tells the Midi Library
  // to call "MyHandleNoteOff" when a NOTE OFF command is received.
  sr.set(0, LOW); //This section sets all notes to their off state.
  sr.set(1, LOW);
  sr.set(2, LOW);
  sr.set(3, LOW);
  sr.set(4, LOW);
  sr.set(5, LOW);
  sr.set(6, LOW);
  sr.set(7, LOW);
}

void loop() {
  MIDI.read(); // Continuously check if Midi data has been received.
}



// MyHandleNoteON is the function that will be called by the Midi Library
// when a MIDI NOTE ON message is received.
// It will be passed bytes for Channel, Pitch, and Velocity
void HandleNoteOn(byte channel, byte pitch, byte velocity) {
  if (note == 60) {
    sr.set(0, HIGH);
  }
  else if (note == 62) {
    sr.set(1, HIGH);//turn on led
  }
  else if (note == 64 ) {
    sr.set(2, HIGH);//turn on led
  }
  else if (note == 65 ) {
    sr.set(3, HIGH);//turn on led

  }
  else if (note == 67 ) {
    sr.set(4, HIGH);//turn on led
  }
  else if (note == 69 ) {
    sr.set(5, HIGH);//turn on led
  }
  else if (note == 71 ) {
    sr.set(6, HIGH);//turn on led
  }
  else if (note == 72 ) {
    sr.set(7, HIGH);//turn on led
  }
}
  // MyHandleNoteOFF is the function that will be called by the Midi Library
  // when a MIDI NOTE OFF message is received.
  // * A NOTE ON message with Velocity = 0 will be treated as a NOTE OFF message *
  // It will be passed bytes for Channel, Pitch, and Velocity
  void HandleNoteOff(byte channel, byte pitch, byte velocity) {

    if (note == 60) {
      sr.set(0, LOW); //turn on led
    }
    else if (note == 62 ) {
      sr.set(1, LOW); //turn on led
    }
    else if (note == 64 ) {
      sr.set(2, LOW); //turn on led
    }
    else if (note == 65 ) {
      sr.set(3, LOW); //turn on led
    }
    else if (note == 67 ) {
      sr.set(4, LOW); //turn on led
    }
    else if (note == 69 ) {
      sr.set(5, LOW); //turn on led
    }
    else if (note == 71 ) {
      sr.set(6, LOW); //turn on led
    }
    else if (note == 72 ) {
      sr.set(7, LOW); //turn on led
    }
  }

Error:

C:\Users\Family\Desktop\MIDI_Player_Piano_sketch_1\MIDI_Player_Piano_sketch_1.ino: In function 'void HandleNoteOn(byte, byte, byte)':

MIDI_Player_Piano_sketch_1:45:7: error: 'note' was not declared in this scope

   if (note == 60) {

       ^

C:\Users\Family\Desktop\MIDI_Player_Piano_sketch_1\MIDI_Player_Piano_sketch_1.ino: In function 'void HandleNoteOff(byte, byte, byte)':

MIDI_Player_Piano_sketch_1:77:9: error: 'note' was not declared in this scope

     if (note == 60) {

         ^

exit status 1
'note' was not declared in this scope

MIDI_Player_Piano_sketch_1.ino (3.51 KB)

Well, the compiler is right, you didn't declare "note". You did declare "pitch".

Okay, I don't know much about this. I'm assuming that you're saying that I should change "note" into "pitch"?

I did that, and the compiler likes me now. However, I must ask: Will that still work with my note numbers, or will I have to change those to the notes' pitch in hertz?

I do not yet have my hardware to test it out, so I am trying to keep my later software changes to a minimum and work out bugs now, while I wait for international shipping from China.

I do not know too much about this, so I am asking you guys, who are much more knowledgeable about these things than I am.

Thanks for the help!

The names of your variables are arbitrary. That is, they don't affect the meaning of their contents.

"byte pitch" is the declaration of variable "pitch" of type "byte". You could've called it "note" and it would also be correct.

The meaning of the variable comes from the MIDI library: you pass the HandleNoteOn function to the MIDI library as a callback function. The MIDI library calls this function when a MIDI note message comes in, and it decides what values it passes to the function as arguments.

You can find the meaning of the parameters in the documentation: Arduino MIDI Library: Thru Struct Reference

As you can see, the first parameter is the channel, the second the note, and the third the value (velocity).
These terms are also used by the MIDI standard, so you should be able to interpret them.

As you've found out, you don't have to use any specific names for the parameters of your callback function. The values of the arguments will be the same, regardless of their name.

According to the MIDI standard 0x3C or 60 is the note number of middle C. The unit is 1 semitone, so 62 is D, 64 is E, 65 is F, and so on (all in the fourth octave).

Thank you, PieterP. That is very helpful to me. :slight_smile: