Pages: [1]   Go Down
Author Topic: analogRead on DUE produces erratic results when requests are long between/Solved  (Read 1184 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using the DUE and doing basic analogRead().   I have tried the code in both 10 and 12 bit resolutions.
Code:
if (inputString.equals()) {
        current_val = analogRead(A0);
Serial.print("current_val");
}

I am calling for an analog  read from a terminal program.  I find that if I request the read repeatedly with less than 1 second between requests I get an accurate value.
If I wait a longer time and only request once every 2 or 3 seconds now the reading is too low.  The situation seems to get worse the lower the analog value I am trying to read is.

It is almost as if the channel mux is not delaying long enough after selection before conversion starts?  Such that if I do not allow the input capacitance to decay I get a good read.

I wanted to keep things simple by using the built-in analogRead() function.  This there an issue in the DUE with this function?  Some other setting I should be doing first?
Or something really simple that I am missing?
 
« Last Edit: September 05, 2013, 04:25:20 pm by ela55 » Logged

Venezuela
Offline Offline
God Member
*****
Karma: 17
Posts: 522
Ground, ground, always ground
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello ela55,

Your problem could be an inadequate input (source) impedance from the terminal program you are calling your analog values. Why? Because a correct source impedance value is required to set the correct sampling rate according to the track time. You can know if your source impedance value needs to be corrected using the table 46-35 on page 1419 of the Atmel doc11057.pdf.

http://www.atmel.com/Images/doc11057.pdf

Knowing the frequency of the ADC clock (in MHz) and the number of bits of the conversion (10 or 12) you can know the correct source impedance value.

How to know the ADC clock in my code?
A) Here a sample code to know your actual ADC clock:

Code:
int ACTUAL_ADC_CLK;
void setup() {
  Serial.begin(9600);
}

void loop() {
  // get and print current ADC clock (in Hz):
  ACTUAL_ADC_CLK = adc_get_actual_adc_clock(ADC, SystemCoreClock);
  Serial.println(ACTUAL_ADC_CLK);
  while (1) {
  }
}

How to know the bit conversion in my code?
B) According to your code excerpt, using analogRead() the bit conversion value is 10.
    In case you use analogReadResolution(12), your bit conversion will be 12.

With A, B and the table, you can get the correct source impedance value. Then, you have to revise the specs of your terminal program and using a resistor(s) arrangement, try to adequate the value to the correct source impedance value. As I use to say, Due is a different monster. Using and AVR MCU, a 10K resistor would resolve the problem. Regards!
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for your response Palliser,

I considered source impedance and that is why I mentioned that if I have a short enough time between samples it works ok ( the input capacitance retains the charge).

I had confirmed that it was not source impedance related by using a low impedance power supply directly to the input and it makes no difference.
Prior to that I was using a source impedance of 1K ohms which is way low on the chart referenced.

On further testing yesterday I found that it works fairly well as long as the input voltage is above 1.3V or so.  Below 1.3 volts it drops off very fast ( reads too low).  This is when I sample at a time greater than 1 second between samples.  If I sample at a time less than 1 second between it tracks just fine.

Without further input it would seem to me that the delay between selection of the mux channel and starting the AtoD is not sufficient.   I will attempt to find the code section and add a delay to confirm.   

      I have done a fair amount of micrcontroller programming using ISP and the GNU compiler.  Thus I am somewhat used to having to fine tune the programming.
I am pretty new to this Arduino environment and had hoped that I would not need to dig so deep here?
I would expect the analogRead() function to work right out of the box with values set for the "average" analog read situation.  I am not doing anything out of the norm that I am aware of.

Any other thoughts would be welcome, else I will dig deeper into the canned code.   
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Need help please,
 I tried adding a delay after the mux was selected and before conversion starts and that did not help.

I thought maybe something else in the code was at issue so I pared my code down to only this main loop:
Code:
void testread (void) {
current = analogRead(A10);
Serial.print(" signal = ");
Serial.print(current);
}

void loop() {
 
  testread();
  testread();
  testread();
  delay(3000);

}

 When the program first starts all three reads are good.  After a short time of running the first read begins to drop in amplitude and will eventually read 0.
This is whenever the analog input is less than about 1.3V.  If the input is above 2 volts the first read is also accurate.

If the delay is reduced to less than 1 seconds all three reads are good even at a the lower analog input.

What is very strange is that the second and third reads are always close to accurate.

    Is the micro-controller going to sleep and needs to wake up ( but too slow) for the first read?    I can see that I could read multiple times and throw away the first read but it bothers me not understanding why this is happening.


Logged

France
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3560
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

may be the sample and hold is in hold state between two conversion
Logged

Venezuela
Offline Offline
God Member
*****
Karma: 17
Posts: 522
Ground, ground, always ground
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I mentioned the source impedance as a key factor in erratic analog reading as a product of my own experience. Afterwards, I found what the ADC Atmel's specs suggests.

Analog inputs in Arduino Due have an input leakage of +-0.5uA and an input capacitance of 8pF (see page 1420), which means that high impedance voltage sources will not generate the readings you expect. You can say: wait a minute. That's nothing! But let's take a closer look:

As I showed you in my previous post, Atmel suggests a source resistance of 14Kohm (for 10 bit) at 20MHz of ADC clock. Why?

If the circuit connected to the analog pin does not source or sink up to 0.5uA of DC leakage, the voltage at the analog pin will change (simple Maximum power transfer theorem). Let's suppose the change is minimum: 2 LSB. For 10-bit this will be about 7mV (our max Vadvref is 3.6v). Thus the resistive component of our source impedance should be limited lower than 7mV/0.5uA = 0.007/0.0000005 = 14kohm that corresponds with the table. Remember that I am not considering the capacitive reactance: for 8 pF and 20MHz of the ADC clock, the aditional impedance is 1K, then we have to add 8K to the source impedance which gives us a total of 15Kohm.

Let's forget for now the numbers and take a look at the real thing. The easiest way to see how the analog reading changes with the source impedance is connecting different potentiometers.

If you use a 10K or smaller pot, the analog readings are always correct (independently of the delay value). Please, corroborate that for me.
If you use pots greater than 470K, the analog readings will start to change depending on the delay value. Slightly with smaller pot values and low ref voltages. Please, corroborate also that for me.

Conclusion: High source impedances will change the analog readings.
« Last Edit: September 04, 2013, 12:38:14 pm by Palliser » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Palliser,
   I was not disagreeing with you.  From my own experience I too know first hand that source impedance can matter.
If you read my post again, I have always been using a low impedance source.

So I have already confirmed - incorrect readings with a low impedance source.
Logged

White River Junction, Vermont USA
Offline Offline
Full Member
***
Karma: 5
Posts: 106
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi ela55,

Could it have something to do with this nugget (From the datasheet)?:
Quote
49.2.4.3, "ADC: Wrong First Conversions", Page 1454 of the datasheet:
The first conversions done by the ADC may be erroneous if the maximum gain (x4 in single
ended or x2 in differential mode) is not used. The issue appears after the power-up or if a conversion
has not been occurred for 1 minute.

-Chris
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Chris,
Thank you for that.  Nice find.  Guess I should have started at the Errata smiley

I have been off trying all sorts of code modifications/timings/sleep modes etc.

Looks like a pain but I will try one of the work-a-rounds.

Thanks again for the effort.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow,
 Looks like I read 17 times and throw away 16 of them.
Hope that gets fixed soon.

Update:
I implemented the 16 dummy reads and that worked ok but I did not like wasting all that time.

I then implemented the second option of a dummy conversion using gain =4 and offset =1, feeding ADVREF/2 to that dummy analog pin.
This seemed to produce slightly more accurate results and of course wasted much less time.

Best of luck to anyone else stuck with this errata issue.   Thanks again to you Chris,   I have been away from needing to reference errata sheets for a some time now.
Quite the refresher course on where to start when issues do not seem to make any sense!
« Last Edit: September 05, 2013, 11:59:58 am by ela55 » Logged

White River Junction, Vermont USA
Offline Offline
Full Member
***
Karma: 5
Posts: 106
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Glad to help.

I thought that I had stumbled upon this when ringing out the DUE, but I wasn't sure... and it wasn't part of the project at hand.

I'm happy (and sad) that you could confirm it.

Best regards,

Chris
Logged

Pages: [1]   Go Up
Jump to: