NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

 NerdKits » Forums » Microcontroller Programming » ADC problem (11 posts)
September 02, 2012
by jmuthe

September 03, 2012
by pcbolt

jmuthe -

You might be pulling too much current when the pot is turned all the way up. In this state you are basically wiring the ADC5 pin directly to the 5v rail and puling a good deal of current. This draw may affect the current to the other pin. One thing to check is if you have the pot turned up, see if the voltage regulator gets hot. If so, you'll need to find a way to limit the current going to ADC5.

September 09, 2012
by jmuthe

If that is the problem then how exactly do I limit the current but still keep the full 5 volts going to ADC5. One thing that I tried to do was use a bigger potentiometer (250 ohms) and also put it in series with a 10 Kohm resistor. By doing this, even if I put the pontentiometer at the maximum value, the current would still have to go through a 10 Kohm resistor. However, first of all it didn't work. The LCD display value for ADC0 still gets more and more jumpy, the higher I set the potentiometer to. The second problem with this method is that by connecting it this way, ADC5 will never get the full 5 volts because there will always be a voltage drop across the 10 Kohm resistor that would reduce the voltage going to ADC5. Anyway, how could I apply a full 5 volts to ADC5 but keep the current low?

September 09, 2012
by pcbolt

jmuthe -

One thing that may work is a shunt resistor. You can put a low value resistor from your ADC5 pin to ground. This would make two paths for the current to flow into ground and since they are in parallel, the voltage should not be affected. The one thing that worries me with this approach is if the internal MCU circuitry produces any voltage on ADC5 it will be sunk to ground through the shunt resistor (I don't think this is the case).

The second thing you could try (and I wish I read this sooner) is to disable the ADC5 pin when making a measurement on ADC0. Something like this...

``````DIDR0 |= (1<<ADC5D)   // disable ADC5
// get measurement for tempsensor
``````
September 10, 2012
by Ralphxyz

The second problem with this method is that by connecting it this way, ADC5 will never get the full 5 volts because there will always be a voltage drop across the 10 Kohm resistor that would reduce the voltage going to ADC5.

So if with your pot and resistor you get .5 volt at the minimum and 3.5 volt at the max essentially just display 3.5 as 5.

Actually it should not matter as long as you know what your potential outputs/actions will be just take what ever actions you would for any given situation.

Ralph

September 10, 2012
by jmuthe

I think that the idea of disabling ADC5 seems to be the best idea but I can't seem to get that line of code to work. I iniitially wrote a program that simply reads the contents of ADC0 (from 0 to 1024) and outputs them on the LCD. The program worked just fine so I modified it to add the line "DIDR0 |= (1<<ADC0D);" to disable ADC0. According to the data sheet that line of code should disable ADC0 and cause it to display a 0 on the LCD. I added it just to test the disable code. However, when I ran the program, the LCD still displayed a value for ADC0. Basically, its like the disable code did nothing, so the program runs the same way it did before I entered that line of code. Here is a copy of the program I did. Could you tell me why the line "DIDR0 |= (1<<ADC0D);" isn't doing anything?

#include <stdio.h>

#include <math.h>

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include <inttypes.h>

#include "../libnerdkits/delay.h"

#include "../libnerdkits/lcd.h"

#include "../libnerdkits/uart.h"

int main() { uint16_t result;

lcd_init();

lcd_home();

ADMUX = 0; // set analog to digital converter for external //reference (5v), single ended input ADC0

ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // set analog to digital converter // to be enabled, with a clock prescale of 1/128 // so that the ADC clock runs at 115.2kHz.

while(1)

{

result = low + (high<<8);

lcd_line_one();

lcd_write_int16(result);

}

return 0;

}

September 11, 2012
by bretm

Because DIDR0 |= (1<<ADC0D) doesn't disable the ADC, it disables the digital function of the pin so that it only functions as analog and not as a digital pin also.

September 11, 2012
by pcbolt

Rats. I was hoping that would work (I guess I should have read the fine print like Bret did). You may have to go back to the shunt resistor idea using a low value resistor in parallel with your ADC pin. Bret...do you know the internal resistance of the I/O pins? I don't have the ATmega 168 datasheet at my disposal right now.

September 20, 2012
by jmuthe

Okay, I am still working on the problem and my first question is for bretm. Could you clarify what you mean when you say "it disables the digital function of the pin so that it only functions as analog and not as a digital pin also"? If the ADC stands for an Analog to Digital Converter, then the input would always be analog. Why would it be digital at all.

In regards to the shunt reistor idea, it doesn't seem to work no matter how I connect the pot and resistor. First I tried connecting a 10 Kohm resistor directly to ADC5 so that ADC5 recieves 5 volts but would have its current limited by a resistor. That didn't work. It still caused the LCD values displayed from ADC0 to jump wildly. I've also hooked one end of the 10k resistor to 5V and the other end to terminal 1 of a 250 kohm potentiometer. The arm of the pot (or pin2) was connected to ADC5 and the other end terminal of the pot (pin 3) was connected to ground. Again, when I set the pot low, the value for ADC0 was steady and became jumpy when I set the pot higher. I also tried to connect pot pin 1 to 5 V, pot pin2 to ADC5, pin 3 to ground and then connect a 10 K reistor from ADC5 to ground. I got the same result. I noticed that when I set the pot all the way up it doesn't cause the regulator to get hot so maybe this isn't a current problem. Could you explain to me how exactly to connect the resistor and pot to ADC5 or maybe I have to connect the temperature sensor differently.

September 20, 2012
by jmuthe

I've been thinking that maybe the problem could be my program. Here it is if you want to check it. Could you also tell me how to copy and paste lines of program without the line spacing looking so distorted. Unless, I fix it after I paste it, the whole code would be written in one long line.

# include "../libnerdkits/uart.h"

int main()

{

uint16_t result;

uint16_t result2;

lcd_home();

// set analog to digital converter // to be enabled, with a clock prescale of 1/128 // so that the ADC clock runs at 115.2kHz.

while(1)

{

delay_ms(1000);

result = low + (high<<8);//value for ADC0

delay_ms(1000);

result2 = low + (high<<8);//value for ADC5

lcd_init();

lcd_line_one();

lcd_line_two();

}

return 0;

}

September 20, 2012
by Ralphxyz

Could you clarify what you mean when you say "it disables the digital function of the pin so that it only functions as analog and not as a digital pin also"?

PORT C can have either digital or analog input, in analog mode it functions as a ADC so you disable the digital capabilities so that the dear little mcu does not get confused.

Could you also tell me how to copy and paste lines of program without the line spacing looking so distorted.

Use the "Indent Selection as Code Block" button! Or if you wanted to do it the way it originally was done precede each line of code with four spaces as the instructions on the bottom of this page instruct.

Just highlight your code and click the button, is definitely the easiest way.

Ralph