SG
Online
Sr. Member
Karma: 3
Posts: 285
Arduino rocks
|
 |
« Reply #15 on: January 02, 2013, 07:52:43 am » |
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 114
Posts: 2205
|
 |
« Reply #16 on: January 02, 2013, 08:22:34 am » |
[/quote]Wrong![/quote] That's an overly simplistic, black-and-white view of a highly complex world. For example, I can point to multiple cases where the "wrong" approach is correct and the author's "Very nice. very elegant. And, more importantly, very useful." approach is "wrong". What the author forgot to mention is that what's right or wrong is highly application specific so it is wrong to insist one approach is "wrong" while the others "right".
|
|
|
|
|
Logged
|
|
|
|
|
SG
Online
Sr. Member
Karma: 3
Posts: 285
Arduino rocks
|
 |
« Reply #17 on: January 02, 2013, 08:59:47 am » |
Yes, the 1.1V have about 10% accuracy. The spec sheet gives a nominal value of 1.1 volts, but states that it can vary from 1.0 to 1.2 volts. That means that any measurement of Vcc could be off by as much as 10%. Such a measurement could be less accurate than our power supply for the Arduino! http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 9
Posts: 356
|
 |
« Reply #18 on: January 02, 2013, 09:06:25 am » |
How much more 'accurate' are you expecting things?
A couple of percent looks pretty good really. There are a number of things that are going to affect the readings you get between your multimeter and the analog ports via voltage divider.
Your Arduino analog ports have 8 bit resolution. Your multimeter most likely has better than 8 bit resolution.
Your multimeter has limits. It will have accuracy fingures given in both percentage and digits (if digital).
Your reference voltage may not be exactly 5v, and will vary slightly with the load on that supply line.
Your resistors have a tolerance. Are you using 5% or 1% resistors. They will also vary as they will have a temperature coefficient.
You are measuring the resistances too, which again will be within the measuring tolerances of your meter AND at a specific temperature that can change.
Combine all of these and what you are seeing is actually pretty good as far as I can see.
You're measuring with two different instruments, in different ways, with various things that have errors and tolerances.
|
|
|
|
« Last Edit: January 02, 2013, 09:10:32 am by tack »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 36
|
 |
« Reply #19 on: January 02, 2013, 01:12:20 pm » |
@tack Well I'm almost pleased with the results but since there's more that can be one to improve the results I would like to try them as well. That seems very interesting however I don't really undertand what that does so I guess I'll have to study it a little more.
|
|
|
|
|
Logged
|
|
|
|
|
the land of sun+snow
Offline
Edison Member
Karma: 91
Posts: 2233
|
 |
« Reply #20 on: January 02, 2013, 02:28:40 pm » |
From dhenry's comments, I don't understand what his "specific" objections are.
In general, straightforward ADC readings using a microcontroller like Arduino will have probably 2-5% error, at best. For 5V, that's as much as 0.25V.
First off, the v.reg voltages are not spot-on 5V, but will have up to 5% error, depending upon the specific v.regs being used. Secondly, whenever you use a voltage divider, the resistors also have their own tolerances, ranging from below 1% for high-precision parts [and who uses these] to 5% for most discrete parts. Therefore, any ADC measurements will be off from the get-go. You can use a precision voltage-reference, but still must use precision resistors in the voltage dividers for best results.
It seems to me that the majenko page has some good info to help deal with the first problem, of v.reg tolerance, so I don't see d-h's trouble.
|
|
|
|
|
Logged
|
Something different - Kitchen-Sink Arduino-compatible boards
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 282
Posts: 15443
Measurement changes behavior
|
 |
« Reply #21 on: January 02, 2013, 02:56:30 pm » |
From dhenry's comments, I don't understand what his "specific" objections are.
In general, straightforward ADC readings using a microcontroller like Arduino will have probably 2-5% error, at best. For 5V, that's as much as 0.25V.
First off, the v.reg voltages are not spot-on 5V, but will have up to 5% error, depending upon the specific v.regs being used. Secondly, whenever you use a voltage divider, the resistors also have their own tolerances, ranging from below 1% for high-precision parts [and who uses these] to 5% for most discrete parts. Therefore, any ADC measurements will be off from the get-go. You can use a precision voltage-reference, but still must use precision resistors in the voltage dividers for best results.
It seems to me that the majenko page has some good info to help deal with the first problem, of v.reg tolerance, so I don't see d-h's trouble.
Well there are pretty simple methods to deal with both the 'problems' you addressed. First it's possible with proper coding to have an arduino measure it's own exact Vcc voltage to gain the proper value to convert counts to voltage readings. The second problem is easily deal with by using a 10 turn pot (say 5K ohms) for the voltage divider and set it for the division ratio you desire using a DMM to verify that it's accurately set. Now if either or both those are really needed or even desired depends on the application and it's accuracy requirements or assumptions. Lefty // Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference // This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc // Now works for 168/328 and mega boards. // Thanks to "Coding Badly" for direct register control for A/D mux // 1/9/10 "retrolefty"
int battVolts; // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc
void setup(void) { Serial.begin(38400); Serial.print("volts X 100"); Serial.println( "\r\n\r\n" ); delay(100); } void loop(void) { battVolts=getBandgap(); //Determins what actual Vcc is, (X 100), based on known bandgap voltage Serial.print("Battery Vcc volts = "); Serial.println(battVolts); Serial.print("Analog pin 0 voltage = "); Serial.println(map(analogRead(0), 0, 1023, 0, battVolts)); Serial.println(); delay(1000); }
int getBandgap(void) // Returns actual value of Vcc (x 100) { #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // For mega boards const long InternalReferenceVoltage = 1115L; // Adjust this value to your boards specific internal BG voltage x1000 // REFS1 REFS0 --> 0 1, AVcc internal ref. -Selects AVcc reference // MUX4 MUX3 MUX2 MUX1 MUX0 --> 11110 1.1V (VBG) -Selects channel 30, bandgap voltage, to measure ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0); #else // For 168/328 boards const long InternalReferenceVoltage = 1056L; // Adjust this value to your boards specific internal BG voltage x1000 // REFS1 REFS0 --> 0 1, AVcc internal ref. -Selects AVcc external reference // MUX3 MUX2 MUX1 MUX0 --> 1110 1.1V (VBG) -Selects channel 14, bandgap voltage, to measure ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0); #endif delay(50); // Let mux settle a little to get a more stable A/D conversion // Start a conversion ADCSRA |= _BV( ADSC ); // Wait for it to complete while( ( (ADCSRA & (1<<ADSC)) != 0 ) ); // Scale the value int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L; // calculates for straight line value return results; }
|
|
|
|
« Last Edit: January 02, 2013, 02:58:22 pm by retrolefty »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 36
|
 |
« Reply #22 on: January 02, 2013, 03:14:05 pm » |
Thanks, that code looks very interesting.
Also a question regarding resistor tolerances. These are manufacturing tolerances right? The resistors themselves does not "change" their resistance over time, right? If so then this problem should be overcome by just measuring them and using that exact value in my code. The projects I make is for myself and will not be mass produced hence it's ok for me to measure each resistor manually.
Also I have some 1% and some 5% resistors, the former is much closer to their specified value, of course, but is there any other benefits to use these over the ones with lower tolerances? As I said I do measure them prior to installation.
|
|
|
|
|
Logged
|
|
|
|
|
the land of sun+snow
Offline
Edison Member
Karma: 91
Posts: 2233
|
 |
« Reply #23 on: January 02, 2013, 03:46:59 pm » |
Resistors will change their values with temperature changes. measure it's own exact Vcc voltage What you mean by "exact"? I've seen nothing "exact" in this analog world. Also, on further looking, the bandgap reference in the ATmega 328P datasheet is only specified to within 10% <-- gakk!
|
|
|
|
|
Logged
|
Something different - Kitchen-Sink Arduino-compatible boards
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 36
|
 |
« Reply #24 on: January 02, 2013, 03:50:49 pm » |
Using that code I got the following when powered over the USB:
USB Battery Vcc volts = 5.03 (serial printer) Analog pin 0 voltage = 1.09 (serial printer) Analog pin 0 voltage = 1.11 (using my meter)
3S external power Battery Vcc volts = 4.94 (serial printer) Analog pin 0 voltage = 2.84 (serial printer) Analog pin 0 voltage = 2.89 (using my meter)
That's pretty good, next I'll try to use these values and update my code to see what I'll get. If I get a consistent difference <2% I guess I can live with that.
|
|
|
|
|
Logged
|
|
|
|
|
The Netherlands
Offline
Sr. Member
Karma: 10
Posts: 379
|
 |
« Reply #25 on: January 02, 2013, 04:00:35 pm » |
No, someone already pointed this out (couldn't find this to quote). Tolerances depend on multiple factors. I guess the most known is temperature. Having the resistors in the circuit, might for instance have them pick up ambient temperature as well as temperature possible generated by your cicuit (one could argue that this is also ambient temperature). The temperature generated by the circuit probably differs after an hour running compared to right after starting. You should take that in consideration. Ofcourse you could try to compensate that by using an other sensor, measuring the resistor's temperature, or heat up the resistors to a known fixed temperature. But you also need to know that these methods themselves will also have their own tolerances.
Ofcourse for the sake of learning this is all worth trying, but it's questionable if this will ever get you to read with very high accuracy.
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 282
Posts: 15443
Measurement changes behavior
|
 |
« Reply #26 on: January 02, 2013, 04:08:33 pm » |
Resistors will change their values with temperature changes. measure it's own exact Vcc voltage What you mean by "exact"? I've seen nothing "exact" in this analog world. Also, on further looking, the bandgap reference in the ATmega 328P datasheet is only specified to within 10% <-- gakk! Well 'exact' means measuring the actual Vcc relative to the bandgap voltage. And as you said even the bandgap voltage has a tolerance but it usually a steady value within that tolerance range for each specific chip, and that is one parameter in the sketch that does have to be 'tweeked' to account for one's specific chips bandgap value. Once that is done then the sketch (see the comments) will measure any variation of the Vcc that can be used to compensate for the standard analogRead commands rather then just assume that Vcc is always an exact 5.000 which it presently does and we all know it's not necessarily so. I've seen .5vdc differences of Vcc on a standard arduino board just switching from USB power to external power and that is what my sketch was designed to address, a way to measure the real world Vcc the chip has applied to it to come up with a compensation value to use with analogRead statements. Lefty
|
|
|
|
« Last Edit: January 02, 2013, 04:10:07 pm by retrolefty »
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 282
Posts: 15443
Measurement changes behavior
|
 |
« Reply #27 on: January 02, 2013, 04:15:59 pm » |
Ofcourse for the sake of learning this is all worth trying, but it's questionable if this will ever get you to read with very high accuracy. And that is particularly true when you are working with the limited 10 bit ADC of the arduino. If one jumps into using one of the many 12,14,16, or even 24 bit external I2C or SPI ADC chips then applying principles and practices of good design and calibration will give dividends in trying for the best possible accuracy. The arduino ADC is very useful and simple to use but one shouldn't mistake if for instrumentation quality measurements. Lefty
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 36
|
 |
« Reply #28 on: January 02, 2013, 04:16:08 pm » |
Ok, I'll better use the ones I have with lower tolerances then.
Measurement doesn't need to be super exact. I'll use the arduino to measure battery voltage in my UAV ground station. So it's mostly to make sure I don't run out of battery. Because of that I'll try to keep it as simple as possible but also not introduce any unneccessary errors. I'll also measure a bunch of other stuff such a current sensor, clock, timer, signal strength and buzzers and lights to indicate warnings etc. Information will be presented mostly on a 20x4 LCD.
As you probably figured out I'm an arduino newbie and this is my first project, I'm learning as I go along and really appreciate all input.
|
|
|
|
|
Logged
|
|
|
|
|
the land of sun+snow
Offline
Edison Member
Karma: 91
Posts: 2233
|
 |
« Reply #29 on: January 02, 2013, 04:16:22 pm » |
All in all, seems like too much variability going on here for OP to read really accurate values. Especially, considering powering via USB versus using Vin and the v.reg. Probably best to go with a good external voltage reference chip and 1% Rs, and call it a day.
|
|
|
|
|
Logged
|
Something different - Kitchen-Sink Arduino-compatible boards
|
|
|
|
|