How do I wire my CD74HC4067 multiplexer for my 61-note matrixed MIDI keyboard?

I'm using the [amazing!] Control Surface library.

I can't figure out for the life of me how to wire my CD74HC4067 multiplexer. My goal is to create an 8x8 matrixed 61-note MIDI controller. My code is below. I have the 8x8 matrix wired up and ready to go - diodes and all (it's a pretty standard keyboard matrix). I intend to feed 8 columns and 8 rows into the multiplexer, but I don't have any idea how to wire the multiplexer to my Arduino Mega in the first place.

#include <Control_Surface.h> // Include the Control Surface library
#include <AH/Hardware/ExtendedInputOutput/AnalogMultiplex.hpp>

HairlessMIDI_Interface midi;
 
using namespace MIDI_Notes;

// Instantiate a multiplexer
CD74HC4067 mux_I{2, {3, 4, 5, 6} , }; //input, S0-S3, optional enable

const AddressMatrix<8, 8> addresses
  {{
    {36, 37, 38, 39, 40, 41, 42, 43},
    {44, 45, 46, 47, 48, 49, 50, 51},
    {52, 53, 54, 55, 56, 57, 58, 59},
    {60, 61, 62, 63, 64, 65, 66, 67},
    {68, 69, 70, 71, 72, 73, 74, 75},
    {76, 77, 78, 79, 80, 81, 82, 83},
    {84, 85, 86, 87, 88, 89, 90, 91},
    {92, 93, 94, 95, 96, 97, 98, 99},
  }};

NoteButtonMatrix<8, 8> matrix_I
  {
    {
      mux_I.pin(8), mux_I.pin(9), mux_I.pin(10), mux_I.pin(11),  // row pins
      mux_I.pin(12), mux_I.pin(13), mux_I.pin(14), mux_I.pin(15)
    },
    {
      mux_I.pin(0), mux_I.pin(1), mux_I.pin(2), mux_I.pin(3),    // column pins
      mux_I.pin(4), mux_I.pin(5), mux_I.pin(6), mux_I.pin(7)
    },
    addresses, // address matrix
    CHANNEL_1,    // channel and cable number
  };


void setup()
{
  mux_I.begin();
  /*for (int i=0; i<8; i++) //not sure if I need this
  {
    mux_I.pinMode(i, OUTPUT);
    mux_I.pinMode(i+8, INPUT);
  }*/

  pinMode(3, INPUT_PULLUP);
  
  Control_Surface.begin(); // Initialize Control Surface
}
 
void loop()
{
  Control_Surface.loop(); // Update the Control Surface
}

//Thanks to PieterP's example code

Thanks in advance for any guidance! :slight_smile:

I believe the CD74HC4067 can only provide one output at a time. So you would need two multiplexers.

Thanks for your reply! Do you mean there can be only one output pin on that multiplexer? I’m not sure I understand.

that is what it appears to be. Perhaps it could also spread 1 signal to 16 outputs.

If you already have diodes at each crosspoint, you can easily scan the matrix on one dimension (the anodes) using a 74HC4017. It just requires a clock pulse to step from one output (out of 10) to the next and a reset pulse to ensure you start at the right line.

You need four lines to control the selection of the 74HC4067. You might as well leave it enabled. You can work it either way but it may be easiest to select one line in the multiplexer and scan the 74HC4017 through all 8 (or 10) outputs while you read the common of the 74HC4067 with a pull-down to ground.

Oh, this is making more sense to me, thanks very much!

If I were to use two CD74HC4067 multiplexer breakout boards, I could dedicate one to columns/outputs and then second to rows/inputs. Would that work?

I am not concerned with having extra pins on the multiplexers…I’d find use for them!

It would, and you would have 256 crosspoints available, but as I explained, if you have the diodes anyway, a 74HC4017 has ten outputs and together with the 74HC4067, you have 160 crosspoints and the 4017 is easier to code.

All that said, a single 4067 and four Arduino pins makes a 4 by 16 = 64 matrix.

I'll check it out, though I would love to use the set of CD74HC4067 multiplexers that I have for a few different reasons. I will ultimately have three 61-key keyboards and additional switches to be controlled by my Arduino and was wondering if this code might do the trick. I wasn't sure if I needed to declare the pinMode for each multiplexer or if the ControlSurface package does that for me when instantiating a NoteButtonMatrix.

#include <Control_Surface.h> // Include the Control Surface library
#include <AH/Hardware/ExtendedInputOutput/AnalogMultiplex.hpp>

HairlessMIDI_Interface midi;

using namespace MIDI_Notes;

// Instantiate a multiplexer
CD74HC4067 mux_1{2, {5, 6, 7, 8} , }; //input, S0-S3, optional enable
CD74HC4067 mux_2{3, {5, 6, 7, 8} , }; //input, S0-S3, optional enable

const AddressMatrix<8, 8> addresses
  {{
    {36, 37, 38, 39, 40, 41, 42, 43},
    {44, 45, 46, 47, 48, 49, 50, 51},
    {52, 53, 54, 55, 56, 57, 58, 59},
    {60, 61, 62, 63, 64, 65, 66, 67},
    {68, 69, 70, 71, 72, 73, 74, 75},
    {76, 77, 78, 79, 80, 81, 82, 83},
    {84, 85, 86, 87, 88, 89, 90, 91},
    {92, 93, 94, 95, 96, 97, 98, 99},
  }};

NoteButtonMatrix<8, 8> matrix_I
  {
    {
      // ROW PINS // INPUT // HORIZONTAL
      mux_1.pin(0), mux_1.pin(1), mux_1.pin(2), mux_1.pin(3), mux_1.pin(4), mux_1.pin(5), mux_1.pin(6), mux_1.pin(7),
    },
    {
      // COLUMN PINS // OUTPUT // VERTICAL
      mux_2.pin(0), mux_2.pin(1), mux_2.pin(2), mux_2.pin(3), mux_2.pin(4), mux_2.pin(5), mux_2.pin(6), mux_2.pin(7),
    },
    addresses, // address matrix
    CHANNEL_1,    // channel and cable number
  };


void setup()
{
  mux_1.begin();
  mux_2.begin();
  
  for(int i=0; i<8; i++)
  {
    //do I need to assign inputs and outputs?
    mux_1.pinMode(i, OUTPUT);
    mux_2.pinMode(i, INPUT_PULLUP);
  }
  
  Control_Surface.begin(); // Initialize Control Surface
}
 
void loop()
{
  Control_Surface.loop(); // Update the Control Surface
}

//Thanks to PieterP's example code

Thanks!!

Actually, a single 4067 four Arduino pins to control that, another four to drive the matrix and one more Arduino pin to read from the common of the 4067, total nine. Further 4067s for more matrices would require just one additional "reading" pin each.