Pages: [1] 2   Go Down
Author Topic: [SOLVED]: Analog values through multiplexer are very inconsistent!  (Read 2043 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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!
« Last Edit: June 18, 2012, 03:48:03 am by dieselboris » Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

-Arne

Montreal
Offline Offline
Faraday Member
**
Karma: 29
Posts: 2590
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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:
//////////////////////////////////////////////////////////////////
//©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;
}


* IMAG0206.jpg (950.83 KB, 2592x1552 - viewed 51 times.)
« Last Edit: June 16, 2012, 10:03:48 am by dieselboris » Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
for (int8_t i=3; i>=0; i--) digitalWrite(cl[i],channel&(1<<i));
smiley
« Last Edit: June 16, 2012, 01:04:46 pm by RIDDICK » Logged

-Arne

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12169
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

[ I won't respond to messages, use the forum please ]

Anaheim CA.
Offline Offline
Faraday Member
**
Karma: 47
Posts: 2891
...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:

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







* IMAG0208.jpg (465.55 KB, 2592x1552 - viewed 46 times.)
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

still not pinMode() call?

i mean code like this in setup():
Code:
pinMode(s0,OUTPUT);
pinMode(s1,OUTPUT);
pinMode(s2,OUTPUT);
pinMode(s3,OUTPUT);
so that the mux-config-arduino-pins r low-impedance pins...
« Last Edit: June 17, 2012, 10:53:19 am by RIDDICK » Logged

-Arne

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What value of capacitor? Make it smaller.
Code:
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:
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);
 
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

still not pinMode() call?

i mean code like this in setup():
Code:
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!
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
hmm according to the tutorial in bildr its not neccessary,
No you misread that.
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
nut i'll give it try!
yup - give it a try...  *wag tail* smiley-wink
Logged

-Arne

Pages: [1] 2   Go Up
Jump to: