Can someone help with Arduino Keyboard Octave code?

Hey crew!
I’m just a noob who happened upon a few Arduino videos and some Organ foot pedals.

I dont have any Arduino knowledge but I found a kind of template from Notes and Volts from their Arduino MIDI Controller series on Youtube

I got some bread board set up to test it out.
Not tested with code from the ‘template’ yet but thought I’d ask on here about putting 2 Octave foot buttons on.
One for minus Octave and one for plus Octave.
By this I mean, you press not hold a button and midi goes up or down an octave with each press, and stays untill you press another to change octaves. (Hope that made sense?!)
That way you can play bass notes or lead notes.

At the moment I have an Arduino Uno wired up like this. I plan to use it with a Arturia Microfreak.
Pin 2: Button C, Midi note number 60
Pin 3: Button C#, Midi note number 61
Pin 4: Button D, Midi note number 62
Pin 5: Button D#, Midi note number 63
Pin 6: Button E, Midi note number 64
Pin 7: Button F, Midi note number 65
Pin 8: Button F#, Midi note number 66
Pin 9: Button G, Midi note number 67
Pin 10: Button G#, Midi note number 68
Pin 11: Button A, Midi note number 69
Pin 12: Button A#, Midi note number 70
Pin 13:

Analog Pins:
A0: Button B, Midi note number 71
A1: Button C, Midi note number 72
A2: Octave Down Button to shift the midi note numbers down 12 with each press
A3: Octave Up Button to shift the midi note numbers up 12 with each press
A4: Hold Footswitch CC72
A5: Expression Pedal input 1 to control CC#23 FilterCutoff

Note buttons shorting to ground. (Am i right saying its best not to use pin 13 because of the LED?).

Can someone help me with the Octave shift please?
The ‘template’ has 3 pages on the Arduino IDE NotesVolts.ino/Controller.cpp/Controller.h

Here is the .ino part which I’ve edited for my uses but haven’t put anything to do with the octave. Alot of it is just commented out, ive put some comments relating to what ive done.
Thankyou

#include <MIDI.h>
#include "Controller.h"

/*************************************************************
  MIDI CONTROLLER

  by Notes and Volts
  www.notesandvolts.com

  Version 1.2 **Arduino UNO ONLY!**
 *************************************************************/

MIDI_CREATE_DEFAULT_INSTANCE();

//************************************************************
//***SET THE NUMBER OF CONTROLS USED**************************
//************************************************************
//---How many buttons are connected directly to pins?---------
byte NUMBER_BUTTONS = 14;
//---How many potentiometers are connected directly to pins?--
byte NUMBER_POTS = 1;
//---How many buttons are connected to a multiplexer?---------
byte NUMBER_MUX_BUTTONS = 0;
//---How many potentiometers are connected to a multiplexer?--
byte NUMBER_MUX_POTS = 0;
//************************************************************

//***ANY MULTIPLEXERS? (74HC4067)************************************
//MUX address pins must be connected to Arduino UNO pins 2,3,4,5
//A0 = PIN2, A1 = PIN3, A2 = PIN4, A3 = PIN5
//*******************************************************************
//Mux NAME (OUTPUT PIN, , How Many Mux Pins?(8 or 16) , Is It Analog?);


//Mux M1(10, 16, false); //Digital multiplexer on Arduino pin 10
//Mux M2(A5, 8, true); //Analog multiplexer on Arduino analog pin A0
//*******************************************************************


//***DEFINE DIRECTLY CONNECTED POTENTIOMETERS************************
//Pot (Pin Number, Command, CC Control, Channel Number)
//**Command parameter is for future use**
// Microfreak CC23Filter 
Pot PO1(A5, 0, 23, 1);
//Pot PO2(A1, 0, 10, 1);
//Pot PO3(A2, 0, 22, 1);
//Pot PO4(A3, 0, 118, 1);
//Pot PO5(A4, 0, 30, 1);
//Pot PO6(A5, 0, 31, 1);
//*******************************************************************
//Add pots used to array below like this->  Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6};
Pot *POTS[] {&PO1};
//*******************************************************************


//***DEFINE DIRECTLY CONNECTED BUTTONS*******************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
//** Command parameter 0=NOTE  1=CC  2=Toggle CC **

Button BU1(2, 0, 60, 1, 5 );
Button BU2(3, 0, 61, 1, 5 );
Button BU3(4, 0, 62, 1, 5 );
Button BU4(5, 0, 63, 1, 5 );
Button BU5(6, 0, 64, 1, 5 );
Button BU6(7, 0, 65, 1, 5 );
Button BU7(8, 0, 66, 1, 5 );
Button BU8(9, 0, 67, 1, 5 );
Button BU9(10, 0, 68, 1, 5 );
Button BU10(11, 0, 69, 1, 5 );
Button BU11(12, 0, 70, 1, 5 );
Button BU12(A0, 0, 71, 1, 5 );
Button BU13(A1, 0, 72, 1, 5 );
// cc72 is Microfreak Hold button
Button SUS(A4, 1, 72, 1, 5 );
//Button BU13(15, 0, 72, 1, 5 );
//*******************************************************************
//Add buttons used to array below like this->  Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8};
Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU3, &BU4, &BU4, &BU5, &BU6, &BU7, &BU8, &BU8, &BU9, &BU10, &BU11, &BU12, &BU13, &SUS};
//*******************************************************************


//***DEFINE BUTTONS CONNECTED TO MULTIPLEXER*************************
//Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
//** Command parameter 0=NOTE  1=CC  2=Toggle CC **

//Button MBU1(M1, 0, 0, 70, 1, 5);
//Button MBU2(M1, 1, 1, 71, 1, 5);
//Button MBU3(M1, 2, 2, 72, 1, 5);
//Button MBU4(M1, 3, 0, 73, 1, 5);
//Button MBU5(M1, 4, 0, 74, 1, 5);
//Button MBU6(M1, 5, 0, 75, 1, 5);
//Button MBU7(M1, 6, 0, 76, 1, 5);
//Button MBU8(M1, 7, 0, 77, 1, 5);
//Button MBU9(M1, 8, 0, 78, 1, 5);
//Button MBU10(M1, 9, 0, 79, 1, 5);
//Button MBU11(M1, 10, 0, 80, 1, 5);
//Button MBU12(M1, 11, 0, 81, 1, 5);
//Button MBU13(M1, 12, 0, 82, 1, 5);
//Button MBU14(M1, 13, 0, 83, 1, 5);
//Button MBU15(M1, 14, 0, 84, 1, 5);
//Button MBU16(M1, 15, 0, 85, 1, 5);
//*******************************************************************
////Add multiplexed buttons used to array below like this->  Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
Button *MUXBUTTONS[] {};

//*******************************************************************


//***DEFINE POTENTIOMETERS CONNECTED TO MULTIPLEXER*******************
//Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
//**Command parameter is for future use**

//Pot MPO1(M2, 0, 0, 1, 1);
//Pot MPO2(M2, 1, 0, 7, 1);
//Pot MPO3(M2, 2, 0, 50, 1);
//Pot MPO4(M2, 3, 0, 55, 2);
//Pot MPO5(M2, 4, 0, 50, 1);
//Pot MPO6(M2, 5, 0, 55, 2);
//Pot MPO7(M2, 6, 0, 50, 1);
//Pot MPO8(M2, 7, 0, 55, 2);
//Pot MPO9(M2, 8, 0, 50, 1);
//Pot MPO10(M2, 9, 0, 55, 2);
//Pot MPO11(M2, 10, 0, 50, 1);
//Pot MPO12(M2, 11, 0, 55, 2);
//Pot MPO13(M2, 12, 0, 50, 1);
//Pot MPO14(M2, 13, 0, 55, 2);
//Pot MPO15(M2, 14, 0, 50, 1);
//Pot MPO16(M2, 15, 0, 55, 2);
//*******************************************************************
//Add multiplexed pots used to array below like this->  Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
Pot *MUXPOTS[] {};
//*******************************************************************


void setup() {
  MIDI.begin(MIDI_CHANNEL_OFF);
}

void loop() {
  if (NUMBER_BUTTONS != 0) updateButtons();
  if (NUMBER_POTS != 0) updatePots();
  if (NUMBER_MUX_BUTTONS != 0) updateMuxButtons();
  if (NUMBER_MUX_POTS != 0) updateMuxPots();
}


//*****************************************************************
void updateButtons() {

  // Cycle through Button array
  for (int i = 0; i < NUMBER_BUTTONS; i = i + 1) {
    byte message = BUTTONS[i]->getValue();

    //  Button is pressed
    if (message == 0) {
      switch (BUTTONS[i]->Bcommand) {
        case 0: //Note
          MIDI.sendNoteOn(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
          break;
        case 1: //CC
          MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
          break;
        case 2: //Toggle
          if (BUTTONS[i]->Btoggle == 0) {
            MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
            BUTTONS[i]->Btoggle = 1;
          }
          else if (BUTTONS[i]->Btoggle == 1) {
            MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
            BUTTONS[i]->Btoggle = 0;
          }
          break;
      }
    }

    //  Button is not pressed
    if (message == 1) {
      switch (BUTTONS[i]->Bcommand) {
        case 0:
          MIDI.sendNoteOff(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
          break;
        case 1:
          MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
          break;
      }
    }
  }
}
//*******************************************************************
void updateMuxButtons() {

  // Cycle through Mux Button array
  for (int i = 0; i < NUMBER_MUX_BUTTONS; i = i + 1) {

    MUXBUTTONS[i]->muxUpdate();
    byte message = MUXBUTTONS[i]->getValue();

    //  Button is pressed
    if (message == 0) {
      switch (MUXBUTTONS[i]->Bcommand) {
        case 0: //Note
          MIDI.sendNoteOn(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
          break;
        case 1: //CC
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
          break;
        case 2: //Toggle
          if (MUXBUTTONS[i]->Btoggle == 0) {
            MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
            MUXBUTTONS[i]->Btoggle = 1;
          }
          else if (MUXBUTTONS[i]->Btoggle == 1) {
            MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
            MUXBUTTONS[i]->Btoggle = 0;
          }
          break;
      }
    }
    //  Button is not pressed
    if (message == 1) {
      switch (MUXBUTTONS[i]->Bcommand) {
        case 0:
          MIDI.sendNoteOff(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
          break;
        case 1:
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
          break;
      }
    }
  }
}
//***********************************************************************
void updatePots() {
  for (int i = 0; i < NUMBER_POTS; i = i + 1) {
    byte potmessage = POTS[i]->getValue();
    if (potmessage != 255) MIDI.sendControlChange(POTS[i]->Pcontrol, potmessage, POTS[i]->Pchannel);
  }
}
//***********************************************************************
void updateMuxPots() {
  for (int i = 0; i < NUMBER_MUX_POTS; i = i + 1) {
    MUXPOTS[i]->muxUpdate();
    byte potmessage = MUXPOTS[i]->getValue();
    if (potmessage != 255) MIDI.sendControlChange(MUXPOTS[i]->Pcontrol, potmessage, MUXPOTS[i]->Pchannel);
  }
}

1: if you connect a button or switch to an arduino, you have to be aware that (allmost) all switches bounce when pressed. They do not close a contact at once, often the contacts connect and disconnect repeatedly over a short time (few milliseconds) before getting to their final position. You will have to deal with this otherwise multiple notes might get fired when pressing just one key.

You can read some more about debouncing here.

2: remove all the other not relevant or code that is not used (save it to some text file so you can put pieces of it back later), but it it best not to keep it in there when asking questions. E.g. have you added the 74HC4067 mux to your circuit? No, then remove all code relating to the MUX from the program. This makes it less confusing to read.

3: For the octave shift what I did in a recent project, is that I have a variable that I increment or decrement depending on the switch pressed (after debouncing).
So when octave up / down is pressed I go:

if (octaveUpPressed == LOW) {
   currentOctave += 1;
   if (currentOctave > 10) currentOctave = 10;
}
if (octaveDownPressed == LOW) {
   currentOctate -= 1;
   if (currentOctave < 0) currentOctave = 0;
}

I’ve used LOW here because in your question you said all buttons will switch to GND. Make sure to define all inputs with PULL UP resistors then!

Note the value of currentOctave is limited to [0, 10] here. Choose what makes sense to you.

Let’s assume that the variable note contains the note value that is pressed and that its value can range from 0 … 11 (C,C#, …A, A#, B). I then calculate the actual pitch like so (and play it using some subroutine):

int actualPitch = note + 12 * currentOctave;
playMidi(actualPitch);

Hope this helps.