CD74HC4067 coding disaster!

Ok guys so i'm very pleased to say that (even if a couple days late) my multiplexers has finally arrived!!!
But well i know that coding a multiplexer should be a feasible thing but, and i repeat but, i'm seriously stuck even with the stuff i found on the net >:( .. and well the fact is i cant read the value of the pot i mounted on the board (attached photo) neither send a midi signal.
thanks in advance for the advices!

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();


////////////////////////////////////
//MUX

//MUX Pins
int s0 = 5;
int s1 = 4;
int s2 = 3;
int s3 = 2;

//Mux in "SIG" pin
int SIG_pin = {A5};
const int nMux=1;



/////////////////////////////////////////////
// potentiometers
const int NPots = 16; //* Number of Pots per MUX

int potCState[nMux][NPots] = {0}; // Current state of the pot
int potPState[nMux][NPots] = {0}; // Previous state of the pot
int potVar = 0; // Difference between the current and previous state of the pot

int midiCState[nMux][NPots] = {0}; // Current state of the midi value
int midiPState[nMux][NPots] = {0}; // Previous state of the midi value

int TIMEOUT = 300; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
int varThreshold = 20; //* Threshold for the potentiometer signal variation
boolean potMoving = true; // If the potentiometer is moving
unsigned long PTime[nMux][NPots] = {0}; // Previously stored time
unsigned long timer[nMux][NPots] = {0}; // Stores the time that has elapsed since the timer was reset

/////////////////////////////////////////////

byte midiCh1 = 1; //MIDI channel to be used bank1
byte midiCh2 = 2;//* MIDI channel to be used bank2
byte note = 36; //* Lowest note to be used
byte cc = 1; //* Lowest MIDI CC to be used


void setup(){
pinMode(s0, OUTPUT); 
pinMode(s1, OUTPUT); 
pinMode(s2, OUTPUT); 
pinMode(s3, OUTPUT); 
pinMode(SIG_pin, INPUT);

digitalWrite(s0, LOW);
digitalWrite(s1, LOW);
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);

Serial.begin(115200);
}

void loop(){

//Loop through and read all 16 values
//Reports back Value at channel 6 is: 346

  MuxPots1();
  


}

void MuxPots1(){
for(int i=0;i<16;i++){
int controlPin[] = {s0, s1, s2, s3};



int muxChannel[16][4]={
  {0,0,0,0}, //channel 0
  {1,0,0,0}, //channel 1
  {0,1,0,0}, //channel 2
  {1,1,0,0}, //channel 3
  {0,0,1,0}, //channel 4
  {1,0,1,0}, //channel 5
  {0,1,1,0}, //channel 6
  {1,1,1,0}, //channel 7
  {0,0,0,1}, //channel 8
  {1,0,0,1}, //channel 9
  {0,1,0,1}, //channel 10
  {1,1,0,1}, //channel 11
  {0,0,1,1}, //channel 12
  {1,0,1,1}, //channel 13
  {0,1,1,1}, //channel 14
  {1,1,1,1}  //channel 15
};

//loop through the 4 sig
for(int j = 0; j < 4; j ++){
  digitalWrite(controlPin[i], muxChannel[i][j]);
}

//read the value at the SIG pin



potCState[1][i]=analogRead(SIG_pin);

midiCState[1][i] = map(potCState[1][i], 0, 1023, 127, 0); // Maps the reading of the potCState to a value usable in midi


  potVar = abs(potCState[1][i] - potPState[1][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[1][i] = millis(); // Stores the previous time
  }

  timer[1][i] = millis() - PTime[1][i]; // Resets the timer 11000 - 11000 = 0ms

  if (timer[1][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
    if (midiPState[1][i] != midiCState[1][i]) {

    
      MIDI.sendControlChange(cc + i, midiCState[1][i], midiCh1); // cc number, cc value, midi channel

      

      //Serial.println(midiCState);
      potPState[1][i] = potCState[1][i]; // Stores the current reading of the potentiometer to compare with the next
      midiPState[1][i] = midiCState[1][i];
    }
    }


}
}

HOOGE_RolandX.ino (3.65 KB)

It appears that you want to read an analog value (between 0 and 1023) from up to 16 potentiometers in sequence, detecting any changes in value from the last reading. If there is a change for a specific potentiometer, you want to register the change using the command MIDI.sendControlChange(). Is that correct ?

I suggest you supply (a) a wiring diagram and (b) links you have found to any code which does approximately what you want to do.

Maybe because of all the italics in your code that it does not work :smiley: Please read How to use this forum - please read, specifically point 7.

Anyway, break the code up in two pieces, one for the midi and one for 74HC4067. Develop each individually and later on merge them.

You need to,learn how to use arrays
http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

Ok guys so as stated by some of you it appears i've also done some disaster in my post (sad joke), well for the reference you need, i took advice from here , but as you can see only as a mean of reading the mux, as for the schematics are pretty the same you can see in the url above.

The idea is to write on the signal pin the matrix named muxChannel (this should light up by different combination means the 16 different ports), and read the sigPin as an output, and then dispose of the output putting it into the matrix wich should contain [1(the first mux)].
Multiplexer Code:
```
*#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

////////////////////////////////////
//MUX

//MUX Pins
int s0 = 5;
int s1 = 4;
int s2 = 3;
int s3 = 2;

//Mux in "SIG" pin
int SIG_pin = {A5};
const int nMux=1;

/////////////////////////////////////////////
// potentiometers
const int NPots = 16; //* Number of Pots per MUX

int potCState[nMux][NPots] = {0}; // Current state of the pot
int potPState[nMux][NPots] = {0}; // Previous state of the pot
int potVar = 0; // Difference between the current and previous state of the pot

int midiCState[nMux][NPots] = {0}; // Current state of the midi value
int midiPState[nMux][NPots] = {0}; // Previous state of the midi value

int TIMEOUT = 300; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
int varThreshold = 20; //* Threshold for the potentiometer signal variation
boolean potMoving = true; // If the potentiometer is moving
unsigned long PTime[nMux][NPots] = {0}; // Previously stored time
unsigned long timer[nMux][NPots] = {0}; // Stores the time that has elapsed since the timer was reset

/////////////////////////////////////////////

byte midiCh1 = 1; //MIDI channel to be used bank1
byte midiCh2 = 2;//* MIDI channel to be used bank2
byte note = 36; //* Lowest note to be used
byte cc = 1; //* Lowest MIDI CC to be used

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(SIG_pin, INPUT);

digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);

Serial.begin(115200);
}

void loop(){

//Loop through and read all 16 values
  //Reports back Value at channel 6 is: 346

MuxPots1();

}

void MuxPots1(){
  for(int i=0;i<16;i++){
  int controlPin[] = {s0, s1, s2, s3};

int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

//loop through the 4 sig
  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[i], muxChannel[i][j]);
  }

//read the value at the SIG pin

potCState[1][i]=analogRead(SIG_pin);

midiCState[1][i] = map(potCState[1][i], 0, 1023, 127, 0); // Maps the reading of the potCState to a value usable in midi

potVar = abs(potCState[1][i] - potPState[1][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[1][i] = millis(); // Stores the previous time
    }

timer[1][i] = millis() - PTime[1][i]; // Resets the timer 11000 - 11000 = 0ms

if (timer[1][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
      if (midiPState[1][i] != midiCState[1][i]) {

MIDI.sendControlChange(cc + i, midiCState[1][i], midiCh1); // cc number, cc value, midi channel

//Serial.println(midiCState);
        potPState[1][i] = potCState[1][i]; // Stores the current reading of the potentiometer to compare with the next
        midiPState[1][i] = midiCState[1][i];
      }
      }

}
  }*
```
and if this help i do attach my source code wich i've written for nonmultiplexed midi controller, that work i'm trying to expand that code with multiplexers.
Thanks again!!!!!
Midi_Controller_SemiDef.ino (5.19 KB)

//loop through the 4 sig
  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[i], muxChannel[i][j]);
  }

That sets the multiplexer address to each value in turn and does nothing with it. In that loop you need to set the channel, then read the multiplexer, then do all the other stuff you want to do.

This is a much better way of addressing the mux using a function.

//function to write a mux address
  void writeMux(byte channel){
   for(byte i = 0; i<4; i++){
    digitalWrite(controlPin[channel], (channel >> i) & 1); // address MUX
  }
}

Note not tested. The & is the bitwise AND function and the >> is the shift right operation. You need no muxChannel array.

int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3

This should be defined outside any function, there is no need to do it each time round the loop it just wastes time. Also you are using 128 bytes of memory when all you need for this is one byte. As shown above this array is not needed anyway.

When writing code do not try and write it all at once, build it up a bit at a time. Testing each part as you go. In your case simply write code to read one input from the multiplexed at a fixed address. Get that working then expand it to reading all of them and printing them out. Then add the threshold bit, then the past values storage bit and finally the bit that sends out MIDI.

Wow that was a pretty comprehensive answer! , well unfortunately i do not now how to use pointer and some of the most usefull stuff (yeah yeah i know please have pity), but luck came to me hopefully and while i was rushing learning some basic stuff about functions, i found this library which is roughly described here what are your thoughs about?
It seems like the holy grail to me but i cant try it since tomorrow :stuck_out_tongue:

well unfortunately i do not now how to use pointer

Well fortunately no one ever mentioned or used pointers in their answers to you.

what are your thoughs about?

Tutorial part looks fine. The code is way more complex than you need.

That is the problem with the world and his wife writing libraries for every stupid little thing. They deny you the opportunity to learn how to code problems minimum complexity by doing it for you. Yes it will do the job but you will learn very little. Where as if you had to write a small amount of code not only would you do the job more efficiently but you would understand what was going on and acquire skills when you come across stuff that no one has written a libiary for.

For example you will continue not to know what a pointer actually is.