MIDI controller- how to un multiplex?

Hey, the MIDI controller sketch below was written (by a long lost associate) to run on a diecimila, with 5 rotary encoders & 16 switches connected via an LS138 multiplexer (grouped as 'puff switches', 'knife switches', 'momentary click switches' & 'pir switch'), with piezo drumpads & 'lovehandles' skin resistance meter voltage going into analog ins.

I want to adapt it to run on a mega, plugging the switches etc straight into digital inputs on the arduino, dispensing with the multiplexer. I guess I need to remove the bank code & assign the inputs to digital ins? Also the multiplexer board was doing the de-bouncing. Any tips for a noob on how to do this would be much appreciated, many thanks, raymondo

int A = LOW;int B = LOW;int enclaststate[6]={LOW,LOW,LOW,LOW,LOW,LOW};int encoderflag[6]={LOW,LOW,LOW,LOW,LOW,LOW};
int cccurrentvalue[6]={0,0,0,0,0,0};int banknum;int encodercount[6]={0,0,0,0,0,0};int lovecheck = 0;
int switches[] = {LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW};
int lovehandles;int lovehandlesflag = LOW;int inputnum;int input;int piezopin;int drumvelocity;
int drumpad[5] = {53,54,55,56,57};int decay[5] = {0,0,0,0,0};int handlescount = 0;
void setup(){
Serial.begin(31250);DDRB = B00000000;PORTB = B00000000;DDRD = B00000000;PORTD = B00000001;}
// Port D - 0 is Rx, 1 is Tx, 7 4 & 2 are mux outs to ls138, Port B is 8 bank inputs / outputs
void loop(){//do our piezo drums , wired to the analog ins
for (piezopin=0;piezopin<=4;piezopin++){// setup the count to read the 5 drumpads
drumvelocity=analogRead(piezopin);if (drumvelocity/2>=25){
if(drumvelocity>=decay[piezopin]){midiCC(0x90,drumpad[piezopin],drumvelocity/2);delay(10);}decay[piezopin]=drumvelocity;delay(1);}}
lovehandles=analogRead(5);if (lovehandles>35){if (lovehandlesflag==LOW){midiCC(0x90,88,127);delay(1);midiCC(0x80,88,127);lovehandlesflag = HIGH;}
if((lovehandles/2)!=lovecheck){midiCC(0xB0,25,lovehandles/2);lovecheck=lovehandles/2;}}else{lovehandlesflag=LOW;}//read the lovehandles send controller and note on/off
// do our 8 banks multiplexed to the digital ins
for (banknum=7; banknum>=0; banknum--){ // set a loop of 8, 1 slot per bank
if (banknum==0){PORTD = B00000001;} // set the bank address, binary 000 outs
else if (banknum==1){PORTD = B00000101;}// set the bank address, binary 001 outs
else if (banknum==2){PORTD = B00010001;// set the bank address, binary 010 ins unused so far
//for(inputnum=8; inputnum<=13; inputnum++){swhandler(inputnum+12,inputnum-8);}
}
else if (banknum==3){PORTD = B00010101;// set the bank address, binary 011 puff switches and pir
for(inputnum=8; inputnum<=13; inputnum++){if(digitalRead(inputnum)==HIGH){midiCC(0x90,inputnum+20,127);delay(10);}}//!!!!!!!!!!put the delay in here
inputnum=6;input=(digitalRead(inputnum));// deal with pir switch, it's normally high going low
if((input==HIGH)&&(switches[6]==LOW)){midiCC(0x80,35,127);switches[6]=HIGH;}
// if a switch is pressed ON send a midi off, set the check value to ON
if((switches[6]==HIGH) && (input==LOW)) {midiCC(0x90,35,127);switches[6]=LOW;}}
else if (banknum==4){PORTD = B10000001;// set the bank address, binary 100 knife switches
for(inputnum=8; inputnum<=13; inputnum++){swhandler(inputnum+28,inputnum+8);}}
else if (banknum==5){PORTD = B10000101;// set the bank address, binary 101 momentary led click-switches
for(inputnum=8; inputnum<=13; inputnum++){swhandler(inputnum+36,inputnum+16);}}
else if (banknum==6){PORTD = B10010001;enchandler(13,4);enchandler(11,5);enchandler(9,75);}//encoders
else{PORTD = B10010101;enchandler(13,1);enchandler(11,2);enchandler(9,3);}}}//encoders
//delay(50); // stall to see the leds
/* function send a Midi message.use 'midiCC(command byte, data, data)' 0xB0 = controller, 0x80 = note on,
0x90 = note off data bytes 0-127 0x00-0x7f eg 0x80 0x34 0x0F note on, note 34, velocity 127*/
void midiCC(char CC_data, char c_num, char c_val){
Serial.print(CC_data, BYTE);Serial.print(c_num, BYTE);Serial.print(c_val, BYTE);}
// function to handle encoders / amend midi controllers
void enchandler(int y,int x){A=digitalRead(y);B=digitalRead(y-1);// fetch encoder states y is pin, x is array member / controller number
// check for movement, direction and midi controller range
if ((A==HIGH) && (enclaststate[x]==LOW)){encodercount[x]=0;if (encoderflag[x]==LOW){midiCC(0x90,x+12,127);delay(1);midiCC(0x80,x+12,127);encoderflag[x]=HIGH;}
//reset stationary count, deal with the start midi note and set flag
if(B == HIGH){if(cccurrentvalue[x]!= 127){cccurrentvalue[x]++;}}//positive move or negative move
else{if(cccurrentvalue[x]!= 0){cccurrentvalue[x]--;}}midiCC(0xB0,x,cccurrentvalue[x]);}//send the controller data
else{encodercount[x]++;if ((encodercount[x]==1000)&&(encoderflag[x]==HIGH)){midiCC(0x90,x+18,127);delay(1);midiCC(0x80,x+18,127);
encoderflag[x]=LOW;}}
enclaststate[x] = A;}// save the state for comparison n1ext time round
//function to read a switch and send a midi note on / off message
void swhandler(int note, int arraymember){input=(digitalRead(inputnum));// read the input pin
if((input==HIGH)&&(switches[arraymember]==LOW)){midiCC(0x90,note,127);delay(1);midiCC(0x80,note,127);switches[arraymember]=HIGH;}
// if a switch is pressed ON send a midi ON / off, set the check value to ON
if((switches[arraymember]==HIGH) && (input==LOW)) {midiCC(0x90,note+36,127);delay(1);midiCC(0x80,note+36,127);switches[arraymember]=LOW;}}
// if a switch is released send an on / OFF + 36, set the check value to OFF

One problem is that the author used Direct Port Access to set multiple output bits and the mapping between ports and pins is different on the Mega.

This spreadsheet shows the mappings between ports and pins:

Re-formatting makes the code easier to read:

int A = LOW;
int B = LOW;
int enclaststate[6]={LOW,LOW,LOW,LOW,LOW,LOW};
int encoderflag[6]={LOW,LOW,LOW,LOW,LOW,LOW};
int cccurrentvalue[6]={0,0,0,0,0,0};
int banknum;
int encodercount[6]={0,0,0,0,0,0};
int lovecheck = 0;
int switches[] = {LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW};
int lovehandles;
int lovehandlesflag = LOW;
int inputnum;
int input;
int piezopin;
int drumvelocity;
int drumpad[5] = {53,54,55,56,57};
int decay[5] = {0,0,0,0,0};
int handlescount = 0;

void setup(){
  Serial.begin(31250);
  DDRB = B00000000;
  PORTB = B00000000;
  DDRD = B00000000;
  PORTD = B00000001;
}

// Port D - 0 is Rx, 1 is Tx, 7 4 & 2 are mux outs to ls138, Port B is 8 bank inputs / outputs
void loop(){//do our piezo drums , wired to the analog ins
  for (piezopin=0;piezopin<=4;piezopin++){// setup the count to read the 5 drumpads
    drumvelocity=analogRead(piezopin);
    if (drumvelocity/2>=25){
      if(drumvelocity>=decay[piezopin]){
        midiCC(0x90,drumpad[piezopin],drumvelocity/2);
        delay(10);
      }
      decay[piezopin]=drumvelocity;
      delay(1);
    }
  }
  lovehandles=analogRead(5);
  if (lovehandles>35){
    if (lovehandlesflag==LOW){
      midiCC(0x90,88,127);
      delay(1);
      midiCC(0x80,88,127);
      lovehandlesflag = HIGH;
    }
    if((lovehandles/2)!=lovecheck){
      midiCC(0xB0,25,lovehandles/2);
      lovecheck=lovehandles/2;
    }
  }
  else{
    lovehandlesflag=LOW;
  }//read the lovehandles send controller and note on/off
  
  // do our 8 banks multiplexed to the digital ins
  for (banknum=7; banknum>=0; banknum--){ // set a loop of 8, 1 slot per bank
    if (banknum==0){
      PORTD = B00000001;
    } // set the bank address, binary 000 outs
    else if (banknum==1){
      PORTD = B00000101;
    }// set the bank address, binary 001 outs
    else if (banknum==2){
      PORTD = B00010001;// set the bank address, binary 010  ins unused so far
      //for(inputnum=8; inputnum<=13; inputnum++){swhandler(inputnum+12,inputnum-8);}
    }
    else if (banknum==3){
      PORTD = B00010101;// set the bank address, binary 011  puff switches and pir
      for(inputnum=8; inputnum<=13; inputnum++){
        if(digitalRead(inputnum)==HIGH){
          midiCC(0x90,inputnum+20,127);
          delay(10);
        }
      }//!!!!!!!!!!put the delay in here
      inputnum=6;
      input=(digitalRead(inputnum));// deal with pir switch, it's normally high going low
      if((input==HIGH)&&(switches[6]==LOW)){
        midiCC(0x80,35,127);
        switches[6]=HIGH;
      }
      // if a switch is pressed ON send a midi off, set the check value to ON
      if((switches[6]==HIGH) && (input==LOW)) {
        midiCC(0x90,35,127);
        switches[6]=LOW;
      }
    }
    else if (banknum==4){
      PORTD = B10000001;// set the bank address, binary 100 knife switches
      for(inputnum=8; inputnum<=13; inputnum++){
        swhandler(inputnum+28,inputnum+8);
      }
    }
    else if (banknum==5){
      PORTD = B10000101;// set the bank address, binary 101  momentary led click-switches
      for(inputnum=8; inputnum<=13; inputnum++){
        swhandler(inputnum+36,inputnum+16);
      }
    }      
    else if (banknum==6){
      PORTD = B10010001;
      enchandler(13,4);
      enchandler(11,5);
      enchandler(9,75);
    }//encoders
    else{
      PORTD = B10010101;
      enchandler(13,1);
      enchandler(11,2);
      enchandler(9,3);
    }
  }
}//encoders
//delay(50); // stall to see the leds
/* function send a Midi message.use 'midiCC(command byte, data, data)' 0xB0 = controller, 0x80 = note on,
 0x90 = note off data bytes 0-127 0x00-0x7f eg 0x80 0x34 0x0F note on, note 34, velocity 127*/
void midiCC(char CC_data, char c_num, char c_val){
  Serial.print(CC_data, BYTE);
  Serial.print(c_num, BYTE);
  Serial.print(c_val, BYTE);
} 
// function to handle encoders / amend midi controllers
void enchandler(int y,int x){
  A=digitalRead(y);
  B=digitalRead(y-1);// fetch encoder states y is pin, x is array member / controller number
  // check for movement, direction and midi controller range
  if ((A==HIGH) && (enclaststate[x]==LOW)){
    encodercount[x]=0;
    if (encoderflag[x]==LOW){
      midiCC(0x90,x+12,127);
      delay(1);
      midiCC(0x80,x+12,127);
      encoderflag[x]=HIGH;
    }
    //reset stationary count, deal with the start midi note and set flag    
    if(B == HIGH){
      if(cccurrentvalue[x]!= 127){
        cccurrentvalue[x]++;
      }
    }//positive move or negative move
    else{
      if(cccurrentvalue[x]!= 0){
        cccurrentvalue[x]--;
      }
    }
    midiCC(0xB0,x,cccurrentvalue[x]);
  }//send the controller data
  else{
    encodercount[x]++;
    if ((encodercount[x]==1000)&&(encoderflag[x]==HIGH)){
      midiCC(0x90,x+18,127);
      delay(1);
      midiCC(0x80,x+18,127);
      encoderflag[x]=LOW;
    }
  } 
  enclaststate[x] = A;
}// save the state for comparison n1ext time round

//function to read a switch and send a midi note on / off message
void swhandler(int note, int arraymember){
  input=(digitalRead(inputnum));// read the input pin
  if((input==HIGH)&&(switches[arraymember]==LOW)){
    midiCC(0x90,note,127);
    delay(1);
    midiCC(0x80,note,127);
    switches[arraymember]=HIGH;
  }
  // if a switch is pressed ON send a midi ON / off, set the check value to ON
  if((switches[arraymember]==HIGH) && (input==LOW)) {
    midiCC(0x90,note+36,127);
    delay(1);
    midiCC(0x80,note+36,127);
    switches[arraymember]=LOW;
  }
}
// if a switch is released send an on / OFF + 36, set the check value to OFF

Thanks for that John, it looks better thinner & taller! & a useful link, Ray