Pages: [1]   Go Down
Author Topic: Analog Input conversion time  (Read 2525 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The current Arduino Library (coming with IDE 1.0.1) only has one function to read analoge inputs. Since the conversion is started with the call of AnalogRead and the function waits until the conversion is complete, it is one of the most time-consuming function calls. Reading all 12 inputs one after each other lasts therefore ca. 1ms which is a long time if the sketch needs high sample rates or performs other time critical functions that have to wait for the conversion.
It is possible by register manipulation to increase the clock speed of the A/D conversion, but at the cost of 1bit accuracy with respect to standard frequency - and the register manipulation is processor dependent.
I suggest to have an additional function that allows to start a conversion but comes back immediately (e.g. naming it "AnalogStart"). The AnalogRead should then check whether an AnalogStart has already been called (means conversion is already in progress) and wait for the result; otherwise internally call AnalogRead first if one does not care so much about speed and staying compatible with existing Sketches.
This would allow to start the conversion of numerous analog inputs before the result of the conversion is needed, and then later to quickly read all of the analog inputs.
Especially for the new Arduino Due, it would be very unsatisfying to have a 32Bit ARM CPU with 87 MHz but still have to wait such long times for analog conversions.
Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It took you longer to write that post than it would to implement what you suggest.
Logged

Per Arduino ad Astra

Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 237
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This would allow to start the conversion of numerous analog inputs before the result of the conversion is needed, and then later to quickly read all of the analog inputs.

Just checking - you are aware that

a) although there are multiple analog input pins, they are all multiplexed to one ADC?
b) the sample and hold capacitor in the ADC takes some time to charge, and takes longer if the inputs are switched?
« Last Edit: October 25, 2012, 02:51:26 am by Nantonos » Logged

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

Thanks for the hints - I knew that there is only one ADC, but did not have this in mind when I wrote my topic. Nevertheless, my suggestion makes sense, it just means one could start a conversion for a certain pin, doing some other processing, read the result, starting conversion of the next pin, and so on. The point is, not to waste processing time while waiting for the sample and hold capacitor to charge and performing the conversion.
@Groove: I would be very happy if I could implement this in 10 Minutes.
Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd be disappointed if it took that long.
You have the source of analogRead.
Logged

Per Arduino ad Astra

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


check this threads

- http://arduino.cc/forum/index.php?topic=109259.0
- http://arduino.cc/forum/index.php/topic,56396.0.html
- http://arduino.cc/forum/index.php/topic,74895.0.html

completely irq driven
- http://arduino.cc/forum/index.php/topic,125766.msg946608.html#msg946608
Logged

Rob Tillaart

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

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void startAnalogRead(uint8_t pin)
{
uint8_t low, high;

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__)
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(__AVR_ATmega32U4__)
pin = analogPinToChannel(pin);
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#elif defined(ADCSRB) && defined(MUX5)
// the MUX5 bit of ADCSRB selects whether we're reading from channels
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
 
// set the analog reference (high two bits of ADMUX) and select the
// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
// to 0 (the default).
#if defined(ADMUX)
ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif

// without a delay, we seem to read from the wrong channel
//delay(1);

#if defined(ADCSRA) && defined(ADCL)
// start the conversion
sbi(ADCSRA, ADSC);
#endif
}

bool analogReadIsReady() {
return !bit_is_set(ADCSRA, ADSC);
}

int finishAnalogread() {
#if defined(ADCSRA) && defined(ADCL)
// we have to read ADCL first; doing so locks both ADCL
// and ADCH until ADCH is read.  reading ADCL second would
// cause the results of each conversion to be discarded,
// as ADCL and ADCH would be locked when it completed.
low  = ADCL;
high = ADCH;
#else
// we dont have an ADC, return 0
low  = 0;
high = 0;
#endif

// combine the two bytes
return (high << 8) | low;
}

30 seconds, but haven't tested it
Logged

Pages: [1]   Go Up
Jump to: