Go Down

Topic: ADC - analogRead at high frequency (1 MHz) on Arduino DUE (Read 1 time) previous topic - next topic

perrociego


There are some great posts about using Arduino Due (I have a Freaduino Due) to read an analogue signal at high frequency.

http://www.djerickson.com/arduino/
http://frenki.net/2013/10/fast-analogread-with-arduino-due/
http://forum.arduino.cc/index.php?topic=137635.5

But the situation changed a bit after ARDUINO 1.5.5 BETA 2013.11.28, when wrong initialization for ADC timings was changed.
This is discussed on:
https://github.com/arduino/Arduino/issues/1418

While before this change you could get an notorious decrease in the sampling time from some 38 us (micro seconds) to 1 us. After that I couldn´t get less than 1.5 us.

With this code I get 1 us again:

Code: [Select]


int x;                                           // read value

void setup()
{
  Serial.begin(57600);                           // initialize the serial port:
  REG_ADC_MR = 0x10380180;                       // change from 10380200 to 10380180, 1 is the PREESCALER and 8 means FREERUN
  ADC -> ADC_CHER = 0x80;                        // enable ADC on pin A0
}

void loop() {

  unsigned long t = micros();                    // init time an elapsed time, in micro seconds
  
  for(int i = 0; i < 1000; i++) {
    
    // instrucction to measure
    while((ADC->ADC_ISR & 0x80)==0);             // wait for conversion
    x = ADC->ADC_CDR[7];                         // read value A0
    
  }
  
  t = micros() - t - 2;                          // 2 us is nothing measured time
  
  Serial.print("Time (us) ");
  Serial.println( ( (double) t / 1000 ), 6 );
  
  delay(2000);
}




I´m getting a 1.00 us sample time, That is 1 MHz frequency!.

My small innovation from the links is that I changed the PRESCALAR, from 2 to 1.  This is in REG_ADC_MR = 0x10380180. I changed the third digit (right to left) from 2 to 1.
The change from 0 to 8 is to enable FREERUN, that means one sample after the other non stop.
___

Some comments:

Without any optimization I'm getting an analogRead(0); at 3.32 us (300 KHz)
enabling FREERUN (REG_ADC_MR = 0x10380280;) 1.92 us (520 KHz)
and changing resolution to 12 bits (shouldn´t be the opposite?) (analogReadResolution(12)) 1.80 us (555 KHz)

Then, from Stimmer post (I just coping and pasting his code, I am not sure to understand what he is doing)
ADC -> ADC_MR |= 0x80;                          // set free running mode on ADC;
ADC -> ADC_CHER = 0x80;                         // enable ADC on pin A0

while((ADC->ADC_ISR & 0x80)==0);                // wait for conversion
x = ADC->ADC_CDR[7];                            // read value
I´m getting 1.50 us (667 KHz)

I just check the speed. I didn´t check any measured values so far.
___

Adios from Buenos Aires
Happy coding
Marcelo





Gericom

Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

perrociego


No no. I´m getting 1 MHz with this.
I am only storing it in memory until the measure ends. It´s a big 24000 int array (I should try a short array).

I tested the light output of a compact fluorescent lamp. I will try to add some picture.


MarkT


I think you can only get 1MHz using dma.


You can only get _reliable_ 1MHz sampling using DMA or disabling all (other) interrupt
handlers (which otherwise may cause lost samples by delaying the ADC code or ISR).

Its obviously going to be more powerful to use DMA which frees the CPU for other stuff.
[ I won't respond to messages, use the forum please ]

perrociego

Ah. Now I understand what you are saying.
Thanks Gericom and thanks MarkT for pointing me that.

Honestly I don´t know how to implement DMA (direct memory access) right now. But I will try to learn (I love to investigate and learn).

In the meantime, will something like this be an acceptable solution?

Code: [Select]
noInterrupts();

(fast loop of analogRead)

interrupts():



Gericom

Here you can find the datasheet of the chip: www.atmel.com/Images/doc11057.pdf
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview