Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using ADC inputs on an ATMEGA

Status
Not open for further replies.

MrMikey83

New Member
I am using the ATMega32 controller to try and sense the output of an accelorometer. The output is 1.5 volts to 3.5 volts. I will be subtracting 1.5 from the voltage number and multiplying it by 90 so that I have a number from 0 to 180 degrees to use for tilt data.

I can't figure out how to interface the ADC inputs on port A. What kind of input comes from the ADC pins? I know it detects the voltage but does it compare it to the reference voltage? If the max voltage from the Accelorometer is 3.5 volts, is that what my VRef should be?
~Mike Steinbach
 
ADCs output a digital number that depends on the input voltage and the Vref.

The maximum input that will be converted correctly is slightly less than Vref. So in your case Vref must be at least 3.5V to get your whole input range. The ADC compares the input voltage with Vref and outputs 0 to 1023 (with a 10 bit ADC) depending on how big the input is compared with Vref.

The ADC outputs a digital number. 10 bits for AVR if i remember correctly. You only need to connect the voltage to the input pin. You also need to write the configuration registers to assign the pin to be an ADC input. When the ADC finishes a conversion it puts the result in an internal register that you can read like it was a port - even though there are no external pins for it. The datasheet for your controller should have all the info you need to set up the ADC.
 
OK thanks, its working now. But the data seems to be all over the place. Even when the accelorometer is just sitting there, my program is giving me angles of anywhere between 75 and 120 degrees. Could this be vibrations? The breadboard is sitting on carpet and the chip is suspended int he air with wires because its surface mount and I had to solder wires to the pads.
~Mike
 
This sounds like a grounding problem. Make sure the ground you use for your accelerometer is the same as the ground for the ADC.
 
Both grounds on the ATMEGA32 are connected to main ground and Accellorometer is connected to main ground as well.

Perhaps I have it set up wrong...

Right now, I have the ADC referenced to AVCC (5V). The output for the accellorometer is connected to ADC0, all other ADC outs are not connected.
As far as the code, I'm using Codevision AVR C Compiler (full version) to write my code. I have tried both using an interrupt on the ADC and just calling the ADC when I need it. The only thing I can't find any information on is when I call the ADC using read_adc() but there is supposed to be a number in the ()'s. I have been using 0 but have tried 1 and other numbers. What exactly is supposed to be in the brackets?

~Mike
 
Check the voltage comming from the accelerometer with your multimeter (or scope if you have one). The accelerometers I've worked with are fairly stable when they are sitting still.

Make sure the ADC MUX is connected to the correct Analog input. Try connecting a known voltage to one of the extra Analog inputs and see if you get good samples.

You should start off polling the ADC- its much easier to debug that way. Once you get that working you can set it up with interrupts.

If you don't know how to call the read_adc funtion you are probably better off just reading the ADC using your own code. If I had to guess though I'd say the number in the brackets is the number of the analog input you want to sample.
 
OK, I'm now testing just the ADC part of my circuit. I have the Accelorometer connected to ADC0.
The accelorometer outputs 1.5 - 3.5 volts output. The ADC returns a value of 0 - 1023. I divide 1023 by 5 volts to get 204.6 which is the output per volt. I subtract 1.5 from the voltage to get a voltage of 0 - 2 volts which I multiply by 90 to get an angle from 0 - 180 degrees.
This seems to work fine, the only problem is stablization of the signal. The output to the terminal seems to be all over the place, sometimes varying 100 degrees while the sensor is completely still.

The sensor is an ADXL103 Accelorometer.

Code:
// Standard Input/Output functions
#include <stdio.h>

#define ADC_VREF_TYPE 0x40
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

void main(void)
{
// Declare local variables
int adc;
int Angle;

PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0xFF;
DDRC=0xFF;
PORTD=0x80;
DDRD=0x80;

UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;

ACSR=0x80;
SFIOR=0x00;

ADMUX=ADC_VREF_TYPE;
ADCSRA=0x85;

while (1)
      {
      adc = read_adc(0);
      Angle = (((adc / 204.6) - 1.5) * 90);
      
      printf("|%d|", Angle);		//Output adc input to terminal
      putchar(13);			//Next line
      delay_ms(500);

      };
}

~Mike
 
First try sampling a known voltage to eleiminate problems with your accelerometer. This will tell you whether its a hardware or software problem.

Other than that I'd double check the while ((ADCSRA & 0x10)==0); line. If you read the ADC value before it's ready it will give weird values.

Also if you post the relevant portion of your schematic we can take a look to see if there are any problems.
 
Here is the schematic. I think I included everything that is relevant to the accelorometer circuit.
~Mike
 

Attachments

  • accel.sch
    7.7 KB · Views: 2,322
What type of file is that? Its much easier if you post a screen capture - odds are I'm not using the same schematic program.
 
The file above is from Eagle.
I'll post a screenshot though.

The accelerometer in the schematic is an ADXL202. The one I'm using is the 103 and has only 4 leads...Common, Vcc, X-out, and St, which is for making sure it works. I haven't read on how to use the ST lead.
I have tested the output of the Accelerometer with my digital multimeter and the voltage seems to hold still, but when I send it through the ATMEGA, something screws with the signal.
~Mike
 

Attachments

  • accel.jpg
    accel.jpg
    97.6 KB · Views: 4,874
Adding a cap between ground and AVcc is a good idea. Some microcontrollers need a cap from VRef to ground to keep the reference nice and stable - check the ATMEGA datasheet. Other than that its almost certainly a problem with how the ADC is set up in software. There should be tons of AVR code on the net for setting up the ADC - try checking your code against some examples. Atmel probably has some appnotes on setting up the ADC too.

Try sending out raw ADC samples through the serial port. The type conversions on your angle calculation could be causing trouble.
 
OK, I'll try the cap later tonight. I ahve tried veiwing the raw ADC data and it too is all over the place, so it must be the connection or how its set up on the outside. There is an option when I am setting up the code wizard to turn on the adc noise canceler. I will try this too and see if it doesn't help any.
Thanks
~Mike
 
Alright! Thanks for the info bmcculla. I put a .1uF cap between 5V and Gnd as well as a .01uF cap between the Accelorometer output and gnd. I am getting absolutely no variation in angle when the sensor is sitting still.
Thansk again!
~Mike
 
i am also working on ATmega ADC. I need complete circuit diagram of interfaced device with ATmega and what should be applied to ATmega at what pin.
 
need help


hi mikey,
i want to use a digital calliper witha atmega 16,
simply i want to display the vaue gained by the calliper.on the lcd,

calliper has four wires - ground,data,clock,vcc
i am trying to put the data wire to the atmega 16
but its not working ,i used an ldr and ir sensor they both are working on same port using the same program,
is it because of i am using a "digital device" now?
Both grounds on the ATMEGA32 are connected to main ground and Accellorometer is connected to main ground as well.

Perhaps I have it set up wrong...

Right now, I have the ADC referenced to AVCC (5V). The output for the accellorometer is connected to ADC0, all other ADC outs are not connected.
As far as the code, I'm using Codevision AVR C Compiler (full version) to write my code. I have tried both using an interrupt on the ADC and just calling the ADC when I need it. The only thing I can't find any information on is when I call the ADC using read_adc() but there is supposed to be a number in the ()'s. I have been using 0 but have tried 1 and other numbers. What exactly is supposed to be in the brackets?

~Mike
 
i am also working on ATmega ADC. I need complete circuit diagram of interfaced device with ATmega and what should be applied to ATmega at what pin.

check this page **broken link removed**

at the end there is an example showing how to use the ADC
 
Hi I'm searching for ADC project using atmega32, can anyone please help me out with sample project and its source code..i want to practice some embedded projects using breadboard...thanks
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top