Go Down

Topic: [SOLVED]: Analog values through multiplexer are very inconsistent! (Read 2557 times) previous topic - next topic

dieselboris

Jun 16, 2012, 02:30 pm Last Edit: Jun 18, 2012, 10:48 am by dieselboris Reason: 1
Hi all,

I need to read 4 analog accelerometers. I thought of using a multiplexer for this (i took the CD74HC4067E for this). I wired everything up the way it should but my values are very inconsistent in comparison to reading the values directly.

These values come from the same sensor, the left ones come trough the multiplexer, the right ones are read directly.

Code: [Select]
x: 309 | y: 320 | z: 317 x: 331 | y: 329 | z: 273
x: 367 | y: 259 | z: 373 x: 331 | y: 329 | z: 273
x: 332 | y: 285 | z: 332 x: 331 | y: 329 | z: 273
x: 259 | y: 348 | z: 262 x: 331 | y: 329 | z: 273
x: 267 | y: 353 | z: 275 x: 331 | y: 329 | z: 273
x: 332 | y: 290 | z: 344 x: 331 | y: 329 | z: 273
x: 364 | y: 260 | z: 367 x: 331 | y: 329 | z: 273
x: 313 | y: 299 | z: 313 x: 331 | y: 329 | z: 273
x: 251 | y: 358 | z: 253 x: 331 | y: 329 | z: 273
x: 282 | y: 341 | z: 291 x: 331 | y: 329 | z: 273


I tried using delays in between reads from the multiplexer channels but no luck.

I'm in the dark here, please help!

RIDDICK

i use the 4067, 2...
and i dont c such big variations...
the capacitance and resistance introduced by the 4067 r quite small...

can u show us the program and cabling u use?

r u possibly reading from a wrong mux line?

what if u dont change the mux line and read again and again?
does it get stable then?
-Arne

Magician

How fast do you scan mux inputs?  Is analogRead and scan function synchronous?

Grumpy_Mike

Have you got decoupling on the multiplexer chips?
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Are you suffering from cross talk, that is one channel affecting the other?
To test:-
Start off with only one channel connected, connect it also through another chip analogue input look at the readings are they similar.
Then add more channels but don't look at them in the software. Do they now behave differently?

dieselboris

#4
Jun 16, 2012, 04:41 pm Last Edit: Jun 16, 2012, 05:03 pm by dieselboris Reason: 1
EDIT: I removed all references to any analog read and my program is just reading channel 0 at the mux and still a lot of deviation.....

EDIT 2: the chip was left unpowered, i'll run another test sorry about this.

Thanks to all for the quick replies!

Ok these values come out when using only one channel:

Code: [Select]
x: 330 x: 330 | y: 330 | z: 273
x: 91 x: 330 | y: 330 | z: 273
x: 100 x: 330 | y: 330 | z: 272
x: 330 x: 330 | y: 330 | z: 273
x: 143 x: 331 | y: 330 | z: 273
x: 325 x: 330 | y: 330 | z: 273
x: 48 x: 330 | y: 330 | z: 273
x: 119 x: 330 | y: 330 | z: 273
x: 330 x: 330 | y: 330 | z: 273
x: 133 x: 330 | y: 330 | z: 273
x: 60         x: 330 | y: 330 | z: 273
x: 330 x: 330 | y: 330 | z: 273
x: 133 x: 330 | y: 330 | z: 273
x: 330 x: 330 | y: 330 | z: 273
x: 121 x: 331 | y: 330 | z: 273
x: 47         x: 330 | y: 330 | z: 273
x: 330 x: 330 | y: 330 | z: 273


still all over the place.

So try to decouple the power source of the multiplexer. I put a capacitator from 0.047 uF from the power pin of the multiplexer to ground.

these are the values i get:

Code: [Select]
x: 331 x: 331 | y: 330 | z: 273
x: 135 x: 331 | y: 330 | z: 273
x: 68 x: 331 | y: 330 | z: 273
x: 331 x: 331 | y: 330 | z: 273
x: 163 x: 331 | y: 330 | z: 273
x: 331 x: 331 | y: 329 | z: 273
x: 121 x: 331 | y: 330 | z: 273
x: 91 x: 331 | y: 330 | z: 273
x: 331 x: 331 | y: 330 | z: 273
x: 158 x: 331 | y: 330 | z: 273
x: 331 x: 331 | y: 330 | z: 272
x: 97 x: 331 | y: 330 | z: 273


not much difference.

The wiring is in the attachment, hope it's clear.

Thanks again!

This is the code i'm using:

Code: [Select]

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Simple code for the ADXL335, prints calculated orientation via serial
//////////////////////////////////////////////////////////////////

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

//Mux in "SIG" pin
int SIG_pin = 0;

//Analog read pins
const int xPin = A8;
const int yPin = A9;
const int zPin = A10;

void setup(){
 Serial.begin(57600); //does the speed matter?
}

void loop(){

 //read the analog values from the accelerometer
 int xRead = readMux(0);
 int xReadDirect = analogRead(xPin);
 //int yRead = readMux(1);
 int yReadDirect = analogRead(yPin);  
 //int zRead = readMux(2);
 int zReadDirect = analogRead(zPin);

 //Output the caculations
 Serial.print("x: ");
 Serial.print(xRead);  
 Serial.print("\t x: ");
 Serial.print(xReadDirect);
 Serial.print(" | y: ");
 Serial.print(yReadDirect);
 Serial.print(" | z: ");
 Serial.println(zReadDirect);
 
 delay(10);//just here to slow down the serial output - Easier to read
}


int readMux(int channel){

 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
 };
 delay(40);//maybe it helps??
 //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
 int val = analogRead(SIG_pin);

 //return the value
 return val;
}

Grumpy_Mike

It is hard to tell what is going on because the output you post is not from the code you post.
The wiring is not much help, better would be a schematic of what you are trying to do.

It is not immediately clear you are doing what I said. Is the first X through the multiplexer and the second one direct? It would imply that you are not getting correct power to the multiplexer or you have something like a floating enable pin or some such.

The code for setting the multiplexer's select line is rather verbose.
You can do it like this:-
Code: [Select]
for(int i=0; i<16; i++){
   // select multiplexer channel
   digitalWrite(s0Pin, i & 0x1);
   digitalWrite(s1Pin, (i>>1) & 0x1);
   digitalWrite(s2Pin, (i>>2) & 0x1);
  digitalWrite(s3Pin, (i>>3) & 0x1);
// now read the multiplexer

In general the output from an accelerometer is not the most stable of signals.
Quote
I put a capacitator from 0.047 uF from the power pin of the multiplexer to ground.

A bit low normally you would use a 0.1uF, don't remove it you need it even if you do not see an immediate change. I would also add some on the supply to your accelerometer boards.

RIDDICK

#6
Jun 16, 2012, 08:01 pm Last Edit: Jun 16, 2012, 08:04 pm by RIDDICK Reason: 1
where do u set the pinMode of the MUX control lines?
or is it not necessary anymore...?
i still use those old arduinos duemil...
http://arduino.cc/en/Reference/PinMode

i have another suggestion (in case u like loops):
Code: [Select]
for (int8_t i=3; i>=0; i--) digitalWrite(cl[i],channel&(1<<i));
:)
-Arne

MarkT

From the photo I can't be sure that pins 13 and 14 are both low - address inputs A3 and A2 respectively, these need to be low to select the correct set of inputs (in particular pin 14 has a red wire not a blue one, which implies you are selecting channels 4/5/6 rather than 0/1/2.  The signal wires are going into pins 9,8,7 (channels 0,1,2).

The leakage current specification is upto 0.8uA for switches in the off state, plenty large enough to explain your readings.
[ I won't respond to messages, use the forum please ]

Docedison

Quote
The leakage current specification is upto 0.8uA for switches in the off state, plenty large enough to explain your readings.
only if the source impedance was as high as the input impedance of the processor. what does the spec sheet say about output impedance or available load current? since you didn't see fit to post the sensor information anything beyond power supply bypassing is a waste of time... My Crystal Ball has been broken since it told me I was ugly...

Doc
--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

dieselboris

Hello again!

I have put a capacitor on the output of the mux and the readings are much more consistent. However, it seems that the capacitor just holds the voltage to long, so that for the next read the output is too high. My readings:

Code: [Select]

Through the Mux x: 274 y: 310 z: 333 Direct analog readings x: 332 | y: 333 | z: 277
Through the Mux x: 274 y: 332 z: 333 Direct analog readings x: 332 | y: 334 | z: 276
Through the Mux x: 274 y: 306 z: 329 Direct analog readings x: 332 | y: 333 | z: 277
Through the Mux x: 277 y: 310 z: 331 Direct analog readings x: 332 | y: 333 | z: 277
Through the Mux x: 274 y: 305 z: 331 Direct analog readings x: 333 | y: 335 | z: 277
Through the Mux x: 274 y: 314 z: 325 Direct analog readings x: 332 | y: 332 | z: 276
Through the Mux x: 310 y: 310 z: 331 Direct analog readings x: 332 | y: 334 | z: 277



It seems that the readings on the channel 0 are actually from the z pin on the sensor. when i position the sensor vertically the readings become:

Code: [Select]


Through the Mux x: 349 y: 295 z: 332 Direct analog readings x: 264 | y: 296 | z: 349
Through the Mux x: 350 y: 268 z: 334 Direct analog readings x: 266 | y: 334 | z: 350
Through the Mux x: 352 y: 271 z: 336 Direct analog readings x: 266 | y: 334 | z: 350


the readings from x pin on the sensor are now visible on the y channel (channel 1 in the code) of the multiplexer. How is this delay introduced.

I have drawn the schematics, see the attachment. When I keep the accelerometer flat the readings on from the analog pins are correct. I have used a delay of even 1000 ms to let the capacitor discharge but no luck. I also have connected GND to channel 15 on the mux and have this channel read in order to "clear" the output pin. But all output became 0.

About crosstalking: if read only one channel in the software but leave all the wires in place then the readings are correct, even if delays are set to 1ms.

What else can i do to prevent and test?

The datasheet of the mux is found here http://datasheet.octopart.com/CD74HC4067E-Texas-Instruments-datasheet-151719.pdf

and my code:

Code: [Select]

//to hold direct read from the analog output of the ADXL335
int xAnaRead;
int yAnaRead;
int zAnaRead;

//to hold readings from the mux:
int xMuxRead;
int yMuxRead;
int zMuxRead;

//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;

//Analog read pins
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
  xMuxRead = readMux(0); 
  //read analog value
  int xAnaRead = analogRead(xPin);
  delay(100); //to let the capacitator discharge

  //read value on channel 1 of Mux
  yMuxRead = readMux(1); 
  //read analog value
  int yAnaRead = analogRead(yPin);
  delay(100); //to let the capacitator discharge

  //read value on channel 2 of Mux
  zMuxRead = readMux(2); 
  //read analog value
  int zAnaRead = analogRead(zPin);
  delay(100); //to let the capacitator discharge


  //Output the readings
  Serial.print("Through the Mux x: ");
  Serial.print(xMuxRead); 
  Serial.print("\t y: ");
  Serial.print(yMuxRead); 
  Serial.print("\t z: ");
  Serial.print(zMuxRead); 

  Serial.print("\t\t Direct analog readings x: ");
  Serial.print(xAnaRead);
  Serial.print(" | y: ");
  Serial.print(yAnaRead);
  Serial.print(" | z: ");
  Serial.print(zAnaRead);
  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 readMux(int channel){

  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
  int val = analogRead(SIG_pin);

  //return the value
  return val;
}







RIDDICK

#10
Jun 17, 2012, 05:51 pm Last Edit: Jun 17, 2012, 05:53 pm by RIDDICK Reason: 1
still not pinMode() call?

i mean code like this in setup():
Code: [Select]
pinMode(s0,OUTPUT);
pinMode(s1,OUTPUT);
pinMode(s2,OUTPUT);
pinMode(s3,OUTPUT);

so that the mux-config-arduino-pins r low-impedance pins...
-Arne

Grumpy_Mike

What value of capacitor? Make it smaller.
Code: [Select]
int xAnaRead = analogRead(xPin);
 delay(100); //to let the capacitator discharge

 //read value on channel 1 of Mux
 yMuxRead = readMux(1);  



This delay is doing nothing because it is while the input is switched through you need to do this:-
Code: [Select]
int xAnaRead = analogRead(xPin);
 delay(100); //to let the capacitator discharge
 xAnaRead = analogRead(xPin); // now read the value once it has discharged
 //read value on channel 1 of Mux
 yMuxRead = readMux(1);
 delay(100); //to let the capacitator discharge
   yMuxRead = readMux(1);

dieselboris


still not pinMode() call?

i mean code like this in setup():
Code: [Select]
pinMode(s0,OUTPUT);
pinMode(s1,OUTPUT);
pinMode(s2,OUTPUT);
pinMode(s3,OUTPUT);

so that the mux-config-arduino-pins r low-impedance pins...


hmm according to the tutorial in bildr its not neccessary, nut i'll give it try!

Grumpy_Mike

Quote
hmm according to the tutorial in bildr its not neccessary,

No you misread that.

RIDDICK

Quote
nut i'll give it try!

yup - give it a try...  *wag tail* ;)
-Arne

Go Up