EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: RMS95 on October 07, 2013, 07:08:55 pm

Title: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: RMS95 on October 07, 2013, 07:08:55 pm
Hi EEVbloggers,

Here's a quick start guide to use the Analog Digital Converter of most ATmega processors.

Some times you just want something to work quickly without having to mess around with the datasheets.
This works on the ATmega32 series, but most of the ATmegas work generally the same.

First
Connect your pin you want to measure.
In case you don't know how to get a voltage from a sensor:
Code: [Select]
VCC
_|_
| |  Your sensor
|_|
 |______To the ADC pin
_|_
| | A resistor that matches approximately the sensors "normal" value
|_|
_|_
 _
 -
GND
At the ATmega32, the ADCs are located at the pins at PORT A (those are the top right pins).

Then, just put this function in your project.
The code
Datasheet page numbers can be found in http://www.atmel.com/Images/doc8155.pdf (http://www.atmel.com/Images/doc8155.pdf)
Code: [Select]
int getADC(int nr/* The zero based ID of the ADC*/)
{
ADMUX = (1 << REFS0) | nr; // For settings see page 225 of the datasheet
ADCSRA = (1 << ADEN /* ADC enable */) | (1 << ADSC /* Start ADC */);
while (ADCSRA & (1 << ADSC)); // Wait till the ADC finished
return ADC;
}
Thanks for the modifications in readability by psycho0815

And you're all set!

That really was everything you had to do!

This function will delay until it gets the value from the ADC. So don't blame me when your aircraft crashed while it was waiting for an ADC value. ;)
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: dannyf on October 07, 2013, 07:20:00 pm
Quote
Some times you just want something to work quickly without having to mess around with the datasheets.

That's done by reading the datasheet, and then coding a piece of code that works so you can reuse them later.
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: RMS95 on October 07, 2013, 07:22:22 pm
Quote
Some times you just want something to work quickly without having to mess around with the datasheets.

That's done by reading the datasheet, and then coding a piece of code that works so you can reuse them later.

Indeed. But sometimes you want something to work in a minute =)
If you want to do something more besides this simple example you at least know where you should start looking.

It's just a quick start quide...
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: dannyf on October 07, 2013, 07:29:03 pm
I take a different strategy: every time you write something, you should always think how that investment (in writing that piece of code) can be harvested again and again in the future.

That strategy, over a period of time, will build you a library of proven and reliable code pieces that you can benefit from in the future.
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: RMS95 on October 07, 2013, 07:32:05 pm
I agree, it's my strategy as well.
I am just trying to give people who don't know where to start a place to start.

Some people just like to see a sample before they start so they know what they can expect.
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: psycho0815 on October 09, 2013, 02:14:25 pm
while there is nothing inherenty wrong with your code, i think it's a lot more readable if you use the constants from the avr-lib:
Code: [Select]
int getADC(int nr/* The zero based ID of the ADC*/)
{
ADMUX = (1 << REFS0) | nr;
ADCSRA = (1 << ADEN) | (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADC;
}

just my 2 cents.
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: RMS95 on October 09, 2013, 02:51:45 pm
Thanks for adding that, that's a lot better, I will edit my original post ;)
Title: Re: AVR ATmega ADC quick start - Reading a sensor with AVR
Post by: geraldjhg on October 14, 2013, 04:16:13 pm
hi
the idea is basically good
but if the sensor is very low power it is better to feed the combo from
vref pin wich is the one the adc also references
i would also put the sensor between gnd and adc pin so as to
use shielded cable if needed for distance
saludos