NerdKits - electronics education for a digital generation

You are not logged in. [log in]

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

Microcontroller Programming » Multiple ADC ports

July 30, 2010
by norby31
norby31's Avatar

I'm going to have 4 different voltage sources in a circuit that change at non-specified times and I want to use ADC ports to read them. Can I change between ports quickly to "poll" among all four inputs or can I assign 4 different pins to be ADC inputs at all times? If I could do either, what may be the better choice?

July 30, 2010
by Rick_S
Rick_S's Avatar

I made a joystick control board for one of the CNC machines at the machine shop I work at. In the program for that board, I polled 3 different analog inputs to determine the x/y/z positions of the stick to (depending on mode) operate as a mouse on a pc or move the machine. The code is fairly simple and quick enough for smooth mouse movement. Not sure what your application is or how fast it needs to be but as long as you aren't talking microsecond response times, you could probably make polling work fine.

Here's some sections of code I used for the analog input...

First I defined the ports I used for analog input (Note, this was on a different atmel not one of the Nerdkit Chips so you would have to change the ports to the correct ones for the chip you use)

#define ANALOG_X        PF1
#define ANALOG_Y        PF0
#define ANALOG_Z        PF4

This code was in the main portion of my program

uint16_t adreadx, adready,adreadz;

// Read X/Y/Z Analog inputs
adc_config(ANALOG_X);
adreadx = adc_read();
adc_config(ANALOG_Y);
adready = adc_read();
adc_config(ANALOG_Z);
adreadz = adc_read();

The remaining functions do the work

void adc_config(unsigned char input)
{
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);  // enable ADC ( ADEN=ADC ENABLE BIT, ADPS2..0 = ADC PRESCALE 111=128 )
    ADMUX = ANALOG_REF_VCC | input;  // select Input and Reference
}

unsigned int adc_read(void)
{
    unsigned char lsb;

    ADCSRA |= (1<<ADSC);               // begin the conversion
    while (ADCSRA & (1<<ADSC)) ;   // wait for the conversion to complete
    lsb = ADCL;                              // read the LSB first
    return (ADCH << 8) | lsb;          // read the MSB and return 10 bit result
}

Hope that helps out with your project some.

Rick

PS... Wow, they've changed the code button even more... ME LIKES :)

July 30, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Norby,

You only have 1 ADC on board your chip, so you have no choice but to multiplex and use polling if you want to read several analogue sources. There is a built in way of doing that with the chip though, you just have to connect the different sources to different pins and set the ADMUX register to tell the ADC where to read from. There is a great post by Mike on the subject of reading from multiple sensors using the ADC(which coincidentally contains quite a bit of our now very pretty formatted code).

You might want to double check the datasheet but I think the ADC runs at clk/128, and it takes 13 cycles to complete one conversion. So assuming you are reading the values as soon as they are available you're ADC will be running at about 8.8Khz. That is not terribly fast, but it is hopefully fast enough for your application.

Ralph, I'm glad you are enjoying the new code formatting. Hopefully it will enable better learning, now that we can easily see what people are coding, easily copy and paste into our own code, and refer to specific lines with line numbers.

Humberto

July 30, 2010
by Rick_S
Rick_S's Avatar

Umm.. Humberto, I'm Rick :)

July 30, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

My apologies Rick. You are both such helpful members of our community, and I failed to double check what I typed. It was early in the morning here =/.

Humberto

July 30, 2010
by norby31
norby31's Avatar

He got Rick-Rolled.

July 30, 2010
by Rick_S
Rick_S's Avatar

Rick Rolled

My son had to explain that one to me :D

July 30, 2010
by Rick_S
Rick_S's Avatar

BTW, Humberto,

Not a problem... It was early here too :D I think we're in the same time zone...

July 31, 2010
by norby31
norby31's Avatar

Thanks. Cool, I'm gonna try it. I definitely understand changing the ADMUX, that makes perfect sense. I'll get back to y'all after I try it.

Post a Reply

Please log in to post a reply.

Did you know that interrupts can be used to trigger pieces of code when events happen? Learn more...