Hi @jaishankarm
If you don't require a super high sample rate, you could try accumulating the result over a number of samples then averaging, to reduce noise.
The code example below sets-up the ADC just like analogRead() on A0, however it's also configured to accumulate over 256 samples. This generates a 20-bit value which the ADC auto shifts to the right by 4 (divide by 16), giving a 16-bit result. Setting the AVGCTRL.ADJRES to 0x4, shifts the 16-bit value to the right by a further 4 bits, giving an averaged 12-bit result:
// Set-up the ADC to read analog input on A0 averaged over 256 samples
// The signal is accululated over 256 samples, auto shifted right by 4 generating a 16-bit value
// This value is then divided by 4 to create an averaged 12-bit result
void setup() {
SerialUSB.begin(115200); // Set-up the native serial port at 115200 bit/s
while(!SerialUSB); // Wait for the console to open
// Selecting the port multiplexer the the ADC doesn't seem necessary on the SAMD21
//PORT->Group[PORTA].PINCFG[2].bit.PMUXEN = 1; // Enable the A0 pin multiplexer
//PORT->Group[PORTA].PMUX[2 >> 1].reg |= PORT_PMUX_PMUXE_B; // Switch the multiplexer to the ADC input
ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 | // Divide Clock ADC GCLK by 512 (48MHz/512 = 93.7kHz)
ADC_CTRLB_RESSEL_16BIT; // Set ADC resolution to either 16-bit accumulation/averaging mode
while(ADC->STATUS.bit.SYNCBUSY); // Wait for synchronization
ADC->AVGCTRL.reg = ADC_AVGCTRL_ADJRES(0x4) | // Divide the accumulated 16-bit value by 4 generating an averaged 12-bit result
ADC_AVGCTRL_SAMPLENUM_256; // Accumulates 256 samples generating 16-bit value
ADC->SAMPCTRL.reg = 0x3f; // Set max Sampling Time Length to half divided ADC clock pulse times SAMPCTRL (341.33us)
ADC->INPUTCTRL.bit.MUXPOS = 0x0; // Set the analog input to A0
while(ADC->STATUS.bit.SYNCBUSY); // Wait for synchronization
ADC->CTRLA.bit.ENABLE = 1; // Enable the ADC
while(ADC->STATUS.bit.SYNCBUSY); // Wait for synchronization
}
void loop() {
ADC->SWTRIG.bit.START = 1; // Initiate a software trigger to start an ADC conversion
while(ADC->STATUS.bit.SYNCBUSY); // Wait for write synchronization
while(!ADC->INTFLAG.bit.RESRDY); // Wait for the conversion to complete
ADC->INTFLAG.bit.RESRDY = 1; // Clear the result ready (RESRDY) interrupt flag
while(ADC->STATUS.bit.SYNCBUSY); // Wait for read synchronization
int result = ADC->RESULT.reg; // Read the ADC result
SerialUSB.println(result); // Output the result
delay(500); // Wait for 500ms
}
The SAMD21's datasheet gives more information on how to adjust these register values.