Here's an example for analog multiplexers with the MIDI controller library. I don't have any multiplexers on hand, so I haven't been able to test it.
Please let me know if it works, so I can add it to the library.
/*
This is an example of the "Analog" class of the MIDI_controller library.
Connect faders or potentiometers to the inputs of analog multiplexers,
and connect the outputs of the multiplexers to analog inputs on the Arduino
(A0 and A1 in this case).
Connect the address lines of the multiplexers together, and connect them
to digital outputs on the Arduino (pins 2, 3 and 4 in this case).
Change the number of multiplexers, the number of address lines, the
analog inputs and the address select pins to fit your hardware.
Upload the sketch, and map the faders in your DAW or DJ software.
If you are using a Teensy, make sure you have the USB type set to MIDI.
If you are using an Arduino Uno or Mega, use the HIDUINO firmware for the ATmega16U2.
Written by tttapa, 04-7-2017
https://github.com/tttapa/MIDI_controller
*/
#include <MIDI_controller.h> // include the library
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise
const static uint8_t numberOfMultiplexers = 2; // Total number of multiplexers connected to the Arduino
const static uint8_t addressWidth = 3; // Number of address lines of the multiplexers
const static uint8_t addressLines[addressWidth] = {2, 3, 4}; // The pins connected to the address lines of the multiplexers
const static uint8_t analogInputs[numberOfMultiplexers] = {A0, A1}; // The pins connected to the outputs of the multiplexers
//________________________________________________________________________________________________________________________________
const static uint8_t numberOfInputsPerMultiplexer = 1 << addressWidth; // Number of inputs of each multiplexer
const static size_t totalNumberOfAnalogInputs = numberOfMultiplexers * numberOfInputsPerMultiplexer; // the total number of potentiometers
//________________________________________________________________________________________________________________________________
Analog* potentiometers[totalNumberOfAnalogInputs]; // create an empty array of pointers to Analog objects
//________________________________________________________________________________________________________________________________
void setup() {
USBMidiController.blink(LED_BUILTIN); // flash the built-in LED (pin 13 on most boards) on every message
USBMidiController.setDelay(15); // wait 15 ms after each message not to flood the connection
USBMidiController.begin(); // Initialise the USB MIDI connection
delay(1000); // Wait a second...
for (unsigned int i = 0; i < totalNumberOfAnalogInputs; i++) {
potentiometers[i] = new Analog(analogInputs[i % numberOfMultiplexers], i, 1); // create a new Analog object and store it in the array
potentiometers[i]->average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
}
for (unsigned int i = 0; i < addressWidth; i++) {
pinMode(addressLines[i], OUTPUT); // set all address line pins as outputs
}
}
//________________________________________________________________________________________________________________________________
void loop() {
for (unsigned int i = 0; i < numberOfInputsPerMultiplexer; i++) { // refresh all Analog inputs
setMuxAddress(i);
for (unsigned int j = 0; j < numberOfMultiplexers; j++) {
potentiometers[i * numberOfMultiplexers + j]->refresh();
}
}
}
void setMuxAddress(unsigned int address) {
for (unsigned int i = 0; i < addressWidth; i++) {
digitalWrite(addressLines[i], address & (1 << i));
}
}
Or if you prefer to use ControlChange class you mentioned earlier, and the function Johnwasser proposed (it's a bit easier to see what's going on, without too much modulos and nested loops):
/*
This is an example of the "ControlChange" class of the MIDI_controller library.
Connect faders or potentiometers to the inputs of analog multiplexers,
and connect the outputs of the multiplexers to analog inputs on the Arduino
(A0 and A1 in this case).
Connect the address lines of the different multiplexers together, and connect
them to digital outputs on the Arduino (pins 2, 3 and 4 in this case).
Change the number of multiplexers, the number of address lines, the
analog inputs and the address select pins to fit your hardware.
Upload the sketch, and map the faders in your DAW or DJ software.
If you are using a Teensy, make sure you have the USB type set to MIDI.
If you are using an Arduino Uno or Mega, use the HIDUINO firmware for the ATmega16U2.
Written by tttapa, 04-7-2017
https://github.com/tttapa/MIDI_controller
*/
#include <MIDI_controller.h> // include the library
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise
const static uint8_t numberOfMultiplexers = 2; // Total number of multiplexers connected to the Arduino
const static uint8_t addressWidth = 3; // Number of address lines of the multiplexers
const static uint8_t addressLines[addressWidth] = {2, 3, 4}; // The pins connected to the address lines of the multiplexers
const static uint8_t analogInputs[numberOfMultiplexers] = {A0, A1}; // The pins connected to the outputs of the multiplexers
//________________________________________________________________________________________________________________________________
const static uint8_t numberOfInputsPerMultiplexer = 1 << addressWidth; // Number of inputs of each multiplexer
const static size_t totalNumberOfAnalogInputs = numberOfMultiplexers * numberOfInputsPerMultiplexer; // the total number of potentiometers
//________________________________________________________________________________________________________________________________
ControlChange* potentiometers[totalNumberOfAnalogInputs]; // create an empty array of pointers to Analog objects
//________________________________________________________________________________________________________________________________
void setup() {
USBMidiController.blink(LED_BUILTIN); // flash the built-in LED (pin 13 on most boards) on every message
USBMidiController.setDelay(15); // wait 15 ms after each message not to flood the connection
USBMidiController.begin(); // Initialise the USB MIDI connection
delay(1000); // Wait a second...
for (unsigned int i = 0; i < totalNumberOfAnalogInputs; i++) {
potentiometers[i] = new ControlChange(i, 1); // create a new ControlChange object and store it in the array
potentiometers[i]->average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
}
for (unsigned int i = 0; i < addressWidth; i++) {
pinMode(addressLines[i], OUTPUT); // set all address line pins as outputs
}
}
//________________________________________________________________________________________________________________________________
void loop() {
for (unsigned int i = 0; i < totalNumberOfAnalogInputs; i++) { // refresh all Analog inputs
uint8_t value = analogReadMux(i) >> 3; // convert 10-bit analog value to 7-bit MIDI value (10-7 = 3)
potentiometers[i]->refresh(value);
}
}
void setMuxAddress(unsigned int address) {
for (unsigned int i = 0; i < addressWidth; i++) {
digitalWrite(addressLines[i], address & (1 << i));
}
}
int analogReadMux(unsigned int muxPin) {
int address = muxPin % numberOfInputsPerMultiplexer; // the input of the multiplexer
int analogPinIndex = muxPin / numberOfInputsPerMultiplexer; // the index of the multiplexer
setMuxAddress(address); // select the right input of the multiplexer
return analogRead(analogInputs[analogPinIndex]); // read the output of the right multiplexer
}
Pieter