Go Down

Topic: ZERO's ADC with DMA (Read 4031 times) previous topic - next topic

mantoui

Sep 10, 2015, 01:41 am Last Edit: Sep 10, 2015, 06:16 am by mantoui
Here is a proof of concept sketch that uses DMA to collect ADC samples. With the ADC clock running at 48MHz/16, the DMA reads a sample every 2.0 us.  I just did simple testing with DAC, and jumpering to ground or 3.3v.  You can experiment with various ADC settings.

EDIT: corrected github sketch

Dirk67

very nice,
thanks for your work !
arduino powered car relais / car "micro PLC" / with USB --> http://goo.gl/ofWFW3

AloyseTech

Mantoui you're amazing!

AloyseTech

Have you been able to do something similar for the DAC? That would open the possibility for audio playback while CPU will do other things :)

mantoui

Have you been able to do something similar for the DAC? That would open the possibility for audio playback while CPU will do other things :)
See the thread DAC with DMA

drewfish

Hmmm... could this be used to build a simple oscilloscope?

mantoui

#6
Nov 30, 2015, 03:28 pm Last Edit: Nov 30, 2015, 03:28 pm by mantoui
Hmmm... could this be used to build a simple oscilloscope?
There is an Atmel example of using DMA to continuously send ADC values to the DAC, see
 use case

BobEdge

Hi mantoui,

I can't get the sketch to work. I am using an M0 Pro.
When I compile the sketch it says "void ADCsync()' was declared 'extern' and later 'static' [-fpermissive]"

Any help would be greatly appreciated. I would really like to get this working.

Regards
Bob.

BobEdge

Ok, it is working now. It was a problem that 1.6.6 of arduino had introduced, fixed with a nightly build.

Only problem is when I run it, the console tells me the conversion is taking 2056 uS.

Any ideas?

dzfan

#9
Mar 07, 2016, 04:29 pm Last Edit: Mar 07, 2016, 04:48 pm by dzfan
Huh, I ran this code without modification on an Adafruit Feather M0 (Adafruit's smaller version of Arduino Zero), and I got conversion times of 2057 us too, not 2 us.

AloyseTech

#10
Mar 08, 2016, 08:44 am Last Edit: Mar 09, 2016, 03:16 pm by AloyseTech
Hey guys,

If you check at the beginning of the code you'll find a buffer of 1024 analog value :

Code: [Select]
#define HWORDS 1024
uint16_t adcbuf[HWORDS];   


The printed time is the one needed to complete the bufffer. It means 1024 conversions. So if you have a printed time of 2056us, divide it by HWORDS to get the time needed for one sample... :)

Code: [Select]
void loop() {
 uint32_t t;

 t = micros();
 adc_dma(adcbuf,HWORDS);
 while(!dmadone);  // await DMA done isr
 t = micros() - t;
 Serial.print(float(t/HWORDS));  Serial.print(" us per conversion  ");
 Serial.println(adcbuf[0]);
 delay(2000);
}

hiitsali

I'm a little confused and would love if someone could clarify things for me.  The last thing printed is adcbuf, which looks like it contains the analog values read, am I wrong about that?  I applied a constant 2V to the pin and got readings that were: 0, 0, 1023, 0, 0, 1023, repeating.  Also, is there any limit for how small or large hwords can be besides the memory limit?  If I wanted to do only two conversion at a time would that create other issue?  Thanks

nigelepsom

Hi Mantoui

I have tried your fast adcdma and it is truly impressive.

Is it possible to disable the free run and trigger sampling anew each time the routine is called? I have tried but without success. ( I am new to this and am not sure how to proceed.) I am aiming to use the pin scan facility of the chip.

Any pointer in the right direction will be truly appreciated.

Thanks

Go Up