MIDI controller (Arduino UNO) multiple paramenters

No it compiles for me, you've made mistakes. My files now look like this :

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

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

  by Notes and Volts
  www.notesandvolts.com

  Version 1.2 
 *************************************************************
  WALDORF PULSE Controller edition by Konstantin Jagoulis 2021
 *************************************************************/

MIDI_CREATE_DEFAULT_INSTANCE();

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

//***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(A0, 16, true); //Analog multiplexer on Arduino analog pin A0
Mux M3(A1, 16, true); //Analog multiplexer on Arduino analog pin A1
Mux M4(A2, 16, true); //Analog multiplexer on Arduino analog pin A2
//*******************************************************************


//***DEFINE DIRECTLY CONNECTED POTENTIOMETERS************************
//Pot (Pin Number, Command, CC Control, Channel Number)
//**Command parameter is for future use**

//Pot PO1(A0, 0, 1, 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[] {};
//*******************************************************************


//***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, 1, 64, 1, 5 );
//Button BU8(9, 2, 64, 1, 5 );
//*******************************************************************
//Add buttons used to array below like this->  Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8};
Button *BUTTONS[] {};
//*******************************************************************


//***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  5=Toggle CC **

Button MBU4(M1, 3, 4, 32, 1, 5);    //2"                        yes
Button MBU3(M1, 2, 3, 32, 1, 5);    //4"                        yes
Button MBU2(M1, 1, 2, 32, 1, 5);    //8"                        yes
Button MBU1(M1, 0, 6, 32, 1, 5);    //16"                       yes

Button MBU8(M1, 7, 5, 40, 1, 5);    //Key Track                 yes
Button MBU7(M1, 6, 3, 36, 1, 5);    //4"                        yes
Button MBU6(M1, 5, 2, 36, 1, 5);    //8"                        yes
Button MBU5(M1, 4, 6, 36, 1, 5);    //16"                       yes

Button MBU9(M1, 8, 5, 41, 1, 5);    //Sync On/Off               yes

//*******************************************************************
////Add multiplexed buttons used to array below like this->  Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6, &MBU7, &MBU8, &MBU9};
//*******************************************************************


//***DEFINE POTENTIOMETERS CONNECTED TO MULTIPLEXER*******************
//Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
//**Command parameter is for future use**
//MULTIPLEXER 2 (1-15)
//LFO
Pot MPO1(M2, 3, 0, 25, 1, 0, 127);       //Shape 1       (0-7)         
Pot MPO2(M2, 2, 0, 24, 1, 0, 127);       //Speed 1                     
Pot MPO3(M2, 1, 0, 27, 1, 0, 127);       //Delay 2                     
Pot MPO4(M2, 0, 0, 26, 1, 0, 127);       //Speed 2                           
//OSC 1
Pot MPO5(M2, 7, 0, 34, 1, 0, 127);       //Shape 1       (0-2)         
Pot MPO6(M2, 6, 0, 32, 1, 0, 127);       //Semitone 1    (16-112)      
Pot MPO7(M2, 5, 0, 33, 1, 0, 127);       //Tune 1                      
Pot MPO8(M2, 4, 0, 35, 1, 0, 127);       //Pulse Width 1               
//OSC 2
Pot MPO9(M2, 11, 0, 38, 1, 0, 127);      //Shape 2       (0-3)         
Pot MPO10(M2, 10, 0, 36, 1, 0, 127);     //Semitone 2    (16-112)      
Pot MPO11(M2, 9, 0, 37, 1, 0, 127);      //Tune 2                      
Pot MPO12(M2, 8, 0, 39, 1, 0, 127);      //Pulse Width 2                     
//OSC 3
Pot MPO13(M2, 14, 0, 44, 1, 0, 127);     //Shape 3       (0-2)         
Pot MPO14(M2, 13, 0, 42, 1, 0, 127);     //Semitone 3    (16-112)      
Pot MPO15(M2, 12, 0, 43, 1, 0, 127);     //Tune 3                      

//MULTIPLEXER 3 (1-16)
//MIX
Pot MPO16(M3, 3, 0, 45, 1, 0, 127);      //OSC 1                       
Pot MPO17(M3, 2, 0, 46, 1, 0, 127);      //OSC 2                       
Pot MPO18(M3, 1, 0, 47, 1, 0, 127);      //OSC 3                       
Pot MPO19(M3, 0, 0, 48, 1, 0, 127);      //NOISE                       
//FILTER
Pot MPO20(M3, 7, 0, 52, 1, 0, 127);      //Envelope 1                  
Pot MPO21(M3, 6, 0, 53, 1, 0, 127);      //Velocity                    
Pot MPO22(M3, 5, 0, 56, 1, 0, 127);      //Resonance                   
Pot MPO23(M3, 4, 0, 50, 107, 0, 127);    //Cutoff                            
//ADSR 1
Pot MPO24(M3, 11, 0, 14, 1, 0, 127);     //A 1                         
Pot MPO25(M3, 10, 0, 15, 1, 0, 127);     //D 1                         
Pot MPO26(M3, 9, 0, 16, 1, 0, 127);      //S 1                         
Pot MPO27(M3, 8, 0, 17, 1, 0, 127);      //R 1                               
//ADSR 2
Pot MPO28(M3, 15, 0, 18, 1, 0, 127);     //A 2                         
Pot MPO29(M3, 14, 0, 19, 1, 0, 127);     //D 2                         
Pot MPO30(M3, 13, 0, 20, 1, 0, 127);     //S 2                               
Pot MPO31(M3, 12, 0, 21, 1, 0, 127);     //R 2                         

//MULTIPLEXER 4 (1-16)
//MOD
Pot MPO32(M4, 3, 0, 54, 1, 0, 127);      //Cutoff Source  (0-15)       
Pot MPO33(M4, 2, 0, 55, 1, 0, 127);      //Cutoff Amount               
Pot MPO34(M4, 1, 0, 60, 108, 0, 127);    //Pitch Source   (0-15)             
Pot MPO35(M4, 0, 0, 61, 1, 0, 127);      //Pitch Amount                
//MATRIX MOD AMMOUNT
Pot MPO36(M4, 7, 0, 109, 1, 0, 127);     //1                           
Pot MPO37(M4, 6, 0, 112, 1, 0, 127);     //2                           
Pot MPO38(M4, 5, 0, 115, 1, 0, 127);     //3                           
Pot MPO39(M4, 4, 0, 118, 1, 0, 127);     //4                           
//ARPEGGIO
Pot MPO40(M4, 11, 0, 102, 1, 0, 127);    //ON, OFF, HOLD  (0-2)        
Pot MPO41(M4, 10, 0, 105, 1, 0, 127);    //Tempo                       
Pot MPO42(M4, 9, 0, 103, 1, 0, 127);     //Range          (0-9)        
Pot MPO43(M4, 8, 0, 106, 1, 0, 127);     //Mode           (0-6)        
//VOLUME
Pot MPO44(M4, 15, 0, 57, 1, 0, 127);     //Volume                      
Pot MPO45(M4, 14, 0, 58, 1, 0, 127);     //Velocity                    
Pot MPO46(M4, 13, 0, 5, 1, 0, 127);      //Portamento Time             
Pot MPO47(M4, 12, 0, 63, 1, 0, 127);     //Bend Range     (0-24)       
//*******************************************************************
//Add multiplexed pots used to array below like this->  Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6, &MPO7, &MPO8, &MPO9, &MPO10, &MPO11, &MPO12, &MPO13, &MPO14, &MPO15, &MPO16, &MPO17, &MPO18, &MPO19, &MPO20, &MPO21, &MPO22, &MPO23, &MPO24, &MPO25, &MPO26, &MPO27, &MPO28, &MPO29, &MPO30, &MPO31, &MPO32, &MPO33, &MPO34, &MPO35, &MPO36, &MPO37, &MPO38, &MPO39, &MPO40, &MPO41, &MPO42, &MPO43, &MPO44, &MPO45, &MPO46, &MPO47};
//*******************************************************************


void setup() {
  Serial.begin(9600); //9600 bits per second serial data output
  MIDI.begin(MIDI_CHANNEL_OMNI);
}

void loop() {
  MIDI.read();
  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 6: //CC 16"
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 36, MUXBUTTONS[i]->Bchannel);
          break;
        case 2: //CC 8"
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 48, MUXBUTTONS[i]->Bchannel);
          break;
        case 3: //CC 4"
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 60, MUXBUTTONS[i]->Bchannel);
          break;
        case 4: //CC 2"
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 72, MUXBUTTONS[i]->Bchannel);
          break;          
        case 5: //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);
    
  }
}

Controller.cpp :

#include "Controller.h"

//****************************************************************************************
Mux::Mux(byte outpin_, byte numPins_, bool analog_)
{
  outpin = outpin_;
  //enablepin = enablepin_;
  numPins = numPins_;
  analog = analog_;
  if (analog == false) pinMode(outpin, INPUT_PULLUP);
  //pinMode(enablepin, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  if (numPins > 8) pinMode(5, OUTPUT);
}
//****************************************************************************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
Button::Button(byte pin, byte command, byte value, byte channel, byte debounce)
{
  _pin = pin;
  pinMode(_pin, INPUT_PULLUP);
  _value = value;
  _command = command;
  _debounce = debounce;
  _time = 0;
  _busy = false;
  _status = 0b00000010;
  _last = 1;
  Bcommand = command;
  Bvalue = value;
  Bchannel = channel;
  Btoggle = 0;
}

Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
{
  _pin = mux.outpin;
  _numMuxPins = mux.numPins;
  _muxpin = muxpin;
  _value = value;
  _command = command;
  _debounce = debounce;
  _time = 0;
  _busy = false;
  _status = 0b00000010;
  _last = 1;
  Bcommand = command;
  Bvalue = value;
  Bchannel = channel;
  Btoggle = 0;
}

void Button::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  PORTD = PORTD | temp;
}

byte Button::getValue()
{
  // If BUSY bit not set - read button
  if (bitRead(_status, 0) == false) { // If busy false
    if (digitalRead(_pin) == _last) return 2; // If same as last state - exit
  }

  // If NEW Bit set - Key just pressed, record time
  if (bitRead(_status, 1) == true) { // If new is true
    bitSet(_status, 0); // Set busy TRUE
    bitClear(_status, 1); // Set New FALSE
    _time = millis();
    return 255;
  }

  // Check if debounce time has passed - If no, exit
  if (millis() - _time < _debounce) return 255;

  // Debounce time has passed. Read pin to see if still set the same
  // If it has changed back - assume false alarm
  if (digitalRead(_pin) == _last) {
    bitClear(_status, 0); // Set busy false
    bitSet(_status, 1); // Set new true
    return 255;
  }

  // If this point is reached, event is valid. return event type
  else {
    bitClear(_status, 0); // Set busy false
    bitSet(_status, 1); // Set new true
    _last = ((~_last) & 0b00000001); // invert _last
    return _last;
  }
}

void Button::newValue(byte command, byte value, byte channel)
{
  Bvalue = value;
  Bcommand = command;
  Bchannel = channel;
}

//********************************************************************
Pot::Pot(byte pin, byte command, byte control, byte channel, byte min, byte max)
{
  _min = min;
  _max = max;
  _pin = pin;
  _control = control;
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

void Pot::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  //PORTD = PORTD & B11000011;
  PORTD = PORTD | temp;
}

Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel, byte min, byte max)
{
  _min = min;
  _max = max;
  _pin = mux.outpin;
  _numMuxPins = mux.numPins;
  _muxpin = muxpin;
  _control = control;
  muxUpdate();
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

byte Pot::getValue()
{
  _value = analogRead(_pin);
  int tmp = (_oldValue - _value);
  if (tmp >= 8 || tmp <= -8) {
    _oldValue = _value >> 3;
    _oldValue = _oldValue << 3;
    return map( _value >> 3, 0, 127, _min, _max);;
  }
  return 255;
}

void Pot::newValue(byte command, byte value, byte channel) {
  Pcommand = command;
  Pcontrol = value;
  Pchannel = channel;
}

Controller.h :

#ifndef Controller_h
#define Controller_h

#include <Arduino.h>

//***********************************************************************
class Mux
{
  public:
    Mux(byte outpin_, byte numPins_, bool analog_);
    byte outpin;
    byte numPins;
    bool analog;
};
//************************************************************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
class Button
{
  public:
    Button(byte pin, byte command, byte value, byte channel, byte debounce);
    Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);
    byte getValue();
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte Bcommand;
    byte Bvalue;
    byte Bchannel;
    byte Btoggle;

  private:
    byte _previous;
    byte _current;
    unsigned long _time;
    int _debounce;
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _value;
    byte _command;
    bool _busy;
    byte _status;
    byte _last;
    byte _enablepin;
};
//*************************************************************************
class Pot
{
  public:
    Pot(byte pin, byte command, byte control, byte channel, byte min, byte max);
    Pot(Mux mux, byte muxpin ,byte command, byte control, byte channel, byte min, byte max);
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte getValue();
    byte Pcommand;
    byte Pcontrol;
    byte Pchannel;

  private:
    byte _min;
    byte _max;
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _control;
    int _value;
    int _oldValue;
    bool _changed;
    byte _enablepin;
};
//*************************************************************************
#endif
1 Like