2

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;
}
  • 2
    `(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. – Lundin Jan 10 '23 at 15:00
  • Great thanks, I'm more keen to know how to change the channel of the ADC that I'm trying to read!? – IlluminatedDan Jan 10 '23 at 21:27
  • 1
    You should put the solution as an answer to this question and then mark it as the solution. – user1850479 Jan 13 '23 at 01:49
  • 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. – the busybee Jan 13 '23 at 07:31
  • Thank you, I have amended Q & A as per requests. – IlluminatedDan Jan 14 '23 at 07:50

1 Answers1

2

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.