Go Down

Topic: MIDI Note On/Off Messages (Read 9066 times) previous topic - next topic

GirlNamedGoo

Hey all,

I have built a MIDI controller, consisting of a 3x3 grid of arcade buttons, 4 pots and 2 faders. The pots and faders are attached to the analog pins on an Arduino Uno and send MIDI CC Messages. The 3x3 grid buttons are attached to the digital pins and send Note On messages when pushed and Note Off messages otherwise.

The problem with the buttons is that they continually send MIDI Note Off messages when they are not pressed. This causes the computer that the controller is attached to to slow down alot and causes lag. It's just not really ideal. Is there a way to code the Arduino so that it only sends a Note On message and then only one Note Off message when the button is let go?

The code I am using is below.

Thanks  :)


Code: [Select]
#include <MIDI.h>


//**BUTTONS**
// Set inputs and outputs 
const int BUTTON1 = 2;
const int BUTTON2 = 3;
const int BUTTON3 = 4;
const int BUTTON4 = 5;
const int BUTTON5 = 6;
const int BUTTON6 = 7;
const int BUTTON7 = 8;
const int BUTTON8 = 9;
const int BUTTON9 = 10;
const int LED = 13;
int buttonState = 0;


void setup() { 
  //  Set MIDI baud rate:
  Serial.begin(31250);   

//**BUTTONS**
  pinMode(BUTTON1, INPUT);
  pinMode(BUTTON2, INPUT);
  pinMode(BUTTON3, INPUT);
  pinMode(BUTTON4, INPUT);
  pinMode(BUTTON5, INPUT);
  pinMode(BUTTON6, INPUT);
  pinMode(BUTTON7, INPUT);
  pinMode(BUTTON8, INPUT);
  pinMode(BUTTON9, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
   // read the pushbutton value:
  buttonState = digitalRead(BUTTON1);
 
  //check if the button has been pressed.
  //if the button state is HIGH, turn on the LED and play a note:
  if (buttonState == HIGH) {
    digitalWrite(LED, HIGH);
    MIDI.sendNoteOn(36, 127, 1);
  }
  else {
    digitalWrite(LED, LOW);
    MIDI.sendNoteOff(36, 0, 1);
  }
}


//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

Nantonos

Your code is constantly detecting the state of each button and always sending a MIDI message. Instead, you should be looking for a change of state (on to off, or off to on). For each button, save the state. When reading the state, compare it to the value last time the loop and only send a MIDI message if the value has changed. Then set the saved state to the current reading.

GirlNamedGoo

Thanks for your reply:)


Instead, you should be looking for a change of state (on to off, or off to on). For each button, save the state. When reading the state, compare it to the value last time the loop and only send a MIDI message if the value has changed. Then set the saved state to the current reading.


Okay, so by using the buttonState function, does this code make a little more sense?
Code: [Select]



// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state:
  if (buttonState != lastButtonState) {
 
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
    MIDI.sendNoteOn(36, 127, 1);
   
    }
    else {
      // if the current state is LOW then the button went from on to off:
    MIDI.sendNoteOff(36, 0, 1); 
  }
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
 
}

//  plays a MIDI note.  Doesn't check to see that

void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

Nantonos

it does, yes. Did you try it?

I notice that its still only one button, and that you actually want 9 buttons. I also saw some variable names like button2, button3 etc in your earlier code. Do you know about arrays?

GirlNamedGoo

Hiya,

Yes it worked! Thank you :)

The extra variables are for the additional buttons. Essentially copied the code for 9 buttons. I'm not sure what you mean by arrays though?

GirlNamedGoo

I'm also having trouble now where some of the button send out a MIDI Note On message at the same pitch, but I'm not sure what it could be. Perhaps my circuit is a little dodgy or something?

deved

Hi, did you ever get this problem solved? I am making a simple midi drum trigger and am having problems with constant retriggering while a button is pressed. I thought your code above comparing button press states did the trick but it didn't...

boguz

Hi.
i am also very interested in Midi Controllers and i had also this problem before.

The last code you posted has the code for only one button, so it is hard to say exactly why you are having your problem.
To have each button send different notes, you need them to send different MIDI Messages. You are sending your messages like this:

Code: [Select]
void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}


so, when you click a button, those are the parameters you want each button to send: Command, PITCH and Velocity.
If for the pitch you send the same value for each button, then they will "play the same note"...
So, if you want different notes you should send different PITCH values for each button.  ;)


Another good idea, as someone mentioned before, would be to use an array.
This means that instead of writing the code for each button you have to write it only ONCE and it will work for all the buttons.
You can see here how it works:
http://arduino.cc/en/Tutorial/Array

Maybe at the beginning it looks a little bit strange, but it is worth taking your time to understand it. Arrays are quite important and can really help you save time and make your code much smaller and easy to read.
Give it a try. If you have any problems, i'll be happy to help you!

Go Up