2
\$\begingroup\$

I'm stuck with trying to read multiple ADC channels on a SAMD21 that I have configured using ATMEL.start. I am very new to Microchip Studio (Arduino convert trying to upgrade).

The below code is my basic "read the input voltage" function to test the ADC. My issue is that I have tried changing the channel number (0 below) to both the sequential channels set in Atmel Start ADC confuration (i.e. 0 is PA08/AIN16, 1 is PA09/AIN17, etc.), and the absolute AIN channel, i.e. 16, 17, 18, ...

This gives me exactly the same result for each channel, and not different results for the 4 pins. I have tried enabling the channel before reading each one (no joy) and I have tried using the adc_sync_set_inputs with odd results.

Can somebody give me an example of how to read two ADC inputs, on pins PA08 and PA09, please? I have been banging my head on datasheets and tutorials for days!

Code and atmel.start configuration below:

[![atmel start adc setting][1]][1]

static void read_battery_level()
{
    adc_sync_enable_channel(&ADC_BATTERY, 0); // enable ADC, channel 0
    
    uint32_t sum = 0;
    for (int i=0; i<NUM_READINGS; i++)
    {
        // read from ADC channel 0
        adc_sync_read_channel(&ADC_BATTERY, 0, battery_reading.c, 2); // 0 is the channel, the .c is the union variable (like a struct)
        
        //add to sum
        sum += battery_reading.i;
        
        //short delay
        delay_us(20);
    }
    //calculate battery voltage
    battery_voltage = ((sum/NUM_READINGS) * ADC_LSB_MV) / 1000.0f;
}
\$\endgroup\$
5
  • 2
    \$\begingroup\$ (sum/NUM_READINGS) * ADC_LSB_MV should probably be sum*ADC_LSB_MV / NUM_READINGS or you might introduce rounding errors. Also there is no valid reason why you should be using floating point, since this MCU does not have a FPU. \$\endgroup\$
    – Lundin
    Commented Jan 10, 2023 at 15:00
  • \$\begingroup\$ Great thanks, I'm more keen to know how to change the channel of the ADC that I'm trying to read!? \$\endgroup\$ Commented Jan 10, 2023 at 21:27
  • 1
    \$\begingroup\$ You should put the solution as an answer to this question and then mark it as the solution. \$\endgroup\$ Commented Jan 13, 2023 at 1:49
  • \$\begingroup\$ Welcome to SE/EE! Please take the tour to learn how this site works. This is not a forum! Please edit your question, remove the "SOLVED" in the title, and move the solution into an actual answer. This way this question will show up as answered (and mark it as accepted) in the list of questions for future visitors. \$\endgroup\$ Commented Jan 13, 2023 at 7:31
  • \$\begingroup\$ Thank you, I have amended Q & A as per requests. \$\endgroup\$ Commented Jan 14, 2023 at 7:50

1 Answer 1

2
\$\begingroup\$

It appears that channel is NOT implemented in the SAMD21 in Microchip Studio! Seems a little silly that all the tutorials mention the channel concept but it doesn't work. The following is a tested and working solution and works to change the input pin on the samd21:

uint8_t buffer[2];
 
adc_sync_set_inputs(&ADC,0x10,0x18,0); // set input pin: ADC, Positive pin, Negative pin, Channel (does nothing).
adc_sync_read_channel(&ADC_BATTERY, 0, buffer, 2);
 
uint16_t reading = (buffer[1] << 8) | buffer[0];
printf("Reading: %d ",reading);

Positive and negative pin values can be found in the hpl_adc_config.h file in the config folder.

For the negative pin, 0x18 is internal ground, 0x19 is I/O ground

For the positive pin, 0x00 = AIN0 ... 0x13=AIN19

I also found that pin defines didn't work (such as ADC_INPUTCTRL_MUXPOS_AIN1_Val) but the hex values did.

Thanks to all comments, much appreciated.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.