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.
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.
MarkT:
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.
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).
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.
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.
Not connected. Tried tying it to VCC just now. No appreciable difference.
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.
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
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.
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.
..maybe I am missing something but normally I would go with the internal ref source (1.1V or 2.56V) when available..
I would consider Vcc as a ref source as a last option, though. P.
You are missing the fact that this is meant to be a simple introductory system, in a world where 5V is the norm and simple to use.
Adding extra complication for accuracy is not normally worth it.
Of course you can use it when you want, if you know how but it is more complex and 95% of the time not necessary.
This is all good stuff, though. I learned a ton on this thread. Also realized that this temp sensor (MCP9700) doesn't exceed 1.1V until way outside the range of temps it will actually operate in, so I could consider INTERNAL.
The interesting thing about Arduino is that it IS made simple, BUT right under the covers is all the power that the AVRFreaks guys have available, all you have to do is figure it out