error in basic adc programming

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

well i made this program for the line following bot i set the adc's prescaler at 8 and timers prescaler at 8 and also adc's voltage reference to AVCC (iam not using crystal and my mcu is atmega16 running at 1mhz) now when i loaded program i tested my pwm channels and i was getting around 3.78 v its cool i needed that much but the problem is i did not connect and sensors so the adc's must be getting 0 v reading but according to my program if i get a value more than 98(nearly 1.5v) i should get pwm of 3.78v but without the adc i shouldnt get any pwm but here iam getting ...can u tell me what is the problem??

PS:i havent connected aref and gnd with a capacitor do u think that is a problem?? also my adc is in auto trigger mode and when i say motor left2 i mean iam turning more to the left than iam turning in motorleft1.....

for better reference i have pasted my code
/* normal header files included*/
# include
# include
# include

//defining pwm values for different level of input adc values left1,left2,right1,right2 specify how much the bot should turnleft2>left1*/
# define motorleft1 127
# define motorleft2 130
# define motorright1 127
# define motorright2 130
# define motorstraight 215
# define threshold 98

void motorleft1turn();
void motorleft2turn();
void motorright1turn();
void motorright2turn();
void motorallstraight();
void timerallinit();
void adcinitialize();
void adcgetvalue();
void directioninputinitialize();

unsigned int analog1,analog2,analog3;

int main(void)
{
timerallinit();
adcinitialize();
directioninputinitialize();
while(1)
{
adcgetvalue();
if(analog1>98 && analog2>98 && analog3>98)
{
if(analog1
threshold && analog3>threshold)
{
motorright1turn();
}
if(analog1
threshold)
{
motorright2turn();
}
if(analog1>threshold && analog2>threshold && analog3
{
motorleft1turn();
}
if(analog1>threshold && analog2
{
motorleft2turn();
}
if(analog1>threshold && analog2>threshold && analog3>threshold)
{
motorallstraight();
}

}
}
return(1);
}

void timerallinit()
{
TCCR0|=_BV(6)|_BV(3)|_BV(5)|_BV(1);
TCCR2|=_BV(6)|_BV(3)|_BV(5)|_BV(1);
DDRD=0x80;
DDRB=0x08;

}
void adcinitialize()
{
ADCSRA|=_BV(7)|_BV(6)|_BV(5)|_BV(1)|_BV(0);
SFIOR=0x00;
ADMUX=0x60;
analog1=ADCH;
}
void adcgetvalue()
{
ADMUX=0x60;
analog1=ADCH;
_delay_ms(5);
ADMUX=0x61;
analog2=ADCH;
_delay_ms(5);
ADMUX=0x63;
analog3=ADCH;
_delay_ms(5);
}

void motorleft1turn()
{
OCR0=motorleft1;
OCR2=motorstraight;
}

void motorleft2turn()
{
OCR0=motorleft2;
_delay_ms(0.5);
OCR2=motorstraight;
}

void motorright1turn()
{
OCR0=motorstraight;
OCR2=motorright1;
}
void motorright2turn()
{
OCR0=motorstraight;
OCR2=motorright2;
_delay_ms(0.5);
}
void motorallstraight()
{
OCR0=motorstraight;
OCR2=motorstraight;
}
void directioninputinitialize()
{

DDRD|=_BV(6)|_BV(5)|_BV(3)|_BV(2);
PORTD|=(1<<5)|(1<<2);
}

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

The ADC needs a reference, either the internal bandgap, AVcc or Vref. If using bandgap or the AVcc then a capacitor should be connected from Vref to ground. Looks like you are waiting 5ms for the ADC conversion before reading the ADCH. Is your conversion rate fast enough? You are reading the high register. Is the ADC set to left justify? Your initialization routine grabs analog1 from the ADCH without waiting for the conversion. The input to the ADC has to be less than 10k impedance.

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

ok i changed the code the new program looks like this do u think this is right here iam changing only the adc getvalue

# include
# include
# include

# define motorleft1 127
# define motorleft2 130
# define motorright1 127
# define motorright2 130
# define motorstraight 215
# define threshold 98

void motorleft1turn();
void motorleft2turn();
void motorright1turn();
void motorright2turn();
void motorallstraight();
void timerallinit();
void adcinitialize();
void adcgetvalue();
void directioninputinitialize();

unsigned int analog1,analog2,analog3;

int main(void)
{
timerallinit();
adcinitialize();
directioninputinitialize();
while(1)
{
adcgetvalue();
if(analog1>98 && analog2>98 && analog3>98)
{
if(analog1
threshold && analog3>threshold)
{
motorright1turn();
}
if(analog1
threshold)
{
motorright2turn();
}
if(analog1>threshold && analog2>threshold && analog3
{
motorleft1turn();
}
if(analog1>threshold && analog2
{
motorleft2turn();
}
if(analog1>threshold && analog2>threshold && analog3>threshold)
{
motorallstraight();
}

}
}
return(1);
}

void timerallinit()
{
TCCR0|=_BV(6)|_BV(3)|_BV(5)|_BV(1);
TCCR2|=_BV(6)|_BV(3)|_BV(5)|_BV(1);
DDRD=0x80;
DDRB=0x08;

}
void adcinitialize()
{
ADCSRA|=_BV(7)|_BV(6)|_BV(5)|_BV(1)|_BV(0);
SFIOR=0x00;
ADMUX=0x60;
_delay_ms(10);
analog1=ADCH;
}
void adcgetvalue()
{
ADMUX=0x60;
_delay_ms(5);
analog1=ADCH;
_delay_ms(5);
ADMUX=0x61;
_delay_ms(5);
analog2=ADCH;
_delay_ms(5);
ADMUX=0x63;
_delay_ms(5);
analog3=ADCH;
_delay_ms(5);
}

void motorleft1turn()
{
OCR0=motorleft1;
OCR2=motorstraight;
}

void motorleft2turn()
{
OCR0=motorleft2;
_delay_ms(0.5);
OCR2=motorstraight;
}

void motorright1turn()
{
OCR0=motorstraight;
OCR2=motorright1;
}
void motorright2turn()
{
OCR0=motorstraight;
OCR2=motorright2;
_delay_ms(0.5);
}
void motorallstraight()
{
OCR0=motorstraight;
OCR2=motorstraight;
}
void directioninputinitialize()
{

DDRD|=_BV(6)|_BV(5)|_BV(3)|_BV(2);
PORTD|=(1<<5)|(1<<2);
}

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

Quote:
i did not connect and sensors
Are you saying you have nothing connected at the ADC inputs? If so, this is not a useful test case since the inputs are floating. Connect GND and then VCC or, even better, a pot so you have some stable known volatage.
BTW, the "Code" button makes it possible to keep the code format (select the code text and press the button).
/Lars

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

isorted my adc out i should have used single conversion mode instead i was using auto trigger without any external interrupts that was the problem adc is working fine another problem i have now is the _delay_ms function suppose i give a delay of 5 ms like this _delay_ms(5) but when i compile i get the following error compiler not optimized and the delay function will not work as defined can u tell me hwy iam getting this error

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

I think you may not have read the function description.

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

well no actually i have read the function description F CPU has been defined there but it says it has not been defined soo wat is the problem?

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

superchiku wrote:
...soo wat is the problem?

In the end, there is one thing that will stand out for sure...

The problem will be operator/programmer error!

It is 99.999... percent of the time.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

u may be right but this is a include file function , it has been made by the makers of the software so i dont think i have implemented them in any wrong way like writing _delay_ms(5) should give me a delay of 5 ms

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

"compiler not optimized " is the optimizer turned On? Is F_CPU defined in the makefile?

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

no i saw that optimazition lvl was s but fcpu wasnt written that was the problem cleared it thanks ....