Mux Shield

I don't understand what this is doing:-

digitalWrite(s0Pin, i & 0x1);

It might be stopping it working. What do you think it does?

One question though: I thought the size of control should be 4, because of the 4 control select pins.

No it should be 16 because you have 16 MIDI control channels you want to control.
This should be initialised with values you want to use, like this:-

int control[] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };

or any set of values you want to use.

digitalWrite(s0Pin, i & 0x1);

I thought this part wrote a value from the mux to the variable s0Pin, which could later be used in the array.
I figured that

    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL3, (i&15)>>3);
    digitalWrite(CONTROL2, (i&7)>>2);  
    digitalWrite(CONTROL1, (i&3)>>1);  
    digitalWrite(CONTROL0, (i&1));

'sets the correct logic for the controlpins to select the desired input' and that s0Pin was used to actually write the desired input to a variable.
But since you say you don't understand why it's there, I suppose it's unnecessary?

What then, should the analogRead funtion read?

temp = analogRead(XXX)/8;

As for the control[] array, I understand how to initialise it, but what values do i want in it? I mean, which values should be in it. I suppose it would be something like control pin numbers or so.

I thought this part wrote a value from the mux to the variable s0Pin, which could later be used in the array.
I figured that

As the variable s0Pin is set to 0 and, I can't see it changing, all it does is to write alternate 0s and 1s to the serial RX pin, not something you want to do I would have thought. Does the multiplex shield have a latch on the control pins? If so it is that pin that needs to be toggled, that is write a one immediately followed by a zero. But you will have to look at the schematic of the mux shield to see if you need to do this.

What then, should the analogRead funtion read?

The one analogue input that the mux funnels all its data to.

the control[] array, I understand how to initialise it, but what values do i want in it?

This code is, I thought, supposed to be sending some MIDI CC values from values it reads on the mux inputs. This array maps what mux input affects what CC number. So if the first value in the array is 10 then when mux input 0 is read it will feed the value to the MIDI CC 10. Each entry maps where each mux input ends up.

Also it should be:-

char control[] = { 10,

and not an int.

This is the schematic of the shield: http://mayhewlabs.com/media/Mux_Shield_Schematic.pdf

According to this I would say that I'd have to cut out

digitalWrite(s0Pin, i & 0x1);

Furthermore, when I want to read the one analogue input that the mux funnels all its data to, I'd say - based on the schematic - that for every multiplexer on the shield, I'd have to read the COM pin (COM1 for mux1, COM2 for mux2, COM3 for mux3). Does this mean that all the analogRead should read is pin 1? Because according to the schematic all COMs are on pin 1. Then the code would be something like:

int COM1 = 1
int COM2 = 1
int COM3 = 1

tempmux1 = analogRead(COM1)/8
tempmux2 = analogRead(COM2)/8
tempmux3 = analogRead(COM3)/8

But then I can't see how this reads the 3 different multiplexers on the shield. It seems this reads the same mux three times.

According to this I would say that I'd have to cut out

Yes totally remove it, it has no function at all.

when I want to read the one analogue input that the mux funnels all its data to, I'd say - based on the schematic - that for every multiplexer on the shield, I'd have to read the COM pin (COM1 for mux1, COM2 for mux2, COM3 for mux3)

You are misunderstanding that circuit. The shied has the COM pin from each selector connected to a different analogue input pin. Shown on connector JP1.
So to read all three outputs from the multiplexer ( COM pins ) you need to do this:-

int COM1 = 0
int COM2 = 1
int COM3 = 2

tempmux1 = analogRead(COM1)/8
tempmux2 = analogRead(COM2)/8
tempmux3 = analogRead(COM3)/8

Of course before you do this you have to set up the 4 select lines to the multiplexer. Suppose you set them all to one, then the three reads will read channel 15 from each of the three multiplexes.

I cut out the analogRead(s0Pin... and added the lines for reading the analog pins. I also added the lines for mux 2 and 3.

//Give convenient names to the control pins
#define CONTROL0 5    //S3
#define CONTROL1 4    //S2
#define CONTROL2 3    //S1
#define CONTROL3 2    //S0

//create temporary variables for analog input
int tempmux0;
int tempmux1;
int tempmux2;

//create char look up tables for MIDI CC
char control0[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
char control1[] = { 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 };
char control2[] = { 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48 };

//create variables which hold the pinnumbers the three muxs send their data to
int COM1 = 0;
int COM2 = 1;
int COM3 = 2;

//Create arrays for data from the the MUXs
int mux0array[16];
int mux1array[16];
int mux2array[16];


void setup()
{
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
  
//Default speed of MIDI serial port
  Serial.begin(31250);
}

void loop()
{
  //This for loop is used to scroll through and store the 16 inputs on the FIRST multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux0 = analogRead(COM1)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux0array[i] - tempmux0) > 2) {
        mux0array[i] = tempmux0;
        MidiTX(char(0xB0), control0[i], char(mux0array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }

  //This for loop is used to scroll through and store the 16 inputs on the SECOND multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux1 = analogRead(COM2)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux1array[i] - tempmux1) > 2) {
        mux1array[i] = tempmux1;
        MidiTX(char(0xB0), control1[i], char(mux1array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }

  //This for loop is used to scroll through and store the 16 inputs on the THIRD multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux2 = analogRead(COM3)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux2array[i] - tempmux2) > 2) {
        mux2array[i] = tempmux2;
        MidiTX(char(0xB0), control2[i], char(mux2array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }
}

void MidiTX(unsigned char MESSAGE, unsigned char CONTROL, unsigned char VALUE) 		//pass values out through standard Midi Command
{
   Serial.write(MESSAGE);
   Serial.write(CONTROL);
   Serial.write(VALUE);
}

I'm not getting anything in the midi monitor yet, but this may be due to other factors than the code?
Furthermore, I don't understand exactly how this works:

void MidiTX(unsigned char MESSAGE, unsigned char CONTROL, unsigned char VALUE) 		//pass values out through standard Midi Command
{
   Serial.write(MESSAGE);
   Serial.write(CONTROL);
   Serial.write(VALUE);}

I think it writes char(message), char(control) and char(value) - which would be char(0xB0), control and char(muxarray*) - to the serial port. But why then do we serial.write MESSAGE, CONTROL & VALUE, instead of:*
*_ <em>*{   Serial.write(char(0xB0));   Serial.write(control[i]);   Serial.write(char(muxarray[i]));*</em> _*

control and char(muxarray) - to the serial port.

We have been through this once. The middle parameter is the CC number you want to change.

Yes you could write like you said at the end but then it would not be a useful function. That function will send any three byte MIDI message if you pass it the correct parameters.

Try changing that function to:-

void MidiTX(byte message, byte control, byte value) 		//pass values out through standard Midi Command
{
   Serial.write(message);
   Serial.write(control);
   Serial.write(value);
}

That is change the data type to byte and don't use capital letters, they are reserved for constants - not required but a style thing.

still nothing.. maybe I wired it the wrong way? I've got everything hooked up like here: Simple Arduino Midi Controler | Starfire's Tech Blog (but then I plugged the wires in on the muxshield), except for the wires that come from the pots and normally go to the analog inputs. These I connected to pin 0 and 1 on the first multiplexer (for the moment, I'm using just 2 potmeters).

Well it is a crap MIDI interface circuit, that could be the problem.
More likely you have the socket connectors swapped over, with confusion over if you are looking from the front or back of the circuit.
Try this sketch and see if you can see anything on a MIDI monitor on your computer:-

/* Midi note fire - Mike Cook March 2012
 *
 * ----------------- 
 * send MIDI serial data, automatically for a test
 * 
*/
// Arduino pin assignments
#define midiChannel (byte)0

// Start of code
void setup() {
 //  Setup serial
   Serial.begin(31250);  // MIDI speed
   programChange(0xc0, 14);  // Change MIDI voice

}

//********************* MAIN LOOP ***********************************

void loop() {
  int val;
  val = random(20,100);
    noteSend(0x90, val, 127);
    delay(200);
    noteSend(0x80, val, 127);
   delay(800);
    } // end loop function
    
//********************* Functions *********************************** 


//  plays a MIDI note
 void noteSend(char cmd, char data1, char data2) {
  cmd = cmd | char(midiChannel);  // merge channel number
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
}
//  change the voice
 void programChange(char cmd, char data1) {
  cmd = cmd | char(midiChannel);  // merge channel number
  Serial.write(cmd);
  Serial.write(data1);
}


//  change the bank
void bankChange(char cmd, char data1) {
  Serial.write(0xB0 | char(midiChannel));  // control change
  Serial.write(cmd);
  Serial.write(data1);
}

Nothing shows in the midi monitor. However, when I take the muxshield of the arduino and then connect the wires as one would in a situation without mux, the midi monitor shows exactly what you would expect. In the case of the small midicontroller (the one with 2 pots and no mux: Simple Arduino Midi Controler | Starfire's Tech Blog), the midi interface circuit also does its job properly. So whatever is stopping this from working should be on the mux shield?

Ive attached two photos: one of how I wired the two pots to the arduino without mux and one with mux.

Nothing shows in the midi monitor. However, when I take the muxshield of the arduino and then connect the wires as one would in a situation without mux, the midi monitor shows exactly what you would expect. In the case of the small midicontroller

So there must be a difference. According to the schematic there is nothing that the shield is doing to the normal behavior. It is hard to see from your pictures but the ground wire looks like it is a pin out. Try using the ground on the other side. Alternatively there could be a miss soldered joint or bad socket on the extension sockets bringing the signals from the arduino to the top of the shield.

I managed to get readings in the midi monitor by pushing the back side (the side where the analog pins and the low digital ones are) of the shield further into the arduino then seems reasonalby necessary. I'm confused, because earlier - when the midi monitor showed nothing - the power led of the shield was on, so I assumed the shield was placed properly. Also, I assumed that the shield ought to be placed horizontally on the arduino. Now it's back end is significantly lower than the front side..

Although I'm happy that the midimonitor receives midi, it's still not the data I want. There seems to be something wrong with how the data are send. I think the control look up table doesn't function properly. When I want to send data from 1 potmeter with 1 Midi CC value, I receive changes of multiple Midi CCs. I attached a screenshot.

Could this have something to do with the placing of the mux shield or is it something else (like the control look up table)?
Btw, when the shield is placed not horizontally, the programm the sends midi notes works properly.

It is probbly your code. Post what you have now and I wil look at it in the morning, it's late here.

//Give convenient names to the control pins
#define CONTROL0 5    //S3
#define CONTROL1 4    //S2
#define CONTROL2 3    //S1
#define CONTROL3 2    //S0

//create temporary variables for analog input
int tempmux0;
int tempmux1;
int tempmux2;

//create char look up tables for MIDI CC
char control0[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
char control1[] = { 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 };
char control2[] = { 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48 };

//create variables which hold the pinnumbers the three muxs send their data to
int COM1 = 0;
int COM2 = 1;
int COM3 = 2;

//Create arrays for data from the the MUXs
int mux0array[16];
int mux1array[16];
int mux2array[16];


void setup()
{
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
  
//Default speed of MIDI serial port
  Serial.begin(31250);
}

void loop()
{
  //This for loop is used to scroll through and store the 16 inputs on the FIRST multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux0array[i] - tempmux0) > 2) {
        mux0array[i] = tempmux0;
        MidiTX(char(0xB0), control0[i], char(mux0array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }

  //This for loop is used to scroll through and store the 16 inputs on the SECOND multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux1 = analogRead(COM2)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux1array[i] - tempmux1) > 2) {
        mux1array[i] = tempmux1;
        MidiTX(char(0xB0), control1[i], char(mux1array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }

  //This for loop is used to scroll through and store the 16 inputs on the THIRD multiplexer
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux2 = analogRead(COM3)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux2array[i] - tempmux2) > 2) {
        mux2array[i] = tempmux2;
        MidiTX(char(0xB0), control2[i], char(mux2array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }
}

void MidiTX(byte message, byte control, byte value) 		//pass values out through standard Midi Command
{
   Serial.write(message);
   Serial.write(control);
   Serial.write(value);
}

This is for 3 multiplexers, but I've connected just two pots to pin 0 and 1 of the first mux.

OK I can't see much wrong with that other than you seem to be doing everything three times, you should be able to do it in just one loop.

Try reading each analogue input twice:-

tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127
tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127

To give the multiplexer time to settle down. What pot values are you using?

You mean like this:

//Give convenient names to the control pins
#define CONTROL0 5    //S3
#define CONTROL1 4    //S2
#define CONTROL2 3    //S1
#define CONTROL3 2    //S0

//create temporary variables for analog input
int tempmux0;
int tempmux1;
int tempmux2;

//create char look up tables for MIDI CC
char control0[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
char control1[] = { 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 };
char control2[] = { 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48 };

//create variables which hold the pinnumbers the three muxs send their data to
int COM1 = 0;
int COM2 = 1;
int COM3 = 2;

//Create arrays for data from the the MUXs
int mux0array[16];
int mux1array[16];
int mux2array[16];


void setup()
{
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
  
//Default speed of MIDI serial port
  Serial.begin(31250);
}

void loop()
{
 
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127
    tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux0array[i] - tempmux0) > 2) {
        mux0array[i] = tempmux0;
        MidiTX(char(0xB0), control0[i], char(mux0array[i]) );   //control[i] is a char look up table for the controller number to change
        }
     
    tempmux1 = analogRead(COM2)/8;  //divide by 8 to get in the range of 1-127
    tempmux1 = analogRead(COM2)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux1array[i] - tempmux1) > 2) {
        mux1array[i] = tempmux1;
        MidiTX(char(0xB0), control1[i], char(mux1array[i]) );   //control[i] is a char look up table for the controller number to change
        }

    tempmux2 = analogRead(COM3)/8;  //divide by 8 to get in the range of 1-127
    tempmux2 = analogRead(COM3)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux2array[i] - tempmux2) > 2) {
        mux2array[i] = tempmux2;
        MidiTX(char(0xB0), control2[i], char(mux2array[i]) );   //control[i] is a char look up table for the controller number to change
        }
  }
}

void MidiTX(byte message, byte control, byte value) 		//pass values out through standard Midi Command
{
   Serial.write(message);
   Serial.write(control);
   Serial.write(value);
}

Still the same problem..
I'm using one pot of 100 k Ohm and one of 250 k Ohm. But again this has worked before for a small midi controller, so I don't see why this wouldn't work now.

Do you mean that you only have two pots wired up and the rest are open circuit? If so that will produce the result you are seeing. The inputs will be floating and picking up stuff from the other channels when they are changed. Try putting a 10K pull down on unconnected inputs or change the software so you only look at wired up inputs.

So I wired up 16 potmeters to the first multiplexer and cut out the code for the second and third mux

//Give convenient names to the control pins
#define CONTROL0 5    //S3
#define CONTROL1 4    //S2
#define CONTROL2 3    //S1
#define CONTROL3 2    //S0

//create temporary variables for analog input
int tempmux0;

//create char look up tables for MIDI CC
char control0[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };


//create variables which hold the pinnumbers the three muxs send their data to
int COM1 = 0;


//Create arrays for data from the the MUXs
int mux0array[16];


void setup()
{
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
  
//Default speed of MIDI serial port
  Serial.begin(31250);
}

void loop()
{
 
  for (int i=0; i<16; i++)
  {
    //The following 4 commands set the correct logic for the control pins to select the desired input
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
     
    
    tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127
    tempmux0 = analogRead(0)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux0array[i] - tempmux0) > 2) {
     mux0array[i] = tempmux0;
        MidiTX(char(0xB0), control0[i], char(mux0array[i]) );   //control[i] is a char look up table for the controller number to change
       }
   
  }
}

void MidiTX(byte message, byte control, byte value) 		//pass values out through standard Midi Command
{
   Serial.write(message);
   Serial.write(control);
   Serial.write(value);
}

and nothing showed in the midi monitor. Then I tried it again with 16 potmeters and the whole code for 3 MUXs and got the old problem again. However, not all pots seemed to be working. Some showed nothing in the midi monitor upon twisting and some did. With one potmeter, I tried to find out why. It turned out that the pins 8,9,15,0,1 returned values to the midimonitor and the other pins didn't send anything (or maybe the computer didn't receive it - I don't know).

and nothing showed in the midi monitor.

Wrong formulation, I meant that the same problem still occurred. About the pins, I tested it today and now only pin 0 and 1 showed signs of life. I'm beginning to wonder whether my mux shield is broken...

I'm beginning to wonder whether my mux shield is broken...

That has crossed my mind especially with placements at a jaunty angle to get things working.