I am trying to add 16 potentiometers with a HC4067 to a controller where I have two multiplexers with buttons and some encoders working without problem
The goal is to read each potentiometer independently, send a midi cc message, only when the potentiometer moves
i tried to make the code from scratch (first code)
and use a template (second code)
but i couldn't get it to work
I've been trying for a couple of days, I know how to program everything separately and put it in a "for" loop to the arduino, but with the multiplexer I'm making a mess
#include <MIDI.h>
const int muxSIG3 = A3;
const int muxS03 = 37;
const int muxS13 = 35;
const int muxS23 = 33;
const int muxS33 = 31;
const int entradasmplex3 = 16;
int mux3[entradasmplex3] = {0};
int vpmux3[entradasmplex3] = {0};
const int pinPots[3] = {A0 , A1 , A2};
int VAPot[3] = {0}; //current value pot
int VPPot[3] = {0};// previous value pot
byte VAMidi[3] = {0}; //current value midi
byte VPMidi[3] = {0}; //previous value midi
byte VarPot = 0;
int cc = 0;
MIDI_CREATE_DEFAULT_INSTANCE();
void SetMuxChannel3(byte channel)
{
digitalWrite(muxS03, bitRead(channel, 0));
digitalWrite(muxS13, bitRead(channel, 1));
digitalWrite(muxS23, bitRead(channel, 2));
digitalWrite(muxS33, bitRead(channel, 3));
}
void setup()
{
pinMode(muxS03 , OUTPUT);
pinMode(muxS13, OUTPUT);
pinMode(muxS23 , OUTPUT);
pinMode(muxS33 , OUTPUT);
pinMode(muxSIG3 , INPUT);
Serial.begin(57600);
delay(1000);
}
void loop()
{
for (int i = 0 ; i < 3 ; i++ )
{
VAPot[i] = analogRead (pinPots[i]);
VAMidi[i] = map(VAPot[i] , 0 , 1023 , 0 , 127);
VarPot = abs(VPPot[i] - VAPot[i]);
if (VarPot > 2)
{
if (VAMidi[i] != VPMidi[i])
{
MIDI.sendControlChange( cc + i , VAMidi[i] , 1 );
VPPot[i] = VAPot[i];
VPMidi[i] = VAMidi[i];
}
}
}
}```
#include <MIDI.h>
#include <Multiplexer4067.h>
MIDI_CREATE_DEFAULT_INSTANCE();
#define N_MUX 1
#define s0 37
#define s1 35
#define s2 33
#define s3 31
#define x1 A3
// Initializes the multiplexer
Multiplexer4067 mux[N_MUX] = {
Multiplexer4067(s0, s1, s2, s3, x1),
};
const int N_POTS = 0 + 16 + 0; //* total numbers of pots (slide & rotary). Number of pots in the Arduino + number of pots on multiplexer 1 + number of pots on multiplexer 2...
const int N_POTS_ARDUINO = 0; //* number of pots connected straight to the Arduino
const int POT_ARDUINO_PIN[N_POTS_ARDUINO] = {}; //* pins of each pot connected straight to the Arduino
const int N_POTS_PER_MUX[N_MUX] = {16}; //* number of pots in each multiplexer (in order)
const int POT_MUX_PIN[N_MUX][16] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}}; //* pins of each pot of each mux in the order you want them to be};
int potCState[N_POTS] = {0}; // Current state of the pot
int potPState[N_POTS] = {0}; // Previous state of the pot
int potVar = 0; // Difference between the current and previous state of the pot
int potMidiCState[N_POTS] = {0}; // Current state of the midi value
int potMidiPState[N_POTS] = {0}; // Previous state of the midi value
const int TIMEOUT = 300; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
const int varThreshold = 10; //* Threshold for the potentiometer signal variation
boolean potMoving = true; // If the potentiometer is moving
unsigned long PTime[N_POTS] = {0}; // Previously stored time
unsigned long timer[N_POTS] = {0}; // Stores the time that has elapsed since the timer was reset
void setup() {
pinMode(s0 , OUTPUT);
pinMode(s1 , OUTPUT);
pinMode(s2 , OUTPUT);
pinMode(s3 , OUTPUT);
pinMode(x1 , INPUT);
Serial.begin(57600);
}
void loop() {
for (int i = 0; i < 16; i++) { // Loops through all the potentiometers
potMidiCState[i] = map(potCState[i], 0, 1023, 0, 127); // Maps the reading of the potCState to a value usable in midi
potVar = abs(potCState[i] - potPState[i]); // Calculates the absolute value between the difference between the current and previous state of the pot
if (potVar > varThreshold) { // Opens the gate if the potentiometer variation is greater than the threshold
PTime[i] = millis(); // Stores the previous time
}
timer[i] = millis() - PTime[i]; // Resets the timer 11000 - 11000 = 0ms
if (timer[i] < TIMEOUT) { // If the timer is less than the maximum allowed time it means that the potentiometer is still moving
potMoving = true;
}
else {
potMoving = false;
}
if (potMoving == true) { // If the potentiometer is still moving, send the change control
MIDI.sendControlChange (i , potMidiCState , 1 );
if (potMidiPState[i] != potMidiCState[i]) {
}
}
}
int nPotsPerMuxSum = N_POTS_ARDUINO; //offsets the buttonCState at every mux reading
for (int j = 0; j < N_MUX; j++) {
for (int i = 0; i < N_POTS_PER_MUX[j]; i++) {
potCState[i + nPotsPerMuxSum] = mux[j].readChannel(POT_MUX_PIN[j][i]);
}
nPotsPerMuxSum += N_POTS_PER_MUX[j];
}
}
I am unfamiliar with MIDI programming, but saw your "template" has a conditional test with no action...
if (potMoving == true) { // If the potentiometer is still moving, send the change control
MIDI.sendControlChange (i , potMidiCState , 1 );
if (potMidiPState[i] != potMidiCState[i]) {
// nothing happens if "P" and "C" are not equal
}
The problem is that I need to read the potentiometers connected to the multiplexer independently, only when they move and that each send a midi cc message
What happens now is that they send midi data through all the channels consecutively, without touching any potentiometer and with values that do not correspond to the position of the potentiometer
int VAPot[3] = {0}; //current value pot
int VPPot[3] = {0};// previous value pot
byte VAMidi[3] = {0}; //current value midi
byte VPMidi[3] = {0}; //previous value midi
byte VarPot = 0;
Try ditching all the midi code and just try to make the pots work first. Write a simple test sketch that only does that, and just reports changes and values to serial output.
Since you report that your button version works, it should be easy to integrate the pots after you make them work.
By the way, I can't resist a design suggestion. You detect the dead zone after scaling. That will work better if you do it before scaling (before using map() ).
I just quickly programmed the part of the potentiometers, but connected to the arduino directly, without using the multiplexer and it works perfect, this is what I want, but with the mux
`#include <MIDI.h>
const int pinPots[3] = {A0 , A1 , A2};
int VAPot[3] = {0}; //current value pot
int VPPot[3] = {0}; //previous value pot
byte VAMidi[3] = {0}; //current value midi
byte VPMidi[3] = {0}; //previous value midi
byte VarPot = 0;
MIDI_CREATE_DEFAULT_INSTANCE();
void setup()
{
Serial.begin(57600);
}
void loop()
{
for (int i = 0 ; i < 3 ; i++ )
{
VAPot[i] = analogRead (pinPots[i]);
VAMidi[i] = map(VAPot[i] , 0 , 1023 , 0 , 127);
VarPot = abs(VPPot[i] - VAPot[i]);
if (VarPot > 2)
{
if (VAMidi[i] != VPMidi[i])
{
MIDI.sendControlChange( 0 + i , VAMidi[i] , 1 );
VPPot[i] = VAPot[i];
VPMidi[i] = VAMidi[i];
}
}
}
}`
If you are having trouble with the mux code, then the simple example code you need is mux code. But that muxes the pots. So actually, to create working mux code, I will repeat again, make a test sketch that ONLY reads the pots. Using the mux, not just reading different analog pins.
I.E. if your difficulty is in the mux, no code that has no mux code in it, can be of any possible use in writing the code. If you are presenting code and hoping someone will pencil in the mux code for you, forget about it.
Also, not all mux circuits are the same. So please play by the forum guidelines, and post a schematic.
I just did this code, it reads the potentiometers without problem
#include <MIDI.h>
const int muxSIG3 = A3;
const int muxS03 = 37;
const int muxS13 = 35;
const int muxS23 = 33;
const int muxS33 = 31;
const int entradasmplex3 = 5;
int VAPot = 0; //current value pot
byte VAMidi = 0; //current value midi
MIDI_CREATE_DEFAULT_INSTANCE();
void SetMuxChannel3(byte channel)
{
digitalWrite(muxS03, bitRead(channel, 0));
digitalWrite(muxS13, bitRead(channel, 1));
digitalWrite(muxS23, bitRead(channel, 2));
digitalWrite(muxS33, bitRead(channel, 3));
}
void setup()
{
pinMode(muxS03 , OUTPUT);
pinMode(muxS13, OUTPUT);
pinMode(muxS23 , OUTPUT);
pinMode(muxS33 , OUTPUT);
pinMode(muxSIG3 , INPUT);
Serial.begin(9600);
delay(1000);
}
void loop()
{
for (int i = 0 ; i < 5 ; i++ )
{
SetMuxChannel3(i);
VAPot = analogRead (muxSIG3);
VAMidi = map(VAPot , 0 , 1023 , 0 , 127);
//MIDI.sendControlChange( 0 + i , VAMidi , 1 );
Serial.print(i);
Serial.print(".........");
Serial.println(VAMidi);
}
}
If you are presenting code and hoping someone will pencil in the mux code for you, forget about it.
Do you think that's what I'm doing?
I assure you, that coming to ask other people has been the last resort, and between answers I am here trying to make it work
It was hard to determine what you are doing, because you didn't say. I made that statement because you didn't follow my suggestion previously. But at least now, you have two working codes that you can integrate. Please make an attempt at that, and post the results if it still has problems.
Fixed, it was a silly error, the value of the array (VAPot, VPPot, VAMidi, VPMidi) did not match the value of "entradasmplex" ,
I had set the focus convinced that the error was from the "for loop" and even knowing that this error existed, I thought that I had already tried to correct it and it still did not work, so I ruled it out as the reason for the failure
For those who read this and are starting out like me, don't take things for granted, check everything
#include <MIDI.h>
const int muxSIG3 = A3;
const int muxS03 = 37;
const int muxS13 = 35;
const int muxS23 = 33;
const int muxS33 = 31;
const int entradasmplex3 = 15;
int VAPot[15] = {0}; //current value pot
int VPPot[15] = {0};// previous value pot
byte VAMidi[15] = {0}; //current value midi
byte VPMidi[15] = {0}; //previous value midi
byte VarPot = 0;
MIDI_CREATE_DEFAULT_INSTANCE();
void SetMuxChannel3(byte channel)
{
digitalWrite(muxS03, bitRead(channel, 0));
digitalWrite(muxS13, bitRead(channel, 1));
digitalWrite(muxS23, bitRead(channel, 2));
digitalWrite(muxS33, bitRead(channel, 3));
}
void setup()
{
pinMode(muxS03 , OUTPUT);
pinMode(muxS13, OUTPUT);
pinMode(muxS23 , OUTPUT);
pinMode(muxS33 , OUTPUT);
pinMode(muxSIG3 , INPUT);
Serial.begin(31250);
delay(1000);
}
void loop()
{
for (int i = 0 ; i < entradasmplex3 ; i++ )
{
SetMuxChannel3(i);
VAPot[i] = analogRead (muxSIG3);
VAMidi[i] = map(VAPot[i] , 0 , 1023 , 0 , 127);
VarPot = abs(VPPot[i] - VAPot[i]);
if (VarPot > 2)
{
if (VAMidi[i] != VPMidi[i])
{
MIDI.sendControlChange( 0 + i , VAMidi[i] , 2 );
// Serial.print("channel........." );
// Serial.print(i);
// Serial.print("value........." );
// Serial.println(VAMidi[i] );
VPMidi[i] = VAMidi[i];
VPPot[i] = VAPot[i];
}
}
}
}
#include <MIDI.h>
const int muxSIG3 = A3;
const int muxS3[4] = {37, 35, 33, 31};
const int entradasmplex3 = 15;
int VAPot[15] = {0}; //current value pot
int VPPot[15] = {0};// previous value pot
byte VAMidi[15] = {0}; //current value midi
byte VPMidi[15] = {0}; //previous value midi
byte VarPot = 0;
MIDI_CREATE_DEFAULT_INSTANCE();
void SetMuxChannel3(byte channel)
{
for (byte b=0; b<4; b++)
digitalWrite(muxS3[b], bitRead(channel, b));
}
void setup()
{
for (byte b=0; b<4; b++)
pinMode(muxS3[b] , OUTPUT);
pinMode(muxSIG3 , INPUT);
Serial.begin(31250);
delay(1000);
}
void loop()
{
for (int i = 0 ; i < entradasmplex3 ; i++ )
{
SetMuxChannel3(i);
VAPot[i] = analogRead (muxSIG3);
VAMidi[i] = map(VAPot[i] , 0 , 1023 , 0 , 127);
VarPot = abs(VPPot[i] - VAPot[i]);
if (VarPot > 2)
{
if (VAMidi[i] != VPMidi[i])
{
MIDI.sendControlChange( 0 + i , VAMidi[i] , 2 );
// Serial.print("channel........." );
// Serial.print(i);
// Serial.print("value........." );
// Serial.println(VAMidi[i] );
VPMidi[i] = VAMidi[i];
VPPot[i] = VAPot[i];
}
}
}
}
What is the purpose of the other 2 multiplexers? More pots? Do you need independent control of the channel selection of each multiplexer for any reason? If not, do you know that you can use the same 4 pins to control all 3 multiplexers?