Pages: [1]   Go Down
Author Topic: How to make analogRead() faster?  (Read 2298 times)
0 Members and 1 Guest are viewing this topic.
Ukraine
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have measured the run-time of function analogRead () [for analogReadResolution (12)]. On average, it is 40 uS. However, I would like to digitize at least at 200 Ksample / s on one channel. It is known that sam3x8e processor can do it much faster.
Is it possible to get a faster work of function analogRead () for Arduino Due?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 223
Posts: 13903
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

don't know the DUE yet in detail, but with the UNO I did the following trick once:

I split the analogRead() in three functions:
- one to start conversion: void analogReadStart(int pin);
- one to check if it is ready: bool analogReadReady(int pin);
- one to read the data when conversion was ready int analogRead(int pin);

This allowed me to do the following:

Code:
void setup()
{
  ...
  analogReadStart(A0);
}

void loop()
{
  if (analogReadReady(A0))
  {
    value = analogRead(A0);
    analogReadStart(A0);  // restart the next conversion immediately

    process(value);
  }
  // do other things here

}
It is an "analogRead() without (polling) delay" construct. It allowed me to process more samples per second than wit the standard analogRead().

Don't know if similar trick is possible with DUE

Another possibility might be a continuous mode conversion that triggers an ISR() when a new reading is ready. For an UNO this exists, agian don't know for the DUE.

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Ottawa,Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

don't use analogRead smiley-wink

Really .. you have to get into the guts / shorten the track time / read time / setling time

keep it  on / don't use a sleep mode
 use a constant trigger ..I'm using the PWM,
read the data via the PDC

below was modeled after  the Atmel Studio adc/PWM example
Code:
 adc_init (ADC, VARIANT_MCK, adc_clk,  ADC_STARTUP_FAST);

  adc_configure_timing (ADC, 0, //uc_tracking,        
(const enum adc_settling_time_t) ADC_MR_SETTLING_AST3, //settling,
(const uint8_t) 1); //uc_transfer
   adc_enable_channel ((Adc *) ADC,
     (const enum adc_channel_num_t) 0);
  adc_disable_anch (ADC);

 adc_configure_power_save (ADC, ADC_MR_SLEEP_NORMAL, ADC_MR_FWUP_OFF);
 adc_configure_trigger (ADC, ADC_TRIG_PWM_EVENT_LINE_0, ADC_MR_FREERUN_OFF);
« Last Edit: January 23, 2013, 02:59:41 pm by ralphnev » Logged

Ukraine
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, robtillaart. I'm using the Arduino 1.5.1r2. Alack, there are no such functions as analogReadStart() and analogReadReady().
I agree with ralphnev, that Atmel Studio should be used to optimize code on a low level. It remains only to find out how to combine the Arduino and Atmel Studio. smiley
Is it possible to add into Arduino language the functions from Atmel Studio? Give me links to documents on this issue, please.
Logged

Ottawa,Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm using Arduino 1.5.1r2 as well ,  the low level libs from Atmel are all there ,
though i do have to go grep'ing ever time i need a function ...

i did make myself a cheat sheet of locations when working on the PWM - they will be the same for adc :

.../arduino-1.5.1r2/hardware/arduino/sam/variants/arduino_due_x/variant.cpp
.../arduino-1.5.1r2/hardware/arduino/sam/variants/arduino_due_x/variant.h
.../arduino-1.5.1r2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/component/component_pwm.h
.../arduino-1.5.1r2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/instance/instance_pwm.h
.../arduino-1.5.1r2/hardware/arduino/sam/system/libsam/source/pwmc.c
.../arduino-1.5.1r2/hardware/arduino/sam/system/libsam/include/pwmc.h
.../arduino-1.5.1r2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/sam3x8c.h

Logged

Ukraine
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Careful examination of the file c:\arduino-1.5.1r2\hardware\arduino\sam\cores\arduino\wiring_analog.c showed that the function analogRead() always finished with disabling of the analog channel. This is completely unnecessary, if the analog inputs are used only for streaming read from the ADC.
It was enough to comment out the line 164 where the disabling operation of the analog channel executes:

163:       // Disable the corresponding channel
164:       // adc_disable_channel (ADC, ulChannel);

Only one this comment dramatically increased the speed of the ADC. Now the function analogRead () holds less than 2 uS. Reading 12 channels in FOR loop now takes exactly 24 uS. This is with analogReadResolution(12). I think that for many applications this is sufficient.
However, for such a relatively powerful processor, as SAM3X8E, the low-level code inserting into Arduino will always be necessary. We need more new libraries to use all features of this processor.
Thanks all for advises.
Logged

Ottawa,Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

good find // i'll make a note of that

 
 
Logged

Pages: [1]   Go Up
Jump to: