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.

ADC PORT(PORTF) Of atmega128 not working properly...

Status
Not open for further replies.
We are using atmega 128 for automotive chassis robot.We have written proper program for its movement.But we are facing problem with atmega controller.We have used ADC (PORTF)of atmega128 for reading the values of joysticks.
The prob is:
Once we Burn The program in the atmega128,Robot performs desired function properly for few trials.But after few trials THE ADC PORT is not working properly...
If we PULL-UP it through prog,it gives us ADC VALUES between 0-40(initially it showed full range(0-255))

WE tried it on different Atmega's But got no solution to this....
Please see to it....
 
Even I have used ADC loads of time.But right now I cant think of any logical possible explanation.
Only yesterday we used new atmega which worked fine for few trials but after few trials its adc port is disabled (I think so bcuz without even changing the prog or hardware d bot stopped working)..n Now the adc range is only 0-40 though the pins PINF are fine if used as normal I/O Pins.



Code:
 //code for joysticks and switches on remote


/*************GLOBAL VARIABLES********/
//#define ADC_VREF_TYPE 0x20
#define ADC_VREF_TYPE 0x60

unsigned char sens[4],sensor;

unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}

int main(void)
{
 init_port();
 init_adc();
init_usart();
 //init_timer0();
//init_timer2();
 //init_timer1();
//init_analog_com();
 //init_timer_counter_interrupt();
 sei();

 unsigned char i,POT1,POT2;


 
 

while(1)//tx
	{	
	POT1=read_adc(0);
	POT2=read_adc(1);
	
	
		
		if(check_bit(&PIND,4)==0)
		{
		i='h';				//auto
		printf("%c",i);
	
		}
		
	else 	if(check_bit(&PIND,3)==0)
		{
		i='r';				//reset
		printf("%c",i);
	
		}
		else if(check_bit(&PIND,5)==0)
		{
		i='g';				//pump_on
		printf("%c",i);
	
		}
		
		else if(check_bit(&PIND,6)==0)
		{
		i='j';				//led testing
		printf("%c",i);
	
		}
		/*
		else if(POT2>200)
		{i='a';
		printf("%c",i);
	
		}
			else if(POT2<50)
		{i='b';
		printf("%c",i);
	
		}
		else if(50<POT2<200)
		{i='c';
		printf("%c",i);
	
		}
		*/
		else if((POT1>200 && POT2<50)||(POT1<50 && POT2>200))
		{
		if(POT1>200 && POT2<50)
		i='a';//bot forward
		
		 if(POT1<50 && POT2>200)
		i='b';//bot reverse
		}
		
		else if((POT1<50 && POT2<50)||(POT1>200 && POT2>200))
		{
		 if(POT1<50 && POT2<50)
		i='e';//bot diff right
		
		 if(POT1>200 && POT2>200)
		i='d';//bot diff left
		
		}
		
		
		else if((POT1<50 || POT1>200))
		{
		 if(POT1<50)
		i='p';//bot  right
		
		 if(POT1>200)
		i='q';//bot radial right 
		
		}
		
		else if((POT2<50 || POT2>200))
		{
		 if(POT2<50)
		i='m';//bot radial left
		
		 if(POT2>200)
		i='n';//bot diff left
		
		}
		
		
		
		
		/* else//if( (POT1>100 && POT1<200) && ( POT2>100&&POT2<200)  )
		i='c';//bot brake
		
		//printf("%c",i);
		//////////
		
		/*
		if(POT1>200)
		{
		i='a';//for
		printf("%c",i);
		}
		
		else if(POT1<100)
		{i='b';//rev
		printf("%c",i);
		}
		
		else if(POT1<200&&POT1>100)
		{
		
		i='c';
		printf("%c",i);//f
		
		
		if(POT2<100)
		i='e';//for
		else if(POT2>220)
		i='d';rev
		else 
		i='c';
		
		printf("%c",i);
		
		}
		
		*/
		
		else
		i='c';
	//printf("%c",i);
	
		_delay_ms(10);
		printf("%c",i);
	}//wh
	return 0;
}
 
Last edited by a moderator:
Code:
unsigned char read_adc(unsigned char adc_input)
   {
   ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
   // Delay needed for the stabilization of the ADC input voltage
   _delay_us(10);
   // Start the AD conversion
   ADCSRA|=0x40;
   // Wait for the AD conversion to complete
   while ((ADCSRA & 0x10)==0);
   ADCSRA|=0x10;
   return ADCH;
   }

Some of the operations on the ADCSRA are a bit dubious.. Here's a quote from the datasheet..

• Bit 4 – ADIF: ADC Interrupt Flag
This bit is set when an ADC conversion completes and the data registers are updated. The ADC
Conversion Complete Interrupt is executed if th e ADIE bit and the I-bit in SREG are set. ADIF is
cleared by hardware when executing the corresponding interrupt handling vector. Alternatively,
ADIF is cleared by writing a logical one to the flag. Beware that if doing a read-modify-write on
ADCSRA, a pending interrupt can be disabled. This also applies if the SBI and CBI instructions
are used

Try this code

Code:
unsigned char read_adc(unsigned char adc_input)
   {
   ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
   // Delay needed for the stabilization of the ADC input voltage
   ADCSRA &= 0x87;
   _delay_us(10);
   // Start the AD conversion
   ADCSRA += 0x40;    // Or =  has to read the port modify and write
   // Wait for the AD conversion to complete
   while (ADCSRA & 0x10);  // Not alot to be done here
   return ADCH;
   }


Without seeing the adc schematics I can't tell if there are external issues.. When the Mega starts to read a low ADC, does the ADC return to normal with a hard reset?
 
Last edited:
Did you try to measure the ADC pin with a multimeter? Does the voltage change as it should when you move the joystick? Could you post schematics.. and maybe the full code.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top