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.

ATMega32 ADC problem

Status
Not open for further replies.

Cantafford

Member
Hey,

I'm reading the value of a POT with the ADC of ATMega32 and displaying it on an LCD.
I have initialised the ADC to 10 bit result left justified. I convert the result to a string then try to display it on a LCD.

I have one problem. When the pot is at it's highest value I get 1023 displayed on my LCD. All good. But when I move it downwards my values don't coincide with the position of the pot. I get weird values like 6035 or 9055 that shouldn't be there at all no matter the position of the pot. Please help me correct this.

This is the code:
Code:
/*
 * AVRGCC1.c
 *
 * Created: 1/10/2017 10:10:28 AM
 *  Author: Paul
 */ 

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h"

void InitLCD();

char Buffer[4];

int main(void)
{
    InitLCD();
     
    ADCSRA |= 1<<ADPS2; // prescaler
    ADMUX  |= 1<<ADLAR; // result left justified(we'll use 8 bits) 
    ADMUX  |= 1<<REFS0; // using AVCC pin as reference
    ADCSRA |= 1<<ADIE;  // enable ADC interrupts
    ADCSRA |= 1<<ADEN;  // turn the ADC ON
    sei();                // enable global interrupts
    ADCSRA |= 1<<ADSC;  // start FIRST conversion. Setting bit ADSC will start the conversion
       
    while(1)
    {  
    }
}

void InitLCD()
{
    LCDInit(LS_NONE|LS_NONE);
    LCDClear();
    LCDWriteString("ADC Program ");
    _delay_ms(1500);
    LCDClear();
}

ISR(ADC_vect)
{ 
 //uint16_t tenBitValue = ADC; // put the ADC value into the tenBitValue variable

 itoa(ADC, Buffer, 10); // convert ADC result to base 10 number
 LCDWriteStringXY(0,0,Buffer);
 ADCSRA |= 1<<ADSC;  // start NEXT conversion
}
 
Looks to me like you are writing a three digit number and a two digit number over a four digit number..

You need to use sprintf() rather than itoa() with sprintf() you can do this

sprintf(buffer," %4d ", ADC);

and then it will print right justified and it will look correct..
 
Another problem:
You should never put an output or an math routine into an interrupt.
While this interrupt runs no other interrupt can be computed. That will give You ugly overrun problems.
It's better to store the ADC Result into a variable ( like adc_value ), set a marker ( variable e.g. NEWADC ) and make the Output in a function in the main loop.
Like:
char main (void)
{...
...
while(1)
{...
...
if ( NEWADC > 0 )
{
NEWADC = 0;
disp_out ( adc_value );
}
...
}
....
return(0);
}

ISR(ADC_vect)
{
adc_value=ADC;
NEWADC=1;
ADCSRA |= 1<<ADSC; // start NEXT conversion
}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top