How to properly read values from analog sensors trough multiplexer?

I need to read several analog sensors on a Arduino Mega ADK. I want to use a multiplexer for this (CD74HC4067E), see the schematics.

The output however from the multiplexer channels is not consistent with the output which i read directly from on the analog input:

Through the Mux x: 333   y: 276  z: 323      Direct analog readings x: 328 | y: 334 | z: 285
Through the Mux x: 333   y: 276  z: 321      Direct analog readings x: 328 | y: 335 | z: 277
Through the Mux x: 334   y: 276  z: 322      Direct analog readings x: 329 | y: 335 | z: 277
Through the Mux x: 333   y: 276  z: 324      Direct analog readings x: 328 | y: 334 | z: 283
Through the Mux x: 333   y: 276  z: 299      Direct analog readings x: 329 | y: 335 | z: 282


ALthough it might seem that there is a wiring problem (simply switch X and Z), my setup is correct (triple checked!).

When i turn the sensor 90 degrees clockwise so that Y is up, i get the following:

Through the Mux x: 334   y: 344  z: 270      Direct analog readings x: 266 | y: 334 | z: 344
Through the Mux x: 334   y: 345  z: 269      Direct analog readings x: 265 | y: 334 | z: 344
Through the Mux x: 333   y: 343  z: 271      Direct analog readings x: 264 | y: 333 | z: 343
Through the Mux x: 335   y: 344  z: 270      Direct analog readings x: 265 | y: 334 | z: 344


so it seems that the X and Z pins should be switched.

I can i improve this?

And my arduino code:

//to hold direct read from the analog output of the ADXL335

//to hold readings from the mux:

//mux pins
int s0 = 8;
int s1 = 9;
int s2 = 10;
int s3 = 11;

//The pin on which the Mux outputs
int SIG_pin = A0;

const int xPin = A8;
const int yPin = A9;
const int zPin = A10;

void setup(){
Serial.begin(9600);
}

void loop(){

//read value on channel 0 of Mux
delay(100); //to let the capacitator discharge

//read value on channel 1 of Mux
delay(100); //to let the capacitator discharge

//read value on channel 2 of Mux
delay(100); //to let the capacitator discharge

Serial.print("Through the Mux x: ");
Serial.print("\t y: ");
Serial.print("\t z: ");

Serial.print("\t\t Direct analog readings x: ");
Serial.print(" | y: ");
Serial.print(" | z: ");
Serial.println("");
delay(100);//just here to slow down the serial output - Easier to read
}

//this is verbose but it works, and is more readable (i need that :)

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 i = 0; i < 4; i ++){
digitalWrite(controlPin[i], muxChannel[channel][i]);
}
//read the value at the SIG pin

//return the value
return val;
}

• On the schematic, S0 is connected to pin 9, but in the code you have int s0 = 8; Why is that ? – Rocketmagnet Jun 17 '12 at 15:40
• that's a mistake in the drawing, the code is correct. sorry – jorrebor Jun 17 '12 at 22:38
• I didn't see this comment before my answer, but you have other mistakes as well. I would definitely update your schematic exactly as you have your circuit breadboarded, then post the update so we can check it again. – Dave Jun 18 '12 at 13:11

You simply have switched Y and Z on the multiplexer.

• no it's not the case unfortunatly.. see my edit. – jorrebor Jun 17 '12 at 15:15

For starters, I would make your wiring follow a more logical ordering. For example, upon looking at your schematic, you have 8 going to S1, 9 going to S0, 10 going to S3, and 11 going to S2. The truth table for your chip goes from S0-S3, LSB first, so you have 8 and 9 swapped, and 10 and 11 swapped. Also, you have A8 going to Y and A9 going to X, but your code says that xPin is 8, and yPin is 9. I'd fix these issues first and then try again.

To summarize, the value you're reading to check your multiplexer is the wrong one (for Y and X), and your MUX mapping is also wrong, so when you loop over the channels, you're not switching to the input that you want.

• sorry, the schema was wrong. It works now thank you – jorrebor Jun 19 '12 at 19:45

i didnt set the pinmode in the setup:

pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
...


when the pins are not initialized in the setup they float between 0 and 1. The readings i got where more luck than wisdom.

After adding initialisation, i also didnt need the capacitator any more.

• Did this resolve your issue? If so can you give a bit more detail about this issue. – Kortuk Jun 18 '12 at 13:12