It's kind of a mystery why one has to read and discard the first read value when it comes to analogRead(). I need to read analog channels fast so I would like to find out why the first value is often wrong. Here is some excerpt wiring_analog.c
// without a delay, we seem to read from the wrong channel
//delay(1);
I wonder if this read-and-discard is still required and for what reason. Thanks.
delay() does nothing else than... delay. Don't use.
Arduinos have multiple analogue inputs, but only one A/D.
If multiple analogue channels are read after each other, then there is a possibility that residual voltage of the previous channel contaminates the reading of the next channel.
That effect (crosstalk) is stronger if the output impedance of the source(s) is >10k.
e.g. you are using >=100k pots instead of 10k pots.
A first "dummy reading" almost clears the previous reading, so the second reading is more "accurate".
Another "fix" is lowering the source impedance with (10-100n) capacitors from the analogue inputs to ground.
That "buffer cap" then acts as a more "solid" source for the A/D to sample from, so the charge of a previous channel is equalized/cleared faster.
If you can use double-readings and/or buffer caps depends on what you're sampling.
Leo..
The rules for the ATmega Arduinos (Mini/Uno/Mega etc) are these:
The first ADC reading after power up can be junk. Just call analogRead() in setup() and
discard the result if this is going to matter to your sketch.
If the source impedance is 10k or less then analogRead() will work reliably (at the default
analog clock speed). There is no point is double reading at all.
If the source impedance is greater than 10k, accuracy will deteriorate in proportion if and
only if you read from different pins - so reading from the same pin every time is fine
(but high source impedances will affect the bandwidth of the response).
So if your source impedance is > 10k, and you switch pins, then calling analogRead twice will
fix things. If the source impedance is 15k, its probably not worth the bother, if its 100k, it
will be noticeable.
The problem is the finite time the sample and hold capacitor has to charge up to the input
voltage when the analog multiplexer is switched (this happens only if you call analogRead
with a different pin number from the previous call). The analog multiplexer gets switched
immediately before the ADC reading is taken (only 4us settling time I believe), which is why its so
critical. If analogRead had been implemented differently the effect could have been
mitigated somewhat.
If you want to have the benefit of a double read without having to waste a whole 110us,
you can directly manipulate the ADC multiplexer registers in advance and wait a shorter time,
but that's going to take some reading of the datasheet and isn't very portable
Thanks for your response and sorry I haven't got back until now. I think my sources are strong sources. They are 4-20mA sensors and I have a 100 ohm resistor for voltage sensing and convert into current. I think you mean this code:
#if defined(ADMUX)
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = (analog_reference << 4) | (pin & 0x07);
#else
ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
#endif
// without a delay, we seem to read from the wrong channel
//delay(1);
#if defined(ADCSRA) && defined(ADCL)
// start the conversion
sbi(ADCSRA, ADSC);
This is from 1.6.13, same in 1.8.7.
There is no delay after ADMUX gets a new value. I think I can add some delay such as 16us. I can start with no delay and switch between the sensor and a GND connection. I then add more and more delay and see if the reading would exponentially approach an asymptotic value.
I did some tests with a PT100 and a 4-20mA transceiver. I then tested with a second analog channel connected to ground and sense these two channels repeatedly. Switching between the channels doesn't seem to cause any difference in the reading of the 4-20mA sensor's voltage. My overall accuracy seems to be +-2LSB to +-3LSB. I wonder if this is expected. I am using a precision 2.048V voltage reference.
I measure the reference with my multimeter and then the voltage across my sensing resistor. The reference is 0.1% accurate with my 4 1/2 digit meter. The arduino sensed voltage is 1% less than my meter though. I'll check my meter with a 6 1/2 digit meter to see what's going on.
liuzengqiang:
My overall accuracy seems to be +-2LSB to +-3LSB. I wonder if this is expected.
That's to be expected indeed.
I measure the reference with my multimeter and then the voltage across my sensing resistor. The reference is 0.1% accurate with my 4 1/2 digit meter. The arduino sensed voltage is 1% less than my meter though. I'll check my meter with a 6 1/2 digit meter to see what's going on.
More digits on the display doesn't mean higher accuracy. It's hard to believe you have a meter that can actually measure voltages at 6 digits precision (i.e. an error of 1 ppm).
liuzengqiang:
My overall accuracy seems to be +-2LSB to +-3LSB. I wonder if this is expected. I am using a precision 2.048V voltage reference.
For ADC of UNO, we have --
1. Accuracy -- it is always 10-bit. We cannot change it.
2. Error (known as digitization error) -- theoretically, it is +/- 1/2 of LSB
Your VREF is external 2.048V. The resolution (value for which the LSB will be set) of the ADC is about 2 mV (2.048/1023). The digitization error of ATmega328P is +/-2LSB (+/- 4mV). Assume that your Vin = 1.25V. What we expect for the ADC value (after conversion) is: 0x0270 (1023/2.0481.25). But, as the ADC error is about 1mV (0.001) +/-4mV (0.004), the ADC will see the input voltage either as 1.251V or 1.249mV 1.254mV or 1.246mV. Under this case, the ADC value would be : 0x0271 or 0x2700x0272 or 0x026E. The ADC error of UNO can not be +/- 6 mV (3LSB)?
There's the digitisation error, but it's not the only source of errors. I recall the datasheet mentions a 2 LSB error. Then there are errors in the sensor output itself, noise from the transmission, instability and noise in the sensing resistor (temperature changes), and probably some more sources of error.
Getting to within 1% without special measures is about all you should expect.
I would have preferred an ADS1115 over a 2.048volt reference with Arduino's 10-bit A/D (~820 useable values).
Unless speed is the priority.
There is also the ADS1015 (higher speed, lower resolution).
Leo..
More digits on the display doesn't mean higher accuracy. It's hard to believe you have a meter that can actually measure voltages at 6 digits precision (i.e. an error of 1 ppm).
Precision is the easy bit, accuracy is harder, especially long-term accuracy.
Regarding the 6 1/2 meter accuracy:
At 10.00000 V range it has accuracy of 10 μV with 1-year +-0.0038%. After one year, it needs to be recalibrated to regain the accuracy which I didn't do. So the 6 1/2 is about as accurate as maybe 5 digits at its best so I can trust it to produce low-speed measurements at about 0.01% accuracy or slightly worse. If Arduino persistently reads 1% lower value, I think it's not my meter but arduino itself although I don't know why. My trace from reference to Aref is short. Maybe I don't know how to handle decoupling analog and digital grounds or how to connect AVCC to VCC. I would imaging that would create a more random error not persistently lower reading.
The Arduino has a pretty decent ADC but by no means a precision ADC.
If you need that kind of accuracy get a better ADC. The ADS1115 is probably far better than the Arduino's ADC already, and that's still a really cheap part. There must be better ADCs out there.
wvmarle:
The Arduino has a pretty decent ADC but by no means a precision ADC.
If you need that kind of accuracy get a better ADC. The ADS1115 is probably far better than the Arduino's ADC already, and that's still a really cheap part. There must be better ADCs out there.
Thanks. Yes, I have ADS1115 for other projects but it's only 960 SPS, not fast enough for what I do. Maybe next time I'll try Arduino DUE with its faster and better ADC (or really better?). I can't yet design my own DUE board, which limits how much I can use a DUE in my projects that require lots of sensor wiring and limited space.
Yep. I need about 8000 sps, which is about the highest ATMEGA can do. Sorry I didn't spell out the exact number.
BTW, I was reading an adjustable power supply so the likelihood of fluctuation is low compared with a 4-20mA sensor.