two midi notes on 1 switch.

Im pretty new at this but have been doing a lot a research and can’t find anything that works with what I’m trying to do… what i am wanting is, for example, 8 buttons in total, 2 are banks, up and down. 6 are midi notes and each bank to have a new set of midi notes for the 6 buttons that are for the midi notes…

this is a simple version of what i already have but it does work. what i am needing is away to put it into a bank and then repeat what I’ve already got done…

#include <Bounce.h>

// the MIDI channel number to send messages
const int channel = 1;

// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or “bounce”, and
// it makes detecting changes very simple.

Bounce button14 = Bounce(14, 100);
Bounce button15 = Bounce(15, 100); // 5 = 5 ms debounce time
Bounce button2 = Bounce(2, 10); // which is appropriate for good
Bounce button3 = Bounce(3, 10); // quality mechanical pushbuttons
Bounce button4 = Bounce(4, 10);
Bounce button5 = Bounce(5, 10); // if a button is too “sensitive”
Bounce button6 = Bounce(6, 200); // to rapid touch, you can
Bounce button7 = Bounce(7, 10); // increase this time.
Bounce button8 = Bounce(8, 10);
Bounce button9 = Bounce(9, 10);
Bounce button10 = Bounce(10, 10);
Bounce button11 = Bounce(11, 10);
Bounce button12= Bounce(12, 10);

void setup() {
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP); // Teensy++ 2.0 LED, may need 1k resistor pullup
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP); //channel 1
pinMode(15, INPUT_PULLUP); // channel 2 Teensy 2.0 LED, may need 1k resistor pullup

}

void loop() {
button14.update();
button15.update();
button2.update();
button3.update();
button4.update();
button5.update();
button6.update();
button7.update();
button8.update();
button9.update();
button10.update();
button11.update();
button12.update();

if (button14.fallingEdge()) {
usbMIDI.sendNoteOn(60, 99, channel); // 60 = C4
}

delay(50);

if (button14.risingEdge()) {
usbMIDI.sendNoteOff(60, 0, channel); // 60 = C4
}

}

A suggestion.
Put the note values in a 2 dimensional array with each row having 6 columns and each row being a bank.

The up/down buttons select the row and the note buttons select the column to arrive at the required note value.

How would i go about putting the note value into the column and then assigning that note to a particular button?

How would i go about putting the note value into the column and then assigning that note to a particular button?

You type the values into the array

Have a look at this example

const byte anArray[2][4] = {
  {12, 34, 56, 78},
  {21, 32, 54, 76}
};

void setup()
{
  Serial.begin(115200);
  for (int row = 0; row < 2; row++)
  {
    for (int col = 0; col < 4; col++)
    {
      Serial.print(anArray[row][col]);
      Serial.print(",");
    }
    Serial.println();
  }
}

void loop(){}

As you can see the row value chooses a row in the array and the col value chooses a column. You can put the pin numbers of the button inputs into their own array and read through them with a for loop until you find one that a button has been pressed. At that point the for loop value will equal the column number from which to read the value from in the 2 dim array.

After a couple days of research and trial and error I still don't understand how to A. attach the "bank buttons" to scroll through the rows. B. how to attach the columns as the usbMIDI note...

Bank buttons

if (digitalRead(bankButton0) == LOW)
{
  row = 0;
}
else
if (digitalRead(bankButton1) == LOW) 
{
  row = 1;
}

This code assumes that the bank button pins are normally HIGH but change the logic if they are normally LOW. Once you understand that we will revisit how you choose the column and hence the note.

ok so here is what I’ve got so far… this code will upload to my project and the button14 has 2 notes assigned to it. however i can’t toggle between row 0 which has the first note, and row 1 which has the second note… i haven’t put anything on button15 yet. also nothing changes if between digitalRead HIGH or LOW…

#include <Bounce.h>
const int channel = 1;

int row;
int col;

int bankButton0 = 9;
int bankButton1 = 10;

Bounce button14 = Bounce(14, 100);
Bounce button15 = Bounce(15, 100);

int array[2][1] = {
{10},
{20}
};

void setup() {
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
}

void loop() {
button14.update();
button15.update();

for(int row=0; row<2; row++){
for(int col=0; col<1; col++){
array [row][col] = 0;}}

if (digitalRead(bankButton0) == LOW)

{row = 0;}

if (button14.fallingEdge()){
usbMIDI.sendNoteOn(10, 99, channel);}

else
if (digitalRead(bankButton1) == LOW)

{row = 1;}

if (button14.fallingEdge()){
usbMIDI.sendNoteOn(20, 99, channel);}

}

  for (int row = 0; row < 2; row++) {
    for (int col = 0; col < 1; col++) {
      array [row][col] = 0;
    }
  }

Why ?

Try this

const byte noteTable[2][3] = {{11, 22, 33}, {44, 55, 66}};
const byte bankPins[] = {3, 4};
const byte notePins[] = {5, 6, 7};
const byte numberOfBanks = sizeof(bankPins) / sizeof(bankPins[0]);
const byte numberOfNotes = sizeof(notePins) / sizeof(notePins[0]);

void setup()
{
  Serial.begin(115200);
  Serial.print(numberOfBanks);
  Serial.println(" banks");
  Serial.print(numberOfNotes);
  Serial.println(" notes each");

  for (int bank = 0; bank < numberOfBanks; bank++)
  {
    pinMode(bankPins[bank], INPUT_PULLUP);
  }
  for (int note = 0; note < numberOfNotes; note++)
  {
    pinMode(notePins[note], INPUT_PULLUP);
  }
}

void loop()
{
  byte selectedBank = chooseBank();  //select the bank of notes, if any, to be used
  if (selectedBank != 99)  //if a bank was selected
  {
    byte selectedNote = chooseNote();  //select the note to be used, if any
    if (selectedNote != 99)  //if a note was selected
    {
      Serial.println(noteTable[selectedBank][selectedNote]);  //print the value for the note selected
    }
  }
}

byte chooseBank()
{
  for (int bank = 0; bank < numberOfBanks; bank++)  //read each bank pin
  {
    if (digitalRead(bankPins[bank]) == LOW)  //found one pressed
    {
      return bank;    //return index to pressed button
    }
  }
  return 99;      //return 99 if no button found pressed
}

byte chooseNote()
{
  for (int note = 0; note < numberOfNotes; note++)  //read each note pin
  {
    if (digitalRead(notePins[note]) == LOW)
    {
      return note;    //return index to pressed button
    }
  }
  return 99;      //return 99 if no button found pressed
}

It uses 5 buttons. 2 to choose the bank and 3 to choose the note from the bank
The buttons in my test are wired to take the input LOW when pressed

this is making more since now and I'm sure i need to add a few things to it to make it work with what I'm trying to do. this code will upload but its not sending out anything from the project and i think its because of a couple things.. the buttons i am using are momentary buttons, I've only ever seen them work with the fallingEdge function which may just be my lack of experience with writing code.

A. how does the program know to send the notes as usbMIDI?

B. how does it know what channel to send the notes on?

C. if my statement about the fallingEdge function is correct, how would i switch the digitalRead to fallingEdge and declare the fallingEdge function?

this is the "few things" i was referring to. lol.

A. how does the program know to send the notes as usbMIDI?

My sample prints the note values that I put in the array as examples. They are not real note values.
You replace my example note values with real values and where I print the notes send them via the MIDI interface

B. how does it know what channel to send the notes on?

I know nothing about MIDI so cannot answer your question
Presumably you use something like

usbMIDI.sendNoteOn(10, 99, channel);

But I don’t know what the parameters to the function are. Do you ?
I could look it up but you already use the function in your program so I assume that you know what they are.

C. if my statement about the fallingEdge function is correct, how would i switch the digitalRead to fallingEdge and declare the fallingEdge function?

Presumable fallingEdge is part of the Bounce library which I know nothing about, but you use it in your code. From its name it sounds like it detects when a pin goes LOW.

I deliberately kept my program simple as it was meant as an example of how to select a bank of notes and a note from the selected bank, not a full on program to send notes to a MIDI interface.

awesome! this helps me a lot and i really do appreciate the help. i wasn't sure if sketch you posted was just a sample or a simpler version of what i am trying to accomplish and i started messing around with it and wasn't sure. this gives me a lot more stuff to research and study, which is clearly what i am in need of.

thanks again.

The example program selects which bank to use out the the 2 available by reading individual buttons for each bank. What I suspect you want in reality is to use one button to move up a bank and the other to move down a bank. Is that right ?

yes that is correct.

This version allows you to move up/down between banks using 2 buttons

const byte noteTable[2][3] = {{11, 22, 33}, {44, 55, 66}};
const byte decBank = 3;
const byte incBank = 4;
byte curIncBankState;
byte curDecBankState;
byte prevIncBankState;
byte prevDecBankState;
int selectedBank = 0;

const byte notePins[] = {5, 6, 7};
const byte numberOfBanks = 2;
const byte numberOfNotes = sizeof(notePins) / sizeof(notePins[0]);

void setup()
{
  Serial.begin(115200);
  Serial.print(numberOfBanks);
  Serial.println(" banks");
  Serial.print(numberOfNotes);
  Serial.println(" notes each");
  Serial.print("Using bank ");
  Serial.println(selectedBank);

  pinMode(incBank, INPUT_PULLUP);
  pinMode(decBank, INPUT_PULLUP);

  for (int note = 0; note < numberOfNotes; note++)
  {
    pinMode(notePins[note], INPUT_PULLUP);
  }
}

void loop()
{
  checkForBankChange();
  byte selectedNote = chooseNote();  //select the note to be used, if any
  if (selectedNote != 99)  //if a note was selected
  {
    Serial.println(noteTable[selectedBank][selectedNote]);  //print the value for the note selected
  }
}

byte chooseNote()
{
  for (int note = 0; note < numberOfNotes; note++)  //read each note pin
  {
    if (digitalRead(notePins[note]) == LOW)
    {
      return note;    //return index to pressed button
    }
  }
  return 99;      //return 99 if no button found pressed
}

void checkForBankChange()
{
  prevIncBankState = curIncBankState;
  curIncBankState = digitalRead(incBank);
  if (curIncBankState != prevIncBankState && curIncBankState == LOW)  //increment button became pressed
  {
    selectedBank++;
    if (selectedBank >= numberOfBanks)
    {
      selectedBank = numberOfBanks - 1;
    }
    Serial.print("Now using bank ");
    Serial.println(selectedBank);
  }

  prevDecBankState = curDecBankState;
  curDecBankState = digitalRead(decBank);
  if (curDecBankState != prevDecBankState && curDecBankState == LOW)  //decrement button became pressed
  {
    selectedBank--;
    if (selectedBank < 0)
    {
      selectedBank = 0;
    }
    Serial.print("Now using bank ");
    Serial.println(selectedBank);
  }
}

The detection of the bank buttons becoming LOW could presumably be done with the Bounce library fallingEdge method.