Go Down

Topic: Beginner to arrays trying to send MIDI Note On & Note Off messages (Read 668 times) previous topic - next topic

AMBosworth

I had achieved working code as per the instructions in this thread, however I wanted to take up the challenge of writing my code into an array in the hope (perhaps misguided?) that this would also solve my problem of wanting to debounce multiple buttons so that they could be simultaneously pressed achieving polyphonic output.

This is my (working, but redundant) code from before trying to create the array:

Code: [Select]
// variables will not change
const int button1 = 9;
const int button2 = 10;
const int button3 = 11;
const int button4 = 12; //button attach to pin12

// variables will change
int button1State = 0; //current state of the button
int lastButton1State = 0; //previous state of the button

int button2State = 0; //current state of the button
int lastButton2State = 0; //previous state of the button

int button3State = 0; //current state of the button
int lastButton3State = 0; //previous state of the button

int button4State = 0; //current state of the button
int lastButton4State = 0; //previous state of the button

void setup() {
  //  Set MIDI baud rate:
  Serial.begin(31250);
  pinMode(button1,INPUT);//initialize the key pin as input
  pinMode(button2,INPUT);
  pinMode(button3,INPUT);
  pinMode(button4,INPUT);
}

void loop()

{
  //read the state of the key value
  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  button3State = digitalRead(button3);
  button4State = digitalRead(button4);
 
  //compare button1State to its previous state:
  if (button1State != lastButton1State) {

    if (button1State == HIGH) {
      //if the current state is HIGH then the button went from off to on:
      noteOn(0x90, 0x1E, 0x45); //note on, channel 1, F#-0, middle velocity
      delay(10);
    }
    else {
      //if the current state is LOW then the button went from on to off:
      noteOn(0x90, 0x1E, 0x00); //note off of same as above
      delay(10);
    }
  }

  //compare button2State to its previous state:
  if (button2State != lastButton2State) {

    if (button2State == HIGH) {
      //if the current state is HIGH then the button went from off to on:
      noteOn(0x90, 0x21, 0x45); //note on, channel 1, F#-0, middle velocity
      delay(10);
    }
    else {
      //if the current state is LOW then the button went from on to off:
      noteOn(0x90, 0x21, 0x00); //note off of same as above
      delay(10);
    }
  }

  //compare button3State to its previous state:
  if (button3State != lastButton3State) {

    if (button3State == HIGH) {
      //if the current state is HIGH then the button went from off to on:
      noteOn(0x90, 0x1F, 0x45); //note on, channel 1, F#-0, middle velocity
      delay(10);
    }
    else {
      //if the current state is LOW then the button went from on to off:
      noteOn(0x90, 0x1F, 0x00); //note off of same as above
      delay(10);
    }
  }

  //compare button4State to its previous state:
  if (button4State != lastButton4State) {

    if (button4State == HIGH) {
      //if the current state is HIGH then the button went from off to on:
      noteOn(0x90, 0x20, 0x45); //note on, channel 1, F#-0, middle velocity
      delay(10);
    }
    else {
      //if the current state is LOW then the button went from on to off:
      noteOn(0x90, 0x20, 0x00); //note off of same as above
      delay(10);
    }
  }
  //save the current state as the last state,
  //for next time through the loop
  lastButton1State = button1State;
  lastButton2State = button2State;
  lastButton3State = button3State;
  lastButton4State = button4State;
}

//  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);
}


When I tried to create the array, instead of getting a MIDI Note On message upon button press and a MIDI Note Off message upon button release, I'm getting 12 separate MIDI Note On messages on button press and nothing happens on button release. Here is the code:

Code: [Select]
//arrays for buttons and note values
const int numberButtons = 4; //number of buttons
int button[numberButtons] = {9,10,11,12}; //pins connected to button
uint8_t note[] = {0x00, 0x01, 0x02, 0x03}; //MIDI note values to be used

//wizardry for button debounce
int lastButtonState = 0; //set default state to off
bool buttonActive[numberButtons]; //bool for when button is pressed
int buttonState = buttonActive[numberButtons]; //convert bool to int

void setup() {
  //  Set MIDI baud rate:
  Serial.begin(31250);
  pinMode(9,INPUT);//initialize the key pin as input
  pinMode(10,INPUT);
  pinMode(11,INPUT);
  pinMode(12,INPUT);
}

void loop()

{
  for (int x=0; x<numberButtons; x++){
  //read the state of the key value
  buttonState = digitalRead(button[x]);
 
  //compare 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:
      noteOn(0x90, note[x], 0x45); //note on, channel 1, pitch value, middle velocity
      delay(10);
    }
    else {
      //if the current state is LOW then the button went from on to off:
      noteOn(0x90, note[x], 0x00); //note on*, channel 1, same pitch, low velocity
      delay(10);
    }
  }
  }
  //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
//  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);
}

Hints as to the error of my ways would be greatly appreciated. Whether or not I'm able to achieve proper debouncing this way, I really would like to learn how to use an array to my advantage. (And assuming this doesn't solve my polyphonic button problem, if anyone could point me in the right direction there, I'd be eternally grateful.)

AMBosworth

At the very least, after some human testing, I can't seem to get the 10ms delay to actually cause two cues to -not- fire when pressed simultaneously, so we should be fine on the polyphony front.  Still would love to figure out why my array isn't working, though.

Grumpy_Mike

You need to have the last button state as an array because you loose the value of the last button state once you iterate through the for loop.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy