Mux Shield

Hi there,

While working on a midicontroller, i’m using a mux shield (/1/]http://mayhewlabs.com/products/arduino-mux-shield#!prettyPhoto[gallery]/1/)to increase the number of (analog) inputs i can use on the arduino uno. Now, i’ve got a little midicontroller with just 2 analogs and 1 digital working and everythings seems to work just fine. I used this setup: http://starfiretech.wordpress.com/2009/12/08/simple-arduino-midi-controler/

As i said, i want to use the mux shield to increase the number of inputs. When i use the code given on the mux shield site (the analog input example) the midi monitor gives all kinds of weird stuff, i added a screenshot of the midi monitor.

It says something about a timing clock, but as far is i know it isn’'t supposed to do that… Anyone knows why it does that? And if you know how to use the mux shield, any ideas on how i can read analog pins and print the result of a potmeter change over midi?

Grtz

I can only think you have wired it up wrong. The example code does not use the serial port so you must have added code to get an output, either that or you left the MIDI connected when you uploaded the code and you got rubbish.

So post the code you are actually using.

I pretty sure I did disconnect the MIDI device when uploading the example code, but I just tried it again and as one would expect the midi monitor showed nothing :).

I''m using this code to send midi data to the computer when the potmeters value is changed:

void setup()
{
   Serial.begin(31250);                                     // Default speed of MIDI serial port
   pinMode(13, OUTPUT);                                     // Light LED on pin 13 to notify of readynes
   digitalWrite(13, HIGH);
}

int iAn0Val, iAn1Val;

void loop()
{
   //Slider X
   int iAn0ValPrev = iAn0Val;                              //Get the previous value of slider X
   iAn0Val = analogRead(0)/8;
   analogPinMidiTX(1,iAn0Val,iAn0ValPrev);                         //TX the value of slider X
   
   //Slider Y
   int iAn1ValPrev = iAn1Val;                              //Get the previous value of slider Y
   iAn1Val = analogRead(1)/8;
   analogPinMidiTX(2,iAn1Val,iAn1ValPrev);                         //TX the value of slider Y
}

void analogPinMidiTX(int iChan, int iVal, int iValPrev)
{  
                                           //only TX the value over midi if it is changed, as to prevent spamming the midi port and thus confusing the receiving application in learning mode
  if(iValPrev != iVal)
  {
    MidiTX(176,iChan,iVal);
  }
}

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);
}

How do i get the arduino via the muxshield to read a lot of analog inputs? I assume there must be a way to alter the example code and implement the code written above to achieve this...

Grtz

How do i get the arduino via the muxshield to read a lot of analog inputs?

Just before you read the analogue input you write out to the multiplex select lines the bit pattern of the channel you want to read. If you had a variable i that holds the channel number of the input you want to read then:-

   // select multiplexer channel
   digitalWrite(s0Pin, i & 0x1);
   digitalWrite(s1Pin, (i>>1) & 0x1);
   digitalWrite(s2Pin, (i>>2) & 0x1);

With s0Pin etc. being the pin numbers of the multiplex select lines.

This is an extract from my project:- http://www.thebox.myzen.co.uk/Hardware/MIDI_Footsteps.html Which reads in 16 analogue sensors. see the project for the schematic, it will be the same idea as your shield but will probably use different select pins.

I have not been able to work on my project for a while due to exams, but i have finished them now..

What i don't understand is how i can integrate the code i was using to read analog inputs in the example code for reading the multiplexer. Where do i need to write the lines to select the multiplexer channel, where does my own code fit in the example code and should the example code be altered or just stay the same?

I've been trying everything that would seem logic to me, but it seems i'm really stuck on this one. Any help would be greatly appreciated :).

Greets,

So post what you think is right. Basically you set up your multiplexer select pins, then read the analogue pin it is connected to.

This is what i ended with, which is obviously not right :).

 //Give convenient names to the control pins
#define CONTROL0 5    
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 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(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
    
    int s0Pin = 0 
    digitalWrite(s0Pin, i & 0x1);
    //Read and store the input value at a location in the array
    mux0array[i] = analogRead(0);
  }	  
   //Slider X
   int iAn0ValPrev = iAn0Val; 								//Get the previous value of slider X
   iAn0Val = analogRead(0)/8;
   analogPinMidiTX(1,iAn0Val,iAn0ValPrev); 

  
 //The following lines are for printing out results of array0
  Serial.print("mux0array: ");
  for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }
  Serial.println();  //line feed
  
void analogPinMidiTX(int iChan, int iVal, int iValPrev)
{  
  											//only TX the value over midi if it is changed, as to prevent spamming the midi port and thus confusing the receiving application in learning mode
  if(iValPrev != iVal)
  {
    MidiTX(176,iChan,iVal);
  }
}
}
  
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);
}

First of all, this is the error log i get when i try to upload the programm:

sketch_jun25a.cpp: In function ‘void loop()’:
sketch_jun25a:37: error: expected ‘,’ or ‘;’ before ‘digitalWrite’
sketch_jun25a:39: error: ‘iAn0Val’ was not declared in this scope
sketch_jun25a:41: error: ‘analogPinMidiTX’ was not declared in this scope
sketch_jun25a:54: error: a function-definition is not allowed here before ‘{’ token
sketch_jun25a:68: error: expected `}’ at end of input

As i said before, i’m not sure how the two parts of code (example code and what i was using before) should fit together.
Furthermore, i left out the parts where the second and third multiplexer are scrolled trough and printed as to make the whole thing a little more clear.

I’m not sure whether there should be a digitalWrite(CONTROL2, …) and a digitalWrite(s0Pin, …) or that both are used to accomplish the same thing.
I’m not sure how to use the analogPinMidiTX and analogRead() to read the values off the multiplexer and i’m not sure whether the results should be printed of the arrays…

First of all, this is the error log i get when i try to upload the programm:

These are syntax errors, that means you made a mistake in writing the code so the compiler could not understand it.
Basically you missed out a ; you put a } in the wrong place and you did not declare a variable before you used it.
This is the “corrected” version.

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

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

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(CONTROL1, (i&7)>>2);  
    digitalWrite(CONTROL2, (i&3)>>1);  
    digitalWrite(CONTROL3, (i&1));     
    
    int s0Pin = 0; 
    digitalWrite(s0Pin, i & 0x1);
    //Read and store the input value at a location in the array
    mux0array[i] = analogRead(0);
  }	  
   //Slider X
   int iAn0ValPrev = iAn0Val; 								//Get the previous value of slider X
   iAn0Val = analogRead(0)/8;
   analogPinMidiTX(1,iAn0Val,iAn0ValPrev); 

  
 //The following lines are for printing out results of array0
  Serial.print("mux0array: ");
  for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }
  Serial.println();  //line feed
} 
void analogPinMidiTX(int iChan, int iVal, int iValPrev)
{  
  											//only TX the value over midi if it is changed, as to prevent spamming the midi port and thus confusing the receiving application in learning mode
  if(iValPrev != iVal)
  {
    MidiTX(176,iChan,iVal);
  }
}
  
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 say “corrected” because although it now compiles I suspect there are still logical errors in it.

Take this line:-

//Slider X
   int iAn0ValPrev = iAn0Val;

iAn0Val has not been previously defined.
Also the line before it:-

int iAn0ValPrev = iAn0Val;

Is creating a new variable each time that line is executed. You want to define this outside of the loop() function so that it is a global variable and it’s value is preserved from one iteration of the loop to another.
So that line should just read:-

iAn0ValPrev = iAn0Val;

and you should have a line saying:

int iAn0ValPrev = 0;

At the start of your code outside any function.

The line:-

    int s0Pin = 0; 
    digitalWrite(s0Pin, i & 0x1);

Will define a new variable called s0Pin 16 times and each time it will assign the value of 0 to it. So you write to pin 0 which is one of the serial lines, so that is wrong. What are you trying to do here?
You also seem to have missed out writing to CONTROL0 pin, so you are not setting all 4 select lines.

I know this sounds a lot but you are very close to getting it going.

i defined s0Pin, iAn0Val and iAn0ValPrev at the beginning of the programm and added the CONTROL0 line. I think i accidently deleted it when i deleted some comments written above it. The programm loads now, but i still don’t get exactly how it works. Anyways this is what i have now:

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

int s0Pin = 0;
int iAn0Val;
int iAn0ValPrev = 0;

//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));     
     
    digitalWrite(s0Pin, i & 0x1);
    //Read and store the input value at a location in the array
    mux0array[i] = analogRead(0);
  }	  
   //Slider X
   iAn0ValPrev = iAn0Val; 								//Get the previous value of slider X
   iAn0Val = analogRead(0)/8;
   analogPinMidiTX(1,iAn0Val,iAn0ValPrev); 

  
 //The following lines are for printing out results of array0
  Serial.print("mux0array: ");
  for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }
  Serial.println();  //line feed
} 
void analogPinMidiTX(int iChan, int iVal, int iValPrev)
{  
  											//only TX the value over midi if it is changed, as to prevent spamming the midi port and thus confusing the receiving application in learning mode
  if(iValPrev != iVal)
  {
    MidiTX(176,iChan,iVal);
  }
}
  
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);
}

what about the arrays, i don’t understand how i use them in the part where they are printed. For example, what exactly does this do:

Serial.print("mux0array: ");

Do i really need this part?

And where do i read the value of the mux channels; is that here

mux0array[i] = analogRead(0);

, here

  Serial.print("mux0array: ");
  for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }

, another line or do i need to add a few lines (i suspect it’s the mux0array = analogRead(0))?

For a start the control pins look to be the wrong way round. You normally have 0 as the least significant bit, so your code should look like:-

digitalWrite(CONTROL3, (i&15)>>3);
    digitalWrite(CONTROL2, (i&7)>>2);  
    digitalWrite(CONTROL1, (i&3)>>1);  
    digitalWrite(CONTROL0, (i&1));

This line

Serial.print("mux0array: ");

Just prints the message mux0array:, it doesn’t do anything with the value, anything between quotes is simply sent out to the display.
When you do

mux0array[i] = analogRead(0);

You put the value of what is on the analogue port into a variable, the actual one depends on the value of i. It is like saying put this letter into the door number i in the street called mux0array, so as the value of i changes so you change the door where you post ( store ) the value.

for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }

That bit is a loop which prints out the contents of every door in the street.

But since i want to send a midi signal and not a serial signal and at the end of the sketch i have

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);
}

,doesn’t this mean i can get rid of the whole serial.print part? I don’t see the need for

  for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
  }
  Serial.println();  //line feed
}

when i want to send midi.

Then to select the pins i would use

digitalWrite(s0Pin, i & 0x1);

and so on. Then i would want to store the values of those pins in the array, so that would be

mux0array[i] = analogRead(s0Pin)/8  //divide by 8 to get in the range of 1-127

Finally i would use something like to get the values from the array.

iAn0Val = mux0array[i]

Is this in the direction of how i’m supposed to use the shield??

doesn't this mean i can get rid of the whole serial.print part?

Yes, you only have it in at the moment for testing.

Then i would want to store the values of those pins in the array

What you want to do is to store the values you send in the array and only send a value when what you read is not what is in the array. Otherwise you will swamp the MIDI receiver with duplicate values.

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

I tried to fit the code into the sketch i already had. This is what I came up with:

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

int s0Pin = 0;
int iAn0Val;
int iAn0ValPrev = 0;
int temp;
int control[4];

//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(CONTROL3, (i&15)>>3);
    digitalWrite(CONTROL2, (i&7)>>2);  
    digitalWrite(CONTROL1, (i&3)>>1);  
    digitalWrite(CONTROL0, (i&1));     
     
    digitalWrite(s0Pin, i & 0x1);
    temp = analogRead(s0Pin)/8;  //divide by 8 to get in the range of 1-127
    if( abs(mux0array[i] - temp) > 2) {
        mux0array[i] = temp;
        MidiTX(char(0xB0), control[i], char(mux0array[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);
}

The error log gives nothing when I upload the programm and I’m pretty confident that this - or something like it - should work. One question though: I thought the size of control should be 4, because of the 4 control select pins. Is that right?
I’m not receiving midi yet, but I suspect that I didn’t wire up the shield the right way. Working on that!

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.