ADC problems

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

Hi, probably something really simple here but i can't see it...  i'm trying to get the ADC working on an ATTINY48, taking single values from ADC5, checking whether its above or below 1/2 and outputting a 1 or a 0 to PORTD depending on that result (The port settings are odd because I cut this out of a larger piece of code to avoid confusion). The ADC seems to run, but I always get 0 out of it. Can anyone help a man in need?

 

unsigned char newstate = 0;

int main(void)
{
	DDRB = 0b00000000;
	DDRC = 0b11011111;
	DDRD = 0b11111111;

	PORTB = 0b11000011;
	PORTC = 0b00000000;
	PORTD = 0b11111111;
	
	PRR &= ~(1<<PRADC);
	DIDR0 |= (1<<ADC5D);

	ADCSRA |= (1 << ADEN);  //adc enable turned on

	ADMUX |= (1 << 6);  //REFS0, enable the external power supply for the adc
	ADMUX |= (1 << 2);    //enable which adc pin we're listening to -101 - ADC5
	ADMUX |= (1 << 0);    // ''
	ADMUX |= (1 << ADLAR);  //left shift result of adc conversion so you can just read one register - ADCH

    while (1) 
    {
		 ADCSRA |= (1 << ADSC);  //adc start conversion
		 while(ADCSRA &(1<<ADSC))  // wait while conversion takes place
		 {
			 _delay_us(1);
		 }
		
		 newstate = ADCH;  // find if value is higher or lower than 1/2 and output to PORTD
		 if(newstate < 128)
		 {
			 PORTD = 0b00000000;
		 }
		 else if(newstate > 128)
		 {
			 PORTD = 0b11111111;
		 }
    }
}

 

 

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

pgo480 wrote:
The ADC seems to run, but I always get 0 out of it. Can anyone help a man in need?

1) 

pgo480 wrote:
ADMUX |= (1 << 6); //REFS0, enable the external power supply for the adc ADMUX |= (1 << 2); //enable which adc pin we're listening to -101 - ADC5 ADMUX |= (1 << 0); // '' ADMUX |= (1 << ADLAR); //left shift result of adc conversion so you can just read one register - ADCH

Why do you need all those lines?  Why use an inefficeint construct multiple times, instead of a composite simple assignment?  Why introduce possible RMW effects into your app?  What if ADMUX isn't clear to start with?

 

2)  With the above, you realize that you are doing conversions on ADC6?  What is the voltage on ADC6, right on the AVR pin?

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

1) yeah, I know it's daft but I just find it easier to read. i will change it back... i promise. I don't know what RMW effects are, though?

 

2) 101 in the ADMUX means im reading ADC5, right? I have a pot on ADC5 (shoulda mentioned that earlier but i forgot)

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

So, what voltage is right on the pin?

 

Try changing your indication a bit -- how can you tell if your program is really running?  With all those pins as outputs, could you have some fighting signal s somewhere?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

oh, it actually does work, ha! no idea what happened there... false alarm

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

Since you're not using an interrupt handler for the ADC, I believe you have to clear ADIF manually.

 

You haven't configured the clock prescaler for the ADC.  Assuming you're running the default 1Mhz, you ADC clock is 500Khz, when you want a max of 200Khz.  But since you're not using the full resolution, it might work.