Pages: [1] 2   Go Down
Author Topic: Trying to measure input voltage... Doing something wrong.  (Read 1749 times)
0 Members and 1 Guest are viewing this topic.
Seattle, WA
Offline Offline
God Member
*****
Karma: 7
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying to measure the "Vin" voltage into my 3V3 Arduino on an analog input pin.  This is to monitor how the battery is doing.  Because the Vin voltage is higher than the Vcc voltage, there is a voltage divider circuit to cut the voltage down by 1.5x.  There is a 1M resistor from A5 to ground, and a 500k from A5 to Vin.

This actually works reasonably well as long as the ONLY thing being read is the analog pin connected to the voltage divider.

The problem comes when reading ANOTHER analog pin.  In this case there is a a temp sensor which is really the point of the application, so that MUST get read.  Introducing the reading of the temp sensor into the mix hoses the values I get back on my voltage reading.

Here is some sample code

Code:
const int voltage_pin = A5;
const int temp_pin = A4;

void setup(void)
{
  Serial.begin(57600);
  Serial.println("adc_test");
}

void loop(void)
{
  Serial.print("temp=");
  Serial.println(analogRead(temp_pin),DEC);
  Serial.print("volt=");
  Serial.println(analogRead(voltage_pin),DEC);
  delay(1000);
}

Running it, I get the following:

Code:
adc_test
temp=221
volt=883
temp=221
volt=869
temp=223
volt=885
temp=223
volt=900
temp=225
volt=870
temp=224
volt=924
temp=223
volt=881
temp=223
volt=869
temp=224

But if I comment out the temp reading, I get more reasonable values:

Code:
adc_test
volt=980
volt=985
volt=985
volt=986
volt=985

Anyone have thoughts on what needs to be done to get this right?  Thanks!
« Last Edit: May 16, 2011, 07:53:50 am by maniacbug » Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 436
Posts: 23623
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The ADC circuit has a Sample and Hold capacitor that charges up and is then converted.
Your large resistor values don't let much current in for that to happen, just a few microamps.
Put a little delay between the 2 read types, should help the 800+  numbers look more like the 900+ numbers.
Or, lower the 500K/1M values.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

0
Offline Offline
Shannon Member
****
Karma: 159
Posts: 10409
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The spec says the ADC wants signals with a source impedance of 10k or less for reliable measurements.

Change your voltage divider to use 10k and 4k7 resistors.
Logged

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

Seattle, WA
Offline Offline
God Member
*****
Karma: 7
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The spec says the ADC wants signals with a source impedance of 10k or less for reliable measurements.

Change your voltage divider to use 10k and 4k7 resistors.

Oooh..  Wow, ok, thanks.  Reading through the ADC part of the data sheet, I just could not figure that out.

That's rough, though.  So at 10k impedance, that circuit is going to burn 0.33mA, right?  As it stands now, this unit uses 0.12mA on average, so this would quadruple my current usage just to measure current usage...  Taking 20 months out of my battery life!  Yikes.

The thing is, when I read the values by themselves, I get better readings.  They're still a little off from what I'd expect, but not by 100+.

Tonight I'll run some tests against CR's suggestion too.
« Last Edit: May 16, 2011, 08:05:58 pm by maniacbug » Logged


Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
That's rough, though.  So at 10k impedance, that circuit is going to burn 0.33mA, right?  As it stands now, this unit uses 0.12mA on average, so this would quadruple my current usage just to measure current usage...  Taking 20 months out of my battery life!  Yikes.

Time for a "low side switch"?  You can then "turn off" the voltage divider when you are not measuring the battery voltage (you should only need to take a measurement every few minutes, hours, or possibly days).
Logged

Seattle, WA
Offline Offline
God Member
*****
Karma: 7
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Put a little delay between the 2 read types, should help the 800+  numbers look more like the 900+ numbers.

Tried that, to no avail.  Here's the new sample...

Code:
const int voltage_pin = A5;
const int temp_pin = A4;

unsigned long interval = 250; // ms
const unsigned long increase = 250; // ms

void setup(void)
{
  Serial.begin(57600);
  Serial.println("adc_test");
}

void loop(void)
{
  Serial.print("delay=");
  Serial.print(interval,DEC);
  Serial.print(" temp=");
  Serial.print(analogRead(temp_pin),DEC);
  delay(interval);
  Serial.print(" volt=");
  Serial.println(analogRead(voltage_pin),DEC);
  delay(interval);
 
  interval += increase;
}

...and the output:

Code:
adc_test
delay=250 temp=217 volt=908
delay=500 temp=218 volt=901
delay=750 temp=220 volt=882
delay=1000 temp=220 volt=899
delay=1250 temp=220 volt=867
delay=1500 temp=220 volt=886
delay=1750 temp=220 volt=874
delay=2000 temp=220 volt=875
delay=2250 temp=220 volt=886
delay=2500 temp=213 volt=879
delay=2750 temp=220 volt=883
delay=3000 temp=220 volt=874
delay=3250 temp=219 volt=900
delay=3500 temp=220 volt=909
delay=3750 temp=220 volt=870
delay=4000 temp=220 volt=909
delay=4250 temp=213 volt=871
delay=4500 temp=220 volt=883
delay=4750 temp=220 volt=920
delay=5000 temp=220 volt=894
delay=5250 temp=219 volt=889
delay=5500 temp=220 volt=879
delay=5750 temp=220 volt=879
delay=6000 temp=220 volt=893
delay=6250 temp=220 volt=896

Quote
Time for a "low side switch"?  You can then "turn off" the voltage divider when you are not measuring the battery voltage (you should only need to take a measurement every few minutes, hours, or possibly days).

Ok, thanks, I will check those out.  Never heard of it before.  Yes, that's right in fact the whole unit is only awake for 40ms every minute to take and send a temp reading.  And yes, a voltage reading once a day is probably even overkill.  It sounds like that would do the job.

For the moment, it seems to work just living with the low reading.  It's off by a reliable factor, so as long as I calibrate it, I can obtain the true voltage across the range of operating voltages.
Logged


Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


What is connected to AREF?
Logged

Rapa Nui
Offline Offline
Edison Member
*
Karma: 52
Posts: 1990
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

IEdit: I removed the stuff with dividers, needs to be measured again..

Edit: when you use a high impedance dividers on the input ain5 and low impedance source on ain4 and the voltage difference between the channels is high and you are scanning the both analog channels fast in a loop, then you will get such difference
as depicted in the first topic (charging/discharging high potential on the S/H capacitor  via two different impedancies)..
If the voltage difference between the two channels will be low, then you may use an higher impedance divider on one channel and lower impedance on the next as the S/H capacitor will be held on a "constant" potential level and therefore will charge/discharge a smaller potential/current..

Your last readings seems ~ok for me, as a) you use Vcc as the reference ( a lot of niose) and b) there is a lot of noise comming from poor decoupling maybe , c) or from other grounding loops. Try to put 10nF-100nF cpapcitor between analog input and ground and you will get better numbers, hopefully.
P.
« Last Edit: May 17, 2011, 08:47:52 pm by pito » Logged

Seattle, WA
Offline Offline
God Member
*****
Karma: 7
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the responses, folks!

Quote
What is connected to AREF?

Not connected.  Tried tying it to VCC just now.  No appreciable difference.

Quote
Your last readings seems ~ok for me

All those things about the vcc and noise, etc, still apply when I was getting the reading of only the voltage, I was getting 980's which was more right.  Only the addition of testing the other analog pin changes the other reading to <900, which is definitely wrong.

Quote
Try to put 10nF-100nF cpapcitor between analog input and ground and you will get better numbers, hopefully.

Aha!  Yes, a 104 cap did the job.  Now the values are fantastic.  Thanks!!

Doh...  I already sent off the first set to the fab.  Guess I have some blue-wire in my future smiley
Logged


Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What is connected to AREF? Not connected.  Tried tying it to VCC just now.  No appreciable difference.

Try a 0.1 uF capacitor between AREF and positive voltage.
Logged

Rapa Nui
Offline Offline
Edison Member
*
Karma: 52
Posts: 1990
Pukao hats cleaning services
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

..and try this:

analogReference(INTERNAL);

..
Logged

Seattle, WA
Offline Offline
God Member
*****
Karma: 7
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

..and try this:

analogReference(INTERNAL);

From http://arduino.cc/en/Reference/AnalogReference ...

Quote
analogReference(type)
Description

Configures the reference voltage used for analog input (i.e. the value used as the top of the input range). The options are:

INTERNAL: an built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328 and 2.56 volts on the ATmega8 (not available on the Arduino Mega)

1.1 volts?!  Maybe you mean 'EXTERNAL'?
« Last Edit: May 18, 2011, 12:14:03 am by maniacbug » Logged


Seattle, WA
Offline Offline
God Member
*****
Karma: 7
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What is connected to AREF? Not connected.  Tried tying it to VCC just now.  No appreciable difference.

Try a 0.1 uF capacitor between AREF and positive voltage.

Ok, I tried this, and the results were just bizarre.  After adding that cap and setting 'analogReference(EXTERNAL)', which from the docs looks like the right thing, I was getting readings of 1024.

In any case, the cap across A5/GND seems to do the trick.

Thanks again!
Logged


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

The code:-
Serial.print(" temp=");
  Serial.print(analogRead(temp_pin),DEC);
  delay(interval);
  Serial.print(" volt=");
Is not what was meant by inserting a delay it should be like this:-
Serial.print(" temp=");
 temp = analogRead(temp_pin);
  delay(interval);
  Serial.print(analogRead(temp_pin),DEC);
 Serial.print(" volt=");

The delay goes between the first read of the input channel and the second read. You throw away the first read as the capacitor will not have had time to charge up. You do this every time you change channels. Read it, delay, read it again.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Is AVCC connected to power?
Logged

Pages: [1] 2   Go Up
Jump to: