Advice on Midi controller topology: 48 button inputs,96 leds

Hi I was wondering if you guys could give some advise about the feasibility and 'design' / requirements of my project:

I would like to build an alternative midi controller with about 96 buttons (on/off), and an equal amount of addressable Leds. (i lower it a couple if needed). The goal is to send and receive midi notes, and flash the corresponding buttons.

    1. !!IMPORTANT!! the buttons consist of 2 sets providing the same input/function (= 48 pairs) - this leads me to believe i can hook the pairs up to the same pin (on a multiplexer?) and therefor require just 48 inputs. Correct?
    1. Up to 16 (unique) buttons will be on at a time. If i understand correctly this means I have to use AnalogIn's in combination with multiplexers
    1. the same amount of leds can be on at a time. (on / off, no dimming)
    1. The arduino will need to link the leds and buttons to send midi notes, and show which notes are received.
    1. [EDIT] I need to account for Midi in / out connections as well. (looking into that now)

Would the above be feasible to run smoothly on a single standard arduino? And what kind of pin configuration / multiplexing set up would you recommend? I am currently looking into the MCP23016 and 4051.

Just a maybe:
1 analog input, 8 digital pins are used to drive the keypad columns. 3 pins are used to drive shift registers to power your leds. You have 12 pins + 2 pins (load sketch). 6 pins left. How do you get midi message? Through serial or some other inputs?

I would make a string of 12 parallel-in serial out shift registers.
Clock all inputs together to sample the pins, shift the 12 bytes in with SPI.transfer & act on them.
for example:

// ignoring the declarations & void setup stuff for now ...
void loop(){
if (millis() >=previousMillis({ // see if sample time elapsed

previousMillis = previousMillis + 10; // set up for  next sample time, 10mS in the future

digitalWrite (shiftReg_slaveSelect, LOW);
digitalWrite (shiftReg_slaveSelect, HIGH;  // make a clock pulse to capture the data on the parallel inputs

for (x=0; x<12; x=x+1){ //loop to read in the shift registers
shiftReg[x] = SPI.transfer(); //bring in the data, put it in an array - might need 1 false transfer before see the real data
}
// now have 12 bytes in the shiftReg[] array, process them
for (arrayLevel = 0; arrayLevel <8; arrayLevel = arrayLevel +1){ // go thru the 12 bytes
  for (byteBit = 1; byteBit <8; byteBit = byteBit <1){  // go thru each byte, mask off each bit
    if (shiftReg[arrayLevel] & byteBit) !=1){  // example: shiftReg[2] = B00110110, byteBit is B00000100, then result is B00000100
       //send midinote for arrayLevel * 8 + byteAdder[byteBit]
       // where byteAdder[] = {7,6,5,4,3,2,1,0}; is previously defined
      // thus (0 to 11) * 8 + (0-7) represents all 96 notes
     } // end processing each note
   } // end cycling thru 8 bits
 } // end cycling thru 12 registers
} // end void loop

When the 12 bytes are sampled, I would use that same clock to latch the keypress status into 12 octal latches to drive the LEDs.

Thanks so far!

  • @liudr; You're right I forgot to include the MIDI connection. Looking into that as we speak.
  • I could also perhaps expand via I2C?
  • @CrossRoads; Thank's for the idea and example, that helps a lot!
  • I'm guessing the 12 shift registers come from 96 inputs / 8? Since my inputs consist of 2 identical groups (see point 1 of my opening post), can I use 6 shift registers?

I think the right way to do this is with port expanders of some variety. That will give you a more straightforward and modifiable/fixable system. There are a lot of solid I2C port expander chips on the market, but most of them are surface mount. Snootlab sells a nice board based around the MAX7313, which not only does digital I/O but also has a PWM output capability on sixteen channels. (Full disclosure: I'm the US distributor)

Maybe I missed something obvious, but where does the analog input come in? These are two-state buttons right? (On/off?) Or are you trying to capture velocity?

If they're just buttons, I'm with CrossRoads on this one. And yes, you can parallel your two sets of buttons and use half the shift registers if they are in fact serving the same purpose.

Yeah, if both buttons tell you the same thing, cut the quantity of parts in half.

If you only have 10 fingers, not sure why'd need 16 buttons, but as described it doesn't really matter.