ADC in Atmega324, converting 2 inputs, first conversion always zero with fixed input (non zero), every conversion works thereafter

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, as shown in the title, I have what I hope is a simple problem but so far, I have been unable to figure out where the gap is in my understanding.

 

I have two inputs to the ADC, input 1 on ADC6 and input 2 on ADC 4. The analog inputs are basically fixed inputs that are less than 2.5V and are different enough to tell them apart once they are converted. For the sake of argument, assume that input 1 is 1.5V and input 2 is 2.3V. My Atmega324A is running at 16MHz.

 

The pseudo code below runs great EXCEPT that the very first value displayed for input 1 is always zero. Subsequent conversions (the code toggles between converting input 1 and input 2) are always correct until I power off and back on.

 

Any hints or help will be very much appreciated. I think I hit all of the pertinent points in my code but please let me know if you need any clarification.

 

In the initialization routine, I set the associated registers with the following values:

DIDR0 =  0x50;   //Turns off the digital inputs for ADC6 and ACD4
ADCSRA = 0x0C;   //Enables ADC interrupts, Set selection reg for divide by 16

ADMUX =  0xE6;   //Point A/D mux at input 1, set ref=2.56V, select ADC left adjust to get an 8 bit result (bits 9..2)

ADCSRA = 0x8C;  //Enable ADC after ADMUX is changed

BOOL ADC_INT_flag = FALSE;

 

Some time later (many seconds, based on a command from the serial port) I kick off the first conversion:

ADCSRA = 0xCC; //Start the conversion

 

In my ADC ISR:

(uint8_t) var = ADCH; //Read ADCH register

ADCSRA = 0x0C; //Disable ADC

ADC_INT_flag = TRUE;

 

 

In a subsequent routine in my control loop:

if (ADC_INT_flag) {

ADC_INT_flag = FALSE;

<Transmit var to monitor via serial port>

ADMUX =  0xE4   //Input 2 - there is code to toggle between the two inputs here

}
 

Result: First conversion of input 1 = 0, next conversion (input 2 = correct), next conversion (input 1 = correct) ...

This topic has a solution.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In AVR8, the result of the first conversion is always suspect, if not useless.  Generally, I start a dummy conversion when I configure the ADC.

 

Beyond that, I'd like to see real code, preferably a complete small program that demonstrates the symptoms.

 

Personally I never disable the ADC in my AVR8 apps, unless a "sleeping" app where it is shut down completely and PRR bit used.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you have connected to the AREF pin?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"In AVR8, the result of the first conversion is always suspect, if not useless"

Seems like something like that should be discussed in an app note or datasheet. I realize there are work arounds but really wanted to see if anyone else had experienced this. It reacts as if the ADMUX never gets set for the first conversion.

 

Disabling the ADC between conversions seems to work just fine since all subsequent conversions work after the first one.

 

Thanks for the input!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A 0.1 uF capacitor to ground.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It reacts as if the ADMUX never gets set for the first conversion.

Let's see some code.

 

Seems like something like that should be discussed in an app note or datasheet.

Well, I'm going by experience.  Doesn't the datasheet say

 

The first ADC conversion result after switching reference voltage source
may be inaccurate, and the user is advised to discard this result.

 

And what do you have connected to the AREF pin?

 

Oh, yes--enabling/disabling the ADC cuts your conversion rate in half.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Wed. May 13, 2015 - 06:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did not see the comment in the datasheet until you pointed it out. Thanks. At this point my best bet is to just discard the initial result and move on. I appreciate the help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As I spent a bit of time poking at this, I'd appreciate the test program, answer about AREF connection, and comment on why you care to do "extended" ADC conversions each time.

 

I'd also like to know the results if you start a dummy conversion at init time, as I mentioned.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, I DID respond to your AREF question (0.1 uF capacitor to ground).

 

I will let you know the result of doing a dummy conversion as soon as I have it.

 

I do not have readily demonstrable test code since it is wrapped up in a much larger set of code doing serial IO that requires an additional program on the other end of the serial port to send commands and interpret the responses. I simply do not have time to recreate this in a digestible manner.

 

The overall time for the conversions is of no consequence in this application since the command to do the conversion is only received every few minutes or so but yes, I do understand the difference between 25 and 13 clock cycles.

 

As I stated several times, I do truly appreciate the help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

What do you have connected to the AREF pin?

 

0.1 uF capacitor to ground

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

it is wrapped up in a much larger set of code doing serial IO that requires an additional program on the other end of the serial port to send commands and interpret the responses.

Exactly why the test program is a sanity check.  Is the storage/retrieval/send mechanism "one off"?  Or missing an initial value? Or is the conversion not properly checked for completion?  Or free-running mode inadvertently invoked?

 

But suit yourself; no biggie.

 

0.1uF shouldn't take too long to charge up, and you stated that the conversions were not started till some time after init.  (A big cap and immediate conversion could explain inaccuracy, but I'd think the counts wouldn't be zero.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

 

 

Well, I'm going by experience.  Doesn't the datasheet say

 

The first ADC conversion result after switching reference voltage source
may be inaccurate, and the user is advised to discard this result.

 

I now have a "dummy" conversion for the ADC coded in to the init routine. The output for all subsequent conversions is OK. Thank you to theusch for his help in pointing this out to me.

 

Last Edited: Thu. May 14, 2015 - 02:58 PM