Description
On the Arduino Due (Arduino library 1.6.1), if you read several different analog pins in succession using analogRead(), some of the values may be off. For example, I had temperature sensors A and B, which were reading approximately the same value. When I added an analogRead() of another channel prior to reading tempA, the reading of tempA would drop a significant amount (~50 ADC counts). By alternating between the two sequences every second, I was able to confirm this behavior:
analogRead(tempA);
analogRead(tempB);
// Both readings are approximately the same.
analogRead(chX);
analogRead(tempA);
analogRead(tempB);
// The reading for tempA is significantly lower
I tracked this down to lines 150-156 in wiring_analog.c:
// Enable the corresponding channel
if (ulChannel != latestSelectedChannel) {
adc_enable_channel( ADC, ulChannel );
if ( latestSelectedChannel != (uint32_t)-1 )
adc_disable_channel( ADC, latestSelectedChannel );
latestSelectedChannel = ulChannel;
}
If analogRead specifies a new channel, the new channel is first enabled, then the previous channel is disabled. Presumably this could have some undesirable effects with the ADC multiplexer, such as extra current draw or some switching noise (this may also be board layout or timing dependent). However, if you switch the order in code, i.e. disable the previous channel, then enable the new channel, the ADC readings are consistent every time.
// Enable the corresponding channel
if (ulChannel != latestSelectedChannel) {
if ( latestSelectedChannel != (uint32_t)-1 )
adc_disable_channel( ADC, latestSelectedChannel );
adc_enable_channel( ADC, ulChannel );
latestSelectedChannel = ulChannel;
}
I think it would be logical to disable the previous ADC channel prior to enabling the next one, and could seemingly prevent multiple channel read errors such as this one.