Due A/D Speed Question.

Hi Everyone:

I'm going to test out my new Due as a replacement for my friends old Cookbook CCD camera. I'd like to use the A/D inputs at their rated 1 Meg samp/sec in the 12 bit mode. I'd like to malloc a frame worth of RAM, and then dump the A/D output into that memory. Then stream the data over the USB 2.0 interface on the SAM 3 of the Due.

I did not see any functions in the API to allow me to explicitly do this. I cobbled together this bit of code to see how fast I can run the A/D in 12 bit mode and dump the values into an array.

void setup() {
// open a serial connection
Serial.begin(9600);
}

void loop() {

unsigned int count;
unsigned int data_file[256000]; // A sizeable data file.
unsigned int ad_data;
unsigned long start_time, end_time;

analogReadResolution(12); // Set the AD to 12 bits of resolution.

Serial.print("Beginning AD Timing\n");

start_time = micros();

for(count =0; count < 256000; count++)
data_file[count] = analogRead(A0);

end_time = micros();

Serial.println(end_time - start_time);

}

I get a very steady 25,167 samples/sec. Does anyone have any insights on how to speed this up with the standard API commands? Are there any development environments that allow me to work in flat C that will allow me to interact with the SAM 3 in a more direct way? Is there a DMA method in the API I'm missing?

Thank You.

The Due has only ~96K bytes of SRAM... it lets you define an integer array of 256000? That does not seem right.

I am also looking for information on streaming data across the Native USB port but have not been able to get that port working at all.
Has anyone used SerialUSB or have a link to information on it?

The 1.0.3 IDE does errors out on both the array size and the call analogReadResolution(12)

where did this guy come from ? analogReadResolution(12);

Hey Guys:

Thanks for pointing out my errors. Yeah, I thought I had 512k or ram for programs. I thought I had a lot of program space to allow for a decent number of samples to average things out. Don't forget I was expecting at least 100's of thousands of samps/sec and thought that my u sec counts might come in the single or double digits. Either way. I reduced the array size to 1000 and got the same sample rate 25,168. Why my programing was not seg faulting ... Well, I'm just ignorant. Either way, after taking your points into the equation, the outcome is the same. A rather slow A/D.

Thank You.

where did you get the idea that you can sample analog inputs at 1 Mhz ?

The actual limit is about 10,000 samples per second.

I got my speed expectation from the data sheet for the ATSAM3X8E on my Due. Page 1 of the chip features lists 16 channel 12 bit 1 Msps A/D. Pg 63 lists ...

12.10 Analog-to-Digital Converter (ADC)
• 12-bit Resolution
• 1 MHz Conversion Rate

I'm pretty sure I have the right data sheet for the chip. Is there something I'm missing? Where did you get your 10k samp/sec number?

Thanks!

Read from page 1329 further.
From page 1414 are given the ADC Characteristics.

yes,12 bit 1 Msps A/D.

I know how to significantly reduce the no. of clock cycles required for A/D conversion, I'll post a link to it once I get home (5 hrs) cos I don't have it with me although the issue that caused it might have been sorted in the 1.5.2 IDE. I don't know if this is the limiting factor for sampling but IIRC it is. I'll also run a test and see what rate I can get, I've been working to speed up my analogRead to do some FFT data capture & calcs but I can't remember off hand all the changes I made.

I know that analogRead() can complete in 3.3uS (the number sticks in my mind but can't remember the source :~) which theoretically works out to 30,3kHz and I've been told on good authority it's a pretty tidy function (not much to be gained from programming it at a lower level). This is close to your result and isn't anywhere near 1Msps. I wonder if deactivating all but 1 pin would help, I know it does for the atmel chips.

As I said I will follow up later with the documentation I found.

Regards

Andrew

Ok both my memory and my math sucks. The actual number was 4uS and it works out to 250kHz (even if it was 3.3uS it would have worked out to 303kHz not 30,3kHz, my bad ) which is much quicker than what you're getting. The writeup and results are here Evaluating Arduino and Due ADCs.

Before he mods the registers it takes 39uS for the loop which works out to 25,6kHz. Almost spot on what you mentioned, so my suggestion is do this mod and you'll increase your sample rate by a factor of 10. Not 1Msps but certainly a lot closer.

Hope this helps

Andrew

Hey Andrew:

Thanks for the followup. Last week I googled and found the very same article you linked to and was able to re-create his and your numbers by tweaking the register. Like you I got up to 300k samps/sec once I set the register value to zero. I also started reading the ADC configuration section of the SAM3X. I think my next step is to start tweaking and adding functionality in the source sitting in ...

~/build/arduino-1.5.2/hardware/arduino/sam/system/libsam/include

It's obvious the ADC is not fleshed out yet for the DUE. Maybe I can contribute something useful.

As for my application I plan on running a CCD with it. So I think I'll trigger the ADC with start convert off one of serial shift signals from a Due output, and then configure ADC complete to generate an interrupt to DMA the data to a memory block and shift the next serial register.

But it made no sense to read out the CCD at 20khz. 300 is doable, 1 Mhz is better, but if I fall a bit short, I'll be okay.

I mainly wanted to log in and post the link you did as a solution.

P.S. would love to see your Southern skies. Us Northmen don't have as pretty a sky as yours I've heard.

Thanks
Andrew

You could probably speed the ADC beyond 1MHz by :

analogReadResolution(10); // Set the AD to 10 bits of resolution instead of 12

adc_configure_timing (ADC, 1, ADC_SETTLING_TIME_3, 0); // Not (1) - 3 cycles instead of 5 (you have the choice !)