SparkFun Forums 

Where electronics enthusiasts find answers.

Discussions on the software and hardware for Atmel's STK standard.
By smdFan
#58438
Hi there,
Finally, I learned enough about using ADC to come up with the following code. It works fine. I have a potentiometer that I got from Radioshak and it is from 0-10K. When I turn it from end to end the two different LEDs turn on and off, telling me that I got the ADC working. Now my question is:

Obviously, my objective is to determine real pot values. So how do I do that?
how can I understand that a value that is read from ADCH is the correct value and how to correlate the value to real value of potentiomenter?

In another words, How do I figure out the real value of pot, and display that correct value?

With the above code, I can read a value but how do I translated reading from ADCH into real value of pot? Sorry if I am not clear


Code: Select all
#include <avr/io.h>

void InitADC(void);


int main(void)
{

	DDRB = 0xFF;
	
	InitADC();
	
	
	while(1)
	{
		if(ADCH < 100)   
		{
			PORTB = 0xFE;	// LED0 on
			PORTB = 0xFF;	// LED1 off
		}
		else 
		{
			PORTB = 0xFF;	//	LED0 off
			PORTB = 0xFD;	//	LED1 on
		}

	}

}


void InitADC(void)
{

	ADCSRA |= (1 << ADPS2) | (1 << ADPS1) |(1 << ADPS0); // Set ADC prescalar to 128 - 125KHz sample rate @ 16MHz 
	ADMUX |= (1 << REFS0);	 // Set ADC reference to AVCC
	ADMUX |= (1 << ADLAR); //Left adjust ADC result to allow easy 8 bit reading
	
	// No MuX values needed to be changed to use ADC0
	
	ADCSRA |= (1 << ADATE);    //Set ADC to Free-Running mode
	ADCSRA |= (1 << ADEN);  // Enable ADC
	ADCSRA |= (1 << ADSC);  // Start A2D conversions

}
By Vraz
#58451
While I have not used the AVR ADC in a real project, based on some previous research I think its as follows:

1- Since you are using ADLAR and just reading ADCH, you are effectively reducing the ADC to 8-bit resolution. So 0=min voltage, 255=max voltage.

2- The ADC is meant to be roughly linear vs input voltage as compared with VREF (since you are using an external voltage reference). So 0=0 volts and 255=vref volts.

3- Not sure of your schematic, but easiest is to connect the pot as a voltage divider. Connect the two "ends" of the pot resistor to vref and ground. Connect the pot wiper (the adjustable contact) to the ADC input.

4- Assuming #3 above, pot ohms = 10000 * (ADHC / 255)

Hope that helps.
By smdFan
#58474
Vraz wrote:While I have not used the AVR ADC in a real project, based on some previous research I think its as follows:

1- Since you are using ADLAR and just reading ADCH, you are effectively reducing the ADC to 8-bit resolution. So 0=min voltage, 255=max voltage.

2- The ADC is meant to be roughly linear vs input voltage as compared with VREF (since you are using an external voltage reference). So 0=0 volts and 255=vref volts.

3- Not sure of your schematic, but easiest is to connect the pot as a voltage divider. Connect the two "ends" of the pot resistor to vref and ground. Connect the pot wiper (the adjustable contact) to the ADC input.

4- Assuming #3 above, pot ohms = 10000 * (ADHC / 255)

Hope that helps.
Hi Vraz,

The pot is used with STK500. The pot has three pins. I connected one pin to 5V source, and another pin to GND. The middle pin which is the wiper, is connected to ADC0 of Atmega16 on STK500.
Code: Select all
  
pot ohms = 10000 *  (ADHC / 255)
I want to measure the voltage. Will that be the same formula? I am not sure about the 10000. What it is for? Thanks
By Vraz
#58494
>> I want to measure the voltage. Will that be the same formula? I am not sure about the 10000. What it is for?

I thought you wanted to measure the ohms of the pot (so the 10000 was for 10K). Voltage is essentially the same. Assuming AREF is connected to 5V (I assume it is), then volts = 5 * (ADHC) / 255. Its just the linear position of the analog input (ADHC / 255) multiplied by whatever you are trying to scale (5 volts in this case).

In order to avoid losing precision with integer math, you always want to multiply before you divide: Thus, instead of using 5 * (ADHC / 255), you actually want to use (5 * ADHC) / 255. (It makes no difference with floating point.)