Arduino performance and capacity

Hello again Arduino Community! :)

Is there a way to check directly wether the Arduino is working at full capacity with the current program running or if it still has lots of processing power for further tasks?

In my current project I have connected 64 analog sensors through the use of cascading multiplexers to one analog in of the Arduino. It is performing at a nice speed and working great so far.

Now I was wondering if by adding a similar setup to an additional analog in I would cut performance in half or wether there is still enough processing power left so I won't experience any performance breakdown.

Unfortunately I do not have the hardware at hand to simply test it, which is why I was wondering if there is any way to get the current work load of the Arduino displayed?

Thank you very much in advance & have a nice day! Tom

Now I was wondering if by adding a similar setup to an additional analog in I would cut performance in half

There is only one A to D converter on the AVR, so there is no gain. In fact, there's a loss, because of the additional input mux switching time.

is any way to get the current work load of the Arduino displayed?

No need for a display - the workload is 100% processor, 100% of the time (unless in low-power mode)

AWOL: No need for a display - the workload is 100% processor, 100% of the time (unless in low-power mode)

But aren't there times where the Arduino has to "wait" for the connected external hardware to react during which time it should have capacities left to perform other tasks?

For example after the Arduino set 3 digital outs to a certain state that will control an external multiplexer to change the input channel, it will actually take the external mux a few nanoseconds to change the channel. Couldn't we use that delay to set another 3 digital outs before we then read the first analog in and then read the second one thus improving the efficiency of our program?

it will actually take the external mux a few nanoseconds to change the channel.

A few nanoseconds, when an instruction takes at least 62.5nanoseconds is no saving.

If analogue performance is an issue, get rid of “analogRead” altogether.
Lock the input mux to the input you’re using, start the conversion, go off and do something, then come back and see if the conversion has completed.
You have the source for “analogRead” - the code is really quite simple.

Here’s the source of "analogRead from 0021:

int analogRead(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

	// 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);
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#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).
	ADMUX = (analog_reference << 6) | (pin & 0x07);

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

	// start the conversion
	sbi(ADCSRA, ADSC);

<<< SPLIT HERE >>>

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

	// 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;

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

Where I’ve put the “<<>>” comment is where you make two functions out of the one - the first sets the input mux and starts the conversion, the second waits for the conversion to complete.

Ouch, apparently I lost a zero somewhere on the conversion between MHz and nanoSeconds. You are absolutely right AWOL, then it doesn't make any sense.

Thank you very much for your input, I will have a look at the analogRead source code and see if that will speed up things even further. Until now I had used the method proposed here which already made a huge improvement on speed: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11

Thanks again for your help, it is much appreciated! :) Tom

As it says in the other thread, an analogRead takes around 111us, virtually all of which will be spent in the while loop. There is potentially a large saving to be made interleaving readings, so that you're making use of the 80 or 90us you would be wasting in the wait loop (90us is enough for up to 1440 instructions).

You could, for instance, be conditioning the previous reading, or storing it to a buffer.

EDIT: Further thought: In your case, you could split analogRead into three - one to set the mux (called just once, because you'll never change it), one to start the conversion and one to wait for and read the result. If you wanted the ultimate, you could use the end-of-conversion interrupt, but I think the added complexity would lead to more frustration and hair-loss.

Thanks again AWOL, that does sound very interesting. Since the next problem I will be tackling is how to transfer the collected data to a master controller, this might be the perfect spot to make use of the ADC waiting cycle to transfer the data of the previous cycle.

I will definitely look further into that.

Have a great day! Tom