Yet another midi controller

It has been a while since I build something and it seems Im a little rusty.
I want to make a new midi foot controller. I managed to build one with an arduino mega but now i want to build one with a pro micro. That has native usb.
I have made a foot controller with nine buttons. 8 of those buttons send midi messages. NoteOn an NoteOff, from c4 to c5. I used the code from MIDI_controller/Ex.02.Button.ino at master · tttapa/MIDI_controller · GitHub

/*
This is an example of the "Digital" class of the MIDI_controller library.
Connect a push buttons to digital pin 2. Connect the other pin of the button to the ground, 
a pull-up resistor is not necessary, because the internal one will be used. 
This button will play MIDI note C4 when pressed.
Map it in your DAW or DJ software.
Written by tttapa, 08/09/2017
https://github.com/tttapa/MIDI_controller
*/

#include <MIDI_Controller.h> // Include the library

const uint8_t velocity = 0b1111111; // Maximum velocity (0b1111111 = 0x7F = 127)
const uint8_t c4 = 60;              // Note number 60 is defined as middle C in the MIDI specification
const uint8_t d4 = 62;
const uint8_t e4 = 64;
const uint8_t f4 = 65;
const uint8_t g4 = 67;
const uint8_t a4 = 69;
const uint8_t b4 = 70;
const uint8_t c5 = 72;


// Create a new instance of the class 'Digital', called 'button', on pin 2, that sends MIDI messages with note 'C4' (60) on channel 1, with velocity 127
Digital button(2, c4, 1, velocity);
Digital button(3, d4, 1, velocity);
Digital button(4, e4, 1, velocity);
Digital button(5, f4, 1, velocity);
Digital button(6, g4, 1, velocity);
Digital button(7, a4, 1, velocity);
Digital button(8, b4, 1, velocity);
Digital button(9, c5, 1, velocity);


void setup() {}

void loop() {
  // Refresh the button (check whether the button's state has changed since last time, if so, send it over MIDI)
  MIDI_Controller.refresh();
}

So that was easy. But i would like my ninth button to act like a channel changer. So when i press button 9. The other buttons 1-8 choose the channel and then after i choose it returns to the first mode in which i can play the notes in a different channel.

How would i do that?

You could try something like this:

#include <Control_Surface.h>

USBMIDI_Interface midi;

// 8 different banks to select the 8 different channels
Bank<8> bank;

// Selector to select the active bank
ManyButtonsSelector<8> selector = {
  bank,
  {2, 3, 4, 5, 6, 7, 8, 9}, // button pins
};

using namespace MIDI_Notes;

// 8 buttons that send MIDI note events
Bankable::NoteButton noteButtons[] = {
  {{bank, BankType::CHANGE_CHANNEL}, 2, note(C, 4)}, // bank config, button pin, address
  {{bank, BankType::CHANGE_CHANNEL}, 3, note(D, 4)},
  {{bank, BankType::CHANGE_CHANNEL}, 4, note(E, 4)},
  {{bank, BankType::CHANGE_CHANNEL}, 5, note(F, 4)},
  {{bank, BankType::CHANGE_CHANNEL}, 6, note(G, 4)},
  {{bank, BankType::CHANGE_CHANNEL}, 7, note(A, 4)},
  {{bank, BankType::CHANGE_CHANNEL}, 8, note(B, 4)},
  {{bank, BankType::CHANGE_CHANNEL}, 9, note(C, 5)},
};

// A button to enable channel selection
Button channelSelectButton = 10; // button pin

void setup() {
  Control_Surface.begin();
  selector.disable();
  channelSelectButton.begin();
}

void loop() {
  Control_Surface.loop();
  
  // Read the button on pin 10
  channelSelectButton.update();
  if (channelSelectButton.getState() == Button::Falling) {
    // if pressed, disable the note buttons, 
    // and enable the channel selector
    for (auto &button : noteButtons)
      button.disable();
    selector.enable();
  } else if (channelSelectButton.getState() == Button::Rising) {
    // if released, enable the note buttons, 
    // and disable the channel selector
    selector.disable();
    for (auto &button : noteButtons)
      button.enable();
  }
}

Pieter

That works perfectly. I don't know how... yet. This is all new to me.
But thank you!

Is it possible to change the code so that after i press the channelselect button that it waits till i make a choice? I want to operate it with one foot.

I have been searching for a bit and tried another libary. I didnt really understand the former code. I have made aworking code for an 8 button midi note foot controller with a shift button to change the channel and wanted to share it. So here it is

#include "MIDIUSB.h"

byte notes[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
byte maj[8] = {0, 2, 4, 5, 7, 9, 11, 12};
boolean noteAan[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
boolean noteLast[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
byte mode = 0;
boolean shiftOn = 1;
boolean shiftOnLast = 1;
int NoteAanLast = 0x90;
int NoteUitLast = 0x80;
int basenote = 0x30;
byte noteCount = 8;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;

void setup()
{

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);



}




void loop() {


  shiftOn = digitalRead(notes[8]);

  if ((shiftOn != shiftOnLast) && ((millis() - lastDebounceTime) > debounceDelay)) {

    if (shiftOn == LOW) {
      if (mode == 0) {
        mode = 1;
        previousMillis = currentMillis;
      }
      else if (mode == 1) {
        mode = 2;
        previousMillis = currentMillis;
      }

      shiftOnLast = shiftOn;
      lastDebounceTime = millis();
    }


    else if (shiftOn == HIGH) {
      shiftOnLast = shiftOn;
      lastDebounceTime = millis();
    }


  }












  if ( mode  == 0) {



    for (char n = 0; n < noteCount; n++) {
      noteAan[n] = digitalRead(notes[n]);

      if ((noteLast[n] != noteAan[n]) && ((millis() - lastDebounceTime) > debounceDelay)) {

        if (noteAan[n] == LOW) {
          midiEventPacket_t noteOn = {0x09, NoteAanLast , (basenote + maj[n]), 100};
          MidiUSB.sendMIDI(noteOn);
          MidiUSB.flush();
          noteLast[n] = noteAan[n];
          lastDebounceTime = millis();

        }



        else if (noteAan[n] == HIGH) {
          midiEventPacket_t noteOff = {0x09, NoteAanLast , (basenote + maj[n]), 0};
          MidiUSB.sendMIDI(noteOff);
          MidiUSB.flush();
          noteLast[n] = noteAan[n];
          lastDebounceTime = millis();
        }
      }
    }





  }//end if ( mode  == 0)





  else if ( mode  == 1) {

    for (char p = 0; p < noteCount; p++) {


      noteAan[p] = digitalRead(notes[p]);
      if ((noteLast[p] != noteAan[p]) && ((millis() - lastDebounceTime) > debounceDelay)) {
        if (noteAan[p] == LOW) {
          NoteAanLast = (0x90 + p);
          NoteUitLast = (0x80 + p);
          lastDebounceTime = millis();
          noteLast[p] = noteAan[p];
        }

        if (noteAan[p] == HIGH) {
          noteLast[p] = noteAan[p];
          mode = 0;
          lastDebounceTime = millis();
          previousMillis = currentMillis;
        }
      }
    }
  }

}