# How to speed up Due ADC

I'm doing a project where in I'm using Arduino Due to measure the time difference of arrival of signals to four piezoelectric sensors. The piezo sensors where glued on a board and we want to localize the source of taps on the boards based from the TDOA of the vibration to the piezos.

Originally, we are using interrupts to raise flags once we have detected the signals (basically, we've set a threshold on the piezo voltage to say that we've 'detected' a signal) but that seems susceptible to noises especially when the environment has loud noises (music, voices on microphones, etc.).

So what we think as a solution is to perform signal processing. However, to do this, we need to measure the voltage of the incoming signal using the ADC.

So far, my target is to make the performance of this approach comparable to that of the one where we are using interrupts. As of now, the new approach is super sensitive to the difference on the taps giving it a high POE.

As I understand it, the main difference between the two approach is that the interrupt approach has a microsecond difference between counts making the difference of the taps to about 10 to 30 microsecond. However, the Analog approach has a 20 microsecond difference between each sample for each channel, making the count difference 20 second also. Even a count difference would make it 20 us.

Is there anyway to make this time faster? I know the ADC needs time to convert and push the data to the appropriate registers but I'm just trying to find ways to make this faster. I've read on the datasheet of the Due MCU that it has 14 ADC channels plus a temp sensor at the 15th. Maybe a way of doing this could be to reduce the number of channels? I don't know how.

Are there any way to make the ADC conversion of the Arduino Due faster?

Yes, there is a possibility to configure `ADC` to run faster, as it can handle `1Msps`. For four `ADC` channels it means `250ksps` each (with `1us` time difference between samples). It's not possible with Arduino wrappers as they are way too slow and also waits for conversion end. You have to configure it directly in MCUs registers, so start with `SAM3X8` datasheet.

In short: free running mode, sequenced readings like: `0 1 2 3`, with interrupt on 4th sample, interrupt handler and some processing.

• Thanks @KIIV! Another question, in the free running mode, would there be any problem on reading the output registers? I mean since the ADC is freely converting and I'm still reading channel 1 (I reckon reading through SPI or I2C is slower than the actual conversion), but the ADC has new set of data, will there be any data collision or anything? Commented Jul 5, 2017 at 8:54
• @noobiejp That's why I mentioned sequenced readings. You can configure it to go over ADC inputs in any order. And readings are stored in corresponding data registers.
– KIIV
Commented Jul 5, 2017 at 9:05

difference between each sample for each channel,

That's way too slow for any mcu made since the 1980s.

Look into the datasheet and compare it via your code to see where you can pick up the speed. Typically there is a clock prescaler for the adc that you can change.

In general, the fastest would be continuous adc into dma. If you need to add multiple channels turn on scanning.

//Configure ADC PMC->PMC_WPMR &= ~(PMC_WPMR_WPEN); //Disable the Write Protect Mode PMC->PMC_PCER1 |= PMC_PCER1_PID37; //Enable ADC Peripheral Clock

PIOA->PIO_PDR |= PIO_PDR_P16; //Disable PIO Controller

``````adc_configure_trigger(ADC, ADC_TRIG_SW, ADC_MR_FREERUN_ON);