Electronic – Most efficient way to read analog signals in c++

adcanalogavrsignal

I am new to AVR programming, and I am trying to learn the basic I/O with C++.

I am trying to find the simplest, most efficient way to read analog signals using the same function for different devices, just like the analogRead() function in the Wiring language (Arduino code). But I have not found anything very simplistic that I could use for AVR programming.

Any suggestions?

Best Answer

The nice thing about AVR is code ports very easily from processor to processor. I have a set of functions on file for setting up the peripherals.

Here's my ADC initialization function:

void init_adc(void)
{
    sei();  
    ADMUX = 0b11100000;
    ADCSRA = 0b10001100;
    ADCSRA = ADCSRA | (1<< ADSC);
}

The sei() function serves as a global interrupt enable, and only needs to be called once if multiple interrupts are being used.

The ADMUX register has the ADC set up with the internal 2.56V reference, the conversion result left adjusted so the most significant bits are in ADCH, and converting ADC0, single ended.

The ADSRA register has the ADC enabled, in interrupt mode, and sets the prescaler to \$\frac{f_{osc}}{16}\$. This register also houses the conversion complete interrupt flag.

ADCSRA = ADCSRA | (1<< ADSC);

This line starts the conversion. It's important to note that the ADC is not free running. A new conversion must be started after each conversion.

My bare bones interrupt service routine code:

ISR(ADC_vect)
{
    ? = ADCH;
    /*possible incrementing ADMUX for additional channels*/
    ADCSRA = ADCSRA | (1<< ADSC);
}

The most significant part of the result is in ADCH. ADCL contains the least significant bits. Read from ADCH as necessary. If you have multiple channels you're converting single ended, this is a good place to handle the multiplexing. For example:

if (n == 3)
{
    ADMUX = 0b00100000;
    n = 0;
}
else
{
    ADMUX++;
    n++;
}

I strongly recommend reading the datasheet to understand the operation of the ADC before you start writing code. Atmel's datasheets are pretty good, and offer good explanations and some sample code.

Related Topic