Arduino Forum

Using Arduino => Microcontrollers => Topic started by: Riva on Jun 01, 2015, 12:41 pm

Title: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 01, 2015, 12:41 pm
While trying to determine the most suitable MCU for a project that needs fast analogue read I decided to knock up a quick bench-test sketch and run it on some of the various MCU's I have kicking around.
Hope the info is helpful and maybe others can add new MCU's or tests.
Quote
Arduino UNO I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 4.50 Microseconds.
Digital Pin Read  Takes About 4.78 Microseconds.
Analogue Pin Read Takes About 112.00 Microseconds.

Arduino Mega I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 6.50 Microseconds.
Digital Pin Read  Takes About 6.35 Microseconds.
Analogue Pin Read Takes About 112.01 Microseconds.

Arduino Due I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 2.00 Microseconds.
Digital Pin Read  Takes About 1.11 Microseconds.
Analogue Pin Read Takes About 3.30 Microseconds.

Teensy 3.1 @ 24MHz I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 1.00 Microseconds.
Digital Pin Read  Takes About 0.75 Microseconds.
Analogue Pin Read Takes About 12.88 Microseconds.

Teensy 3.1 @ 48MHz I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 0.50 Microseconds.
Digital Pin Read  Takes About 0.38 Microseconds.
Analogue Pin Read Takes About 10.14 Microseconds.

Teensy 3.1 @ 72MHz I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 0.00 Microseconds.
Digital Pin Read  Takes About 0.25 Microseconds.
Analogue Pin Read Takes About 7.59 Microseconds.

Teensy 3.1 @ 96MHz I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 0.00 Microseconds.
Digital Pin Read  Takes About 0.19 Microseconds.
Analogue Pin Read Takes About 10.37 Microseconds.

Fubarino Mini (dev) I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 1.50 Microseconds.
Digital Pin Read  Takes About 0.85 Microseconds.
Analogue Pin Read Takes About 8.77 Microseconds.

Nucleo STM32F401 I/O Speed Tests Over 1000000 Iterations.
Digital Pin Write Takes About 0.1668 Microseconds.
Digital Pin Read  Takes About 0.1788 Microseconds.
Analogue Pin Read Takes About 3.4917 Microseconds.

Arduino Zero I/O Speed Tests Over 50000 Iterations. Compiled Using Arduino IDE v1.8.7
Digital Pin Write Takes About 1.6234 Microseconds.
Digital Pin Read  Takes About 1.0264 Microseconds.
Analogue Pin Read Takes About 423.2541 Microseconds.

ESP8266 Wemos D1 Mini I/O Speed Tests Over 50000 Iterations. Compiled Using Arduino IDE v1.8.9 and 2.50 Core
Digital Pin Write Takes About 0.9627 Microseconds.
Digital Pin Read  Takes About 0.5881 Microseconds.
Analogue Pin Read Takes About 153.9349 Microseconds.

ESP32 DoIt ESP32 Devkit V1 (80MHz) I/O Speed Tests Over 50000 Iterations. Compiled Using Arduino IDE v1.8.9 and 1.0.2 Core
Digital Pin Write Takes About 0.1199 Microseconds.
Digital Pin Read  Takes About 0.1642 Microseconds.
Analogue Pin Read Takes About 10.3027 Microseconds.

Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 01, 2015, 12:46 pm
I have created another sketch for the AVR (UNO) that runs the ADC test using different pre-scaler settings.

The results on an UNO
Quote
Arduino UNO I/O Speed Tests Over 1000 Iterations.
ADPS2 Analogue Pin Read Takes About 4.96 Microseconds.
ADPS4 Analogue Pin Read Takes About 6.52 Microseconds.
ADPS8 Analogue Pin Read Takes About 10.04 Microseconds.
ADPS16 Analogue Pin Read Takes About 17.06 Microseconds.
ADPS32 Analogue Pin Read Takes About 30.12 Microseconds.
ADPS64 Analogue Pin Read Takes About 56.10 Microseconds.
ADPS128 Analogue Pin Read Takes About 112.00 Microseconds.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: robtillaart on Jun 01, 2015, 04:45 pm
Made the topic sticky because imho it is very informative.

athough some numbers make me think there is a loss of precision in the math somewhere.

Teensy 3.1 @ 48MHz I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 0.50 Microseconds.
Digital Pin Read  Takes About 0.38 Microseconds.
Analogue Pin Read Takes About 10.14 Microseconds.

Teensy 3.1 @ 72MHz I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About 0.00 Microseconds.   <<<<<<<<< expected something like 0.33 here
Digital Pin Read  Takes About 0.25 Microseconds.
Analogue Pin Read Takes About 7.59 Microseconds.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Isaac96 on Jun 01, 2015, 04:48 pm
The Teensy is fast! When the Tre and Zero come out, they should be benchmarked as well. (Not the 32u4 on the Tre, the Sitara.)
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 02, 2015, 09:35 am
Made the topic sticky because imho it is very informative.

athough some numbers make me think there is a loss of precision in the math somewhere.
Yes there does appear to be some loss of precision, I should maybe have printed to 4 decimal places instead of the default 2 but I have got the results I need for analogue so will probably not alter the code and re-run the tests.
I have added a Nucleo to the results and I had to up the precision there to see anything.

EDIT: I have attached a slightly modified version that displays result to 4 decimal places instead of 2.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: westfw on Jun 04, 2015, 02:04 am
Quote
Nucleo STM32F401 I/O Speed Tests Over 1000000 Iterations.
Digital Pin Write Takes About 0.1668 Microseconds.
Digital Pin Read  Takes About 0.1788 Microseconds.
Analogue Pin Read Takes About 3.4917 Microseconds.
Using what SW?  I didn't think the Nucleo supported Arduino libraries yet.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 04, 2015, 08:42 am
Using what SW?  I didn't think the Nucleo supported Arduino libraries yet.
The Nucleo is not supported yet but some other STM32 variants have Arduino cores here (http://www.stm32duino.com/).
I converted the Benchmark sketch to suit mbed compiler.
Code: [Select]
#include "mbed.h"

#define targetBoard "Nucleo STM32F401"

AnalogIn analoguePin(A0);
DigitalIn digitalPinIn(USER_BUTTON);
DigitalOut digitalPinOut(LED1);

const unsigned int loopCount = 1000000;
Timer timeX;
Serial pc(USBTX, USBRX); // tx, rx

int main()
{
    unsigned int x;
    double ar;
    
    pc.printf(" *****************\n\n\n");
    while(1) {
        pc.printf(targetBoard);
        pc.printf(" I/O Speed Tests Over ");
        pc.printf("%d Iterations.\n", loopCount);
        wait_ms(1000);

        // Digital Write
        timeX.reset();
        timeX.start();
        for (x = 0; x < loopCount; x++) {
            digitalPinOut = 1;
            digitalPinOut = 0;
        }
        timeX.stop();
        pc.printf("Digital Pin Write Takes About %.4f Microseconds.\n", (double)timeX.read_us() / loopCount / 2.0 );
        wait_ms(1000);

        // Digital Read
        timeX.reset();
        timeX.start();
        for (x = 0; x < loopCount; x++) {
            ar = digitalPinIn;
        }
        timeX.stop();
        pc.printf("Digital Pin Read  Takes About %.4f Microseconds.\n", (double)timeX.read_us() / loopCount );
        wait_ms(1000);

        // Analogue
        timeX.reset();
        timeX.start();
        for (x = 0; x < loopCount; x++) {
            ar = analoguePin.read();
        }
        timeX.stop();
        pc.printf("Analogue Pin Read Takes About %.4f Microseconds.\n\n", (double)timeX.read_us() / loopCount );
        wait_ms(2000);
    }
}

Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Coding Badly on Jun 04, 2015, 10:27 am
Quote
Arduino UNO I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About → 4.50 ← Microseconds.
Digital Pin Read  Takes About → 4.78 ← Microseconds.

Arduino Mega I/O Speed Tests Over 50000 Iterations.
Digital Pin Write Takes About → 6.50 ← Microseconds.
Digital Pin Read  Takes About → 6.35 ← Microseconds.
Something wrong with your Mega?  Was it running at 12 MHz?  Had too much beer the night before the test?

(The question is rhetorical; meant to goad you into investigating.  I know why there is a difference.)

Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 04, 2015, 12:18 pm
Something wrong with your Mega?  Was it running at 12 MHz?  Had too much beer the night before the test?

(The question is rhetorical; meant to goad you into investigating.  I know why there is a difference.)
I had noticed the Mega seemed slower at digital I/O but never bothered to investigate as it was analogue I was interested in. Maybe it's due to core differences in how pins are read/written as pin 9 is PWM on both UNO & MEGA and don't seem to serve as multi function pins (I2C, SPI, UART etc.) that may slow things down. The only other possibility I can think of is interrupt overheads as I don't disable them for testing but analogue read is the same between both UNO & Mega.

Ideally the test sketch should do all the I/O pins and maybe include analogWrite() on supported pins but it served the purpose I needed. Maybe I or someone else can do comprehensive tests at some point.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 05, 2015, 11:02 am
Ideally the test sketch should do all the I/O pins and maybe include analogWrite() on supported pins.
Starting to quote myself now LOL
Below is a new benchmark sketch that does test all the pins and the results obtained from the 3 boards I have configured and tested it for. Due to the added complexity of doing analogue read/write on boards with not consecutive analogue pins the sketch needs any new board types added & configured in the defines.

Code: [Select]
Benchmark V3.0 05-June-2015
Arduino UNO I/O Speed Tests Over 1000 Iterations. Compiled Using Arduino IDE v1.0.6

Digital Pin Read / Write Times In Microseconds.
 0 4.1520 / 4.1200
 1 4.1520 / 4.1200
 2 4.0880 / 4.1200
 3 4.9720 / 5.0020
 4 4.0880 / 4.1200
 5 4.9720 / 4.9980
 6 4.9080 / 4.9360
 7 4.0920 / 4.1200
 8 4.0920 / 4.1200
 9 4.7760 / 4.8140
 10 5.2840 / 5.3140
 11 4.9720 / 5.0000
 12 4.0920 / 4.1200
 13 4.0920 / 4.1200
 14 4.0880 / 4.1200
 15 4.0920 / 4.1200
 16 4.0920 / 4.1240
 17 4.0920 / 4.1200
 18 4.0880 / 4.1200
 19 4.0920 / 4.1200

Analogue Pin Read Times In Microseconds.
 A0 112.0960
 A1 112.0080
 A2 112.0080
 A3 112.0080
 A4 112.0080
 A5 112.0080

Analogue Pin Write Times In Microseconds.
 3 8.5120
 5 8.3240
 6 8.1400
 9 8.2000
 10 8.8320
 11 8.3880


Benchmark V3.0 05-June-2015
Arduino Leonardo I/O Speed Tests Over 1000 Iterations. Compiled Using Arduino IDE v1.0.6

Digital Pin Read / Write Times In Microseconds.
 0 4.5880 / 4.8740
 1 4.5960 / 4.8760
 2 4.5880 / 4.8720
 3 5.7280 / 6.0060
 4 4.5880 / 4.8760
 5 5.7280 / 6.0040
 6 6.4160 / 6.6960
 7 4.5960 / 4.8760
 8 4.5880 / 4.8760
 9 6.2920 / 6.5680
 10 6.3560 / 6.6340
 11 6.2280 / 6.5120
 12 4.5920 / 4.8760
 13 6.0880 / 6.3200
 14 4.5960 / 4.8760
 15 4.5960 / 4.8720
 16 4.5960 / 4.8760
 17 4.6560 / 4.8720
 18 4.5880 / 4.8760
 19 4.5960 / 4.8760

Analogue Pin Read Times In Microseconds.
 A0 112.1080
 A1 112.0040
 A2 112.0680
 A3 114.4760
 A4 112.5000
 A5 112.1400
 A6 112.1480
 A7 112.1640
 A8 112.1440
 A9 112.1320
 A10 112.1520
 A11 112.1480

Analogue Pin Write Times In Microseconds.
 3 8.2400
 5 8.3040
 6 9.4960
 9 8.8720
 10 9.1240
 11 8.6200
 12 13.0920
 13 8.8720


Benchmark V3.0 05-June-2015
Arduino MEGA2560 I/O Speed Tests Over 1000 Iterations. Compiled Using Arduino IDE v1.0.6

Digital Pin Read / Write Times In Microseconds.
 0 4.7200 / 4.9360
 1 4.7160 / 4.9400
 2 5.9120 / 6.1960
 3 6.6080 / 6.8860
 4 6.1640 / 6.4460
 5 6.6040 / 6.8900
 6 6.5480 / 6.8240
 7 6.6640 / 6.9500
 8 6.1640 / 6.4440
 9 6.3520 / 6.6360
 10 6.8560 / 7.1400
 11 6.5480 / 6.8260
 12 6.0400 / 6.3200
 13 6.7080 / 6.9520
 14 4.6600 / 4.9360
 15 4.6520 / 4.9380
 16 4.6600 / 4.9380
 17 4.6520 / 4.9340
 18 4.6520 / 4.9360
 19 4.6600 / 4.9400
 20 4.7160 / 4.9400
 21 4.7240 / 4.9360
 22 4.6600 / 4.9380
 23 4.6560 / 4.9380
 24 4.6600 / 4.9360
 25 4.6520 / 4.9400
 26 4.6560 / 4.9400
 27 4.6520 / 4.9360
 28 4.6520 / 4.9380
 29 4.6600 / 4.9380
 30 4.6520 / 4.9360
 31 4.6560 / 4.9360
 32 4.6520 / 4.9400
 33 4.6600 / 4.9400
 34 4.6600 / 4.9360
 35 4.6520 / 4.9400
 36 4.6600 / 4.9400
 37 4.6520 / 4.9360
 38 4.6560 / 4.9380
 39 4.6600 / 4.9380
 40 4.6560 / 4.9340
 41 4.6600 / 4.9380
 42 4.6520 / 4.9380
 43 4.6560 / 4.9360
 44 6.7360 / 7.0100
 45 6.5400 / 6.8260
 46 7.1080 / 7.3880
 47 4.6600 / 4.9380
 48 4.6560 / 4.9360
 49 4.6600 / 4.9360
 50 4.6520 / 4.9400
 51 4.6560 / 4.9380
 52 4.6520 / 4.9360
 53 4.6520 / 4.9380

Analogue Pin Read Times In Microseconds.
 A0 112.1080
 A1 112.0040
 A2 112.0040
 A3 112.0040
 A4 112.0040
 A5 112.0040
 A6 112.0040
 A7 112.0040
 A8 112.0040
 A9 112.0040
 A10 112.0040
 A11 112.0040
 A12 112.0040
 A13 112.0040
 A14 112.0080
 A15 112.0040

Analogue Pin Write Times In Microseconds.
 2 8.3960
 3 9.3400
 4 8.5880
 5 9.2160
 6 9.4000
 7 9.2760
 8 8.7760
 9 8.9000
 10 9.3400
 11 9.0240
 12 8.6440
 13 8.9680
 44 9.3400
 45 9.1520
 46 9.5920

Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Jun 16, 2015, 10:34 am
Yet another test. This time to determine accuracy & jitter while reading an analogue pin at different pre-scale ADC speeds.

First the test using a 10K trimpot connected between 5V & GND with the wiper set to 3.3V
Code: [Select]
Default ADCSRA = 10010111
Arduino MEGA ADC Accuracy Tests Over 500 Iterations.

ADPS2 (ADCSRA = 10010001)
 Baseline Reading: 768 Rolling Average: 768
 Maximum Reading: 768 Minimum Reading: 768 Maximum Jitter: 0

ADPS4 (ADCSRA = 10010010)
 Baseline Reading: 671 Rolling Average: 671
 Maximum Reading: 671 Minimum Reading: 671 Maximum Jitter: 0

ADPS8 (ADCSRA = 10010011)
 Baseline Reading: 675 Rolling Average: 675
 Maximum Reading: 675 Minimum Reading: 675 Maximum Jitter: 0

ADPS16 (ADCSRA = 10010100)
 Baseline Reading: 675 Rolling Average: 675
 Maximum Reading: 676 Minimum Reading: 675 Maximum Jitter: 1

ADPS32 (ADCSRA = 10010101)
 Baseline Reading: 675 Rolling Average: 675
 Maximum Reading: 676 Minimum Reading: 675 Maximum Jitter: 1

ADPS64 (ADCSRA = 10010110)
 Baseline Reading: 676 Rolling Average: 675
 Maximum Reading: 676 Minimum Reading: 675 Maximum Jitter: 1

ADPS128 (ADCSRA = 10010111)
 Baseline Reading: 675 Rolling Average: 675
 Maximum Reading: 676 Minimum Reading: 675 Maximum Jitter: 1

All results are pretty close to expected reading apart from the very fastest ADC read speed.

Second test is a bit pointless as I just left the pin floating but it's interesting (to me) that all subsequent reads after the initial baseline read are lower and generally the slower the ADC the more jitter.
Code: [Select]
Default ADCSRA = 10010111
Arduino MEGA ADC Accuracy Tests Over 500 Iterations.

ADPS2 (ADCSRA = 10010001)
 Baseline Reading: 560 Rolling Average: 574
 Maximum Reading: 575 Minimum Reading: 560 Maximum Jitter: 15

ADPS4 (ADCSRA = 10010010)
 Baseline Reading: 572 Rolling Average: 572
 Maximum Reading: 572 Minimum Reading: 572 Maximum Jitter: 0

ADPS8 (ADCSRA = 10010011)
 Baseline Reading: 568 Rolling Average: 568
 Maximum Reading: 568 Minimum Reading: 568 Maximum Jitter: 0

ADPS16 (ADCSRA = 10010100)
 Baseline Reading: 563 Rolling Average: 560
 Maximum Reading: 563 Minimum Reading: 560 Maximum Jitter: 3

ADPS32 (ADCSRA = 10010101)
 Baseline Reading: 559 Rolling Average: 509
 Maximum Reading: 559 Minimum Reading: 509 Maximum Jitter: 50

ADPS64 (ADCSRA = 10010110)
 Baseline Reading: 537 Rolling Average: 455
 Maximum Reading: 537 Minimum Reading: 455 Maximum Jitter: 82

ADPS128 (ADCSRA = 10010111)
 Baseline Reading: 514 Rolling Average: 426
 Maximum Reading: 514 Minimum Reading: 426 Maximum Jitter: 88
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: ArthurD on Aug 22, 2015, 06:11 pm
here's a benchmark test, admittedly just about Mega and Due, but some other 3rd party MCUs additionally, performing different low- and high-level computing tests for integer, floats, binay shift, array sort, matrices,  and much more, maybe some one may find it useful:

http://www.mindstormsforum.de/viewtopic.php?p=64772#p64772 (http://www.mindstormsforum.de/viewtopic.php?p=64772#p64772)
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Constantin on Dec 13, 2015, 08:46 pm
Couple of comments:

1) Analog Front ends are not created equal. Most AVRs are lucky to get maybe 8-9 ENOB. The Teensy 3.x series offers up to 12 bit performance in single-channel mode, 13 in differential mode. The datasheet from Freescale may promise higher resolutions under some very specific circumstances, but you are unlikely to create them (chip in sleep mode, beautiful signal presentation, etc.). In other words, the vendor promises 16 bits, the real-life performance is 12-13 bits.

2) The test above does not seem to cover the varying set of resolutions that the Teensy can use. Teensy 3.x units can perform faster ADC conversions @ 10 bits than at 12, for example. If comparing to an UNO, you should select 10 bits as the closest thing to an apples-apples comparison, even if the performance of the ADC is unlikely to be similar re: ENOB.

3) For the Teensy, I'd suggest using the Pedevide ADC library. You can achieve much higher speeds if reads are done sequentially / continuous. This is especially true if you correct for default settings such as the averaging, resolution, etc. The Pedevide library also gives relatively painless access to differential-mode reads and simultaneous reads by the two ADCs in the Teensy 3.1 and 3.2.

4) The Teensy also offers varying lengths of ADC acquisition and conversion time. These can vary depending on your needs, such as source impedance. You can really speed things up if you have a low impedance source or a buffer. Pedevides library gives access to all that.

5) The AVR series doesn't offer a PGA the way Teensy 3.x does. That can be very handy. Early AVRs like the 328P allow ADC reads at up to 5V. The Teensy 3.x and LC series are limited to 3.3V max. input. While many sensors out there have 3.3V compatible versions, some legacy units do not (and vice-versa).

6) If you have two channels to read into, you can double the sampling speed by making use of the second ADC in a Teensy 3.1 or 3.2.

7) For situations where the pin does not have to be reconfigured, try using digitalReadFast(). It significantly speeds up digital reads by dropping some of the setup stuff that is not needed if the pinmode is not changing. Not sure if UNO supports digitalReadFast...

8)
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Dec 14, 2015, 10:42 am
Though I have a Teensy 3.1 I think this is probably the only real thing I had ever done using it so am not familiar with it enough to do detailed tests (I find the documentation on extra commands/features hard to find for Teensy, it could do with a proper reference page like for Arduino - but better) . The initial test program from #0 worked on all but the ST chip so the speed comparisons are what you would expect under normal programming.

If you can write a benchmark for the Teensy that uses standard system commands/libraries (or even hitting the hardware direct) then that would be a great addition to this post and probably the Teensy forum as well.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Constantin on Dec 14, 2015, 01:56 pm
Hi Riva,

The Pedevide ADC library is considered the standard ADC library for Teensy. Users are extremely unlikely to get at ADC features such as differential-mode reads unless they delve into specific registers and enjoying the cryptic (at best!) Freescale datasheets re: how to program the thing.

The Pedevide ADC library is hosted on Github and is installed as part of the Teensyduino package. Thus, if you have a relatively recent sample of the Teensyduino install, you should find it, along with lots of examples. Updating your test is as simple as including the Pedevide library and then using the library commands to do the sequential reads, and so on.

Is this a fair comparison? The answer of course is yes and no. The library enables things like sequential reads that for whatever reason the Arduino IDE does not support using standard commands. Ditto for digitalReadFast, etc. These sorts of standard commands for Teensy are not necessarily part of the the usual Arduino universe thanks to decisions by the higher-ups here. I can see their motivation (keep it simple) but that can get in the way of maximum performance.

Additionally, you need to specify carefully what your source is. For example, the marketing department at Freescale assumes a 8-Ohm source, external caps on the inputs, etc. I presume that Atmel has similar sets of recommendations on how to optimize the input stages. 

Here are some comments from Pedevide in the ADC library with benchmarks for the LC and 3.x series that may be of interest. Note how the Teensy 3.x series can achieve 'legal' sampling speeds of 500kHz, assuming you have a very good signal source. Under default circumstances (i.e. 10bit ADC, 4x oversampling, MED conversion speed) the benchmarks indicate about 17us per conversion. Digital "fast" reads and writes go into the Megahertz range. If there is interest, I can try and dig those up also.

Code: [Select]
RESULTS OF THE TEST Teensy 3.x
Measure continuously a voltage divider.
Measurement pin A9 (23). Clock speed 96 Mhz, bus speed 48 MHz.

 Using ADC_LOW_SPEED (same as ADC_VERY_LOW_SPEED) for sampling and conversion speeds
ADC resolution     Measurement frequency           Num. averages
    16  bits             81 kHz                          1
    12  bits             94 kHz                          1
    10  bits             94 kHz                          1
     8  bits            103 kHz                          1

    16  bits            2.5 kHz                          32
    12  bits            2.9 kHz                          32
    10  bits            2.9 kHz                          32
     8  bits            3.2 kHz                          32


 Using ADC_MED_SPEED for sampling and conversion speeds
ADC resolution     Measurement frequency           Num. averages
    16  bits           193 kHz                         1
    12  bits           231 kHz                         1
    10  bits           231 kHz                         1
     8  bits           261 kHz                         1
    10  bits            58 kHz                         4 (default settings) corresponds to about 17.24 us

 Using ADC_HIGH_SPEED (same as ADC_HIGH_SPEED_16BITS) for sampling and conversion speeds
ADC resolution     Measurement frequency           Num. averages
    16  bits           414 kHz                         1
    12  bits           500 kHz                         1
    10  bits           500 kHz                         1
     8  bits           571 kHz                         1
     8  bits           308 kHz                         1 ADC_VERY_LOW_SPEED sampling
     8  bits           387 kHz                         1 ADC_LOW_SPEED sampling
     8  bits           480 kHz                         1 ADC_MED_SPEED sampling
     8  bits           632 kHz                         1 ADC_VERY_HIGH_SPEED sampling

Using ADC_VERY_HIGH_SPEED for sampling and conversion speeds. This conversion speed is over the limit of the specs! (speed=24MHz, limit = 18 MHz for res<16 and 12 for res=16)
ADC resolution     Measurement frequency           Num. averages
    16  bits           888 kHz                          1
    12  bits          1090 kHz                          1
    10  bits          1090 kHz                          1
     8  bits          1262 kHz                          1

At 96 Mhz (bus at 48 MHz), 632 KHz is the fastest we can do within the specs, and only if the sample's impedance is low enough.

RESULTS OF THE TEST Teensy LC
Measure continuously a voltage divider.
Measurement pin A9 (23). Clock speed 48 Mhz, bus speed 24 MHz.

Using ADC_VERY_LOW_SPEED for sampling and conversion speeds
ADC resolution     Measurement frequency           Num. averages
    16  bits           33.3 kHz                         1
    12  bits           37.5 kHz                         1
    10  bits           37.5 kHz                         1
     8  bits           40.5 kHz                         1

    16  bits            1.04 kHz                       32
    12  bits            1.2 kHz                        32
    10  bits            1.2 kHz                        32
     8  bits            1.3 kHz                        32

ADC_LOW_SPEED, ADC_MED_SPEED, ADC_HIGH_SPEED_16BITS, ADC_HIGH_SPEED and ADC_VERY_HIGH_SPEED are the same for Teensy 3.x and LC, except for a very small amount that depends on the bus speed and not on the ADC clock (which is the same for those speeds). This difference corresponds to 5 bus clock cycles, which is about 0.1 us.

For 8 bits resolution, 1 average, ADC_MED_SPEED sampling speed the measurement frequencies for the different ADACK are:
 ADC_ADACK_2_4       106.8 kHz
 ADC_ADACK_4_0       162.6 kHz
 ADC_ADACK_5_2       235.1 kHz
 ADC_ADACK_6_2       263.3 kHz
 
For Teensy 3.x the results are similar but not identical for two reasons: the bus clock plays a small role in the total time and the frequency of this ADACK clock is acually quite variable, the values are the typical ones, but in the electrical datasheet it says that they can range from +-50% their values aproximately, so every Teensy can have different frequencies.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: spirit on Dec 31, 2015, 05:05 pm
hi.

i did also make a sketch to benchmark the IO/analog speed. on a DUE

here are the results:
Code: [Select]
Digital IO results
Pin.no / DigitalWrite / WriteReg / DigitalRead / ReadReg / PWM
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Pin 0|| Pin 1|| Pin 2|| Pin 3|| Pin 4|| Pin 5|| Pin 6|| Pin 7|| Pin 8|| Pin 9|| Pin10|| Pin11|| Pin12|| Pin13|| Pin14|| Pin15|| Pin16|| Pin17|| Pin18|| Pin19|| Pin20|| Pin21|| Pin22|| Pin23|| Pin24|| Pin25|| Pin26|| Pin27|| Pin28|| Pin29|| Pin30|| Pin31|| Pin32|| Pin33|| Pin34|| Pin35|| Pin36|| Pin37|| Pin38|| Pin39|| Pin40|| Pin41|| Pin42|| Pin43|| Pin44|| Pin45|| Pin46|| Pin47|| Pin48|| Pin49|| Pin50|| Pin51|| Pin52|| Pin53|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1.23 || 1.15 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.28 || 1.23 || 1.23 || 1.15 || 1.28 || 1.23 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.27 || 1.40 || 1.35 || 1.35 || 1.15 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1.09 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0.14 || 0.14 || 0.13 || 0.14 || 0.13 || 0.14 || 0.14 || 0.14 || 0.13 || 0.13 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 || 0.14 || 0.13 || 0.13 || 0.14 || 0.13 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 3.92 || 3.91 || 3.84 || 3.91 || 2.76 || 2.76 || 2.76 || 2.76 || 3.84 || 3.91 || 3.84 || 3.84 |
------------------------------------------------------------------------------------------------
Analog / Digital IO results
Pin.no / DigitalWrite / WriteReg / DigitalRead / ReadReg / AnalogRead 8bit / AnalogRead 10bit / AnalogRead 12bit
--------------------------------------------------------------------------------------------------------------------------------
| Pin 0|| Pin 1|| Pin 2|| Pin 3|| Pin 4|| Pin 5|| Pin 6|| Pin 7|| Pin 8|| Pin 9|| Pin10|| Pin11|| Pin12|| Pin13|| Pin14|| Pin15|
--------------------------------------------------------------------------------------------------------------------------------
| 1.41 || 1.36 || 1.36 || 1.28 || 1.41 || 1.36 || 1.36 || 1.28 || 1.41 || 1.36 || 1.36 || 1.28 || 1.29 || 1.36 || 1.25 || 1.16 |
--------------------------------------------------------------------------------------------------------------------------------
| 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 || 0.05 |
--------------------------------------------------------------------------------------------------------------------------------
| 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 || 1.13 || 1.08 || 1.08 || 1.04 |
--------------------------------------------------------------------------------------------------------------------------------
| 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 || 0.12 |
--------------------------------------------------------------------------------------------------------------------------------
| 3.39 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 || 3.38 |
------------------------------------------------------------------------------------------------
| 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 || 3.47 |
------------------------------------------------------------------------------------------------
| 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 || 3.40 |
------------------------------------------------------------------------------------------------

all are 50000 Iterations.

and for WriteReg and ReadReg i used this code:
Code: [Select]
inline void digitalWriteDirect(int pin, boolean val) {
  if (val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

inline int digitalReadDirect(int pin) {
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: DrDiettrich on Jan 20, 2016, 01:44 pm
I had noticed the Mega seemed slower at digital I/O but never bothered to investigate as it was analogue I was interested in. Maybe it's due to core differences in how pins are read/written as pin 9 is PWM on both UNO & MEGA and don't seem to serve as multi function pins (I2C, SPI, UART etc.) that may slow things down. The only other possibility I can think of is interrupt overheads as I don't disable them for testing but analogue read is the same between both UNO & Mega.
The Mega has at least one overly bloated #define for the digitalPinToPCICRbit macro, in the 1.6.7 version. The 6 comparisons of the pin number could be reduced to 2, which yield a result different from zero.

Dunno if that (all those #defines in pins_arduino.h) affects digital I/O timing, though. The mapping of pins to ports and bits is straight forward (array index), no comparisons there.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Mike44449 on Jul 06, 2016, 06:04 am
I do not know if people will see this, but I ran the benchmark on the Arduino 101, using the IDE 1.6.9. I also added the feature to time an analog-write / PWM on pin 9 and I compensated for the time it took to map the values (by timing them as well).

These are my results for the Arduino 101, doing 5000 iterations as well:

Digital Write:                     1.5634 Microseconds (.31 nanoseconds per execution)
Digital Read:                      1.3131 Microseconds (.26 nanoseconds per execution)
Analog Read:                    27.9999 Microseconds (5.59 nanoseconds per execution)
Analog Write (PWM):           2.2391 Microseconds (.44 nanoseconds per execution)
Mapping 0-5000 to 0-255:     1.9063 Microseconds (.38 nanoseconds per execution)

This is the code I used, after modifying it for the mapping and PWM timers. Credit goes to the original Author Riva.

Code: [Select]
/* Benchmark V2.0 02-June-2015  */

#define targetBoard "Arduino 101"
#define ideVersion "Arduino IDE v1.6.9"
#define analoguePin A0
#define digitalPin 9
#define ledPin 1

#define loopCount 50000   // Max 65535

void setup() {
  Serial.begin(115200);
  while (!Serial) ;
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);
 
  pinMode(analoguePin,INPUT);
}

void loop() {
  unsigned long startTime;
  unsigned long totalTime;
  unsigned int x;
  int ar;
  int y;
 
  Serial.print(F(targetBoard));
  Serial.print(F(" I/O Speed Tests Over "));
  Serial.print(loopCount, DEC);
  Serial.print(F(" Iterations. Compiled Using "));
  Serial.println(F(ideVersion));
  Serial.flush();
  delay(1000);
 
  // Digital Write
  pinMode(digitalPin,OUTPUT);
  digitalWrite(ledPin,HIGH);
  startTime = micros();
  for (x = 0; x < loopCount; x++){
    digitalWrite(digitalPin,HIGH);
    digitalWrite(digitalPin,LOW);
  }
  totalTime = micros() - startTime;
  digitalWrite(ledPin,LOW);
  Serial.print(F("Digital Pin Write Takes About "));
  //Serial.print(totalTime / 2);
  //Serial.print(F(" Microseconds And Each 'digitalWrite' Took About "));
  Serial.print((float)totalTime / (float)loopCount / 2.0, 4);
  Serial.println(F(" Microseconds."));
  Serial.flush();
  delay(1000);
 
  // Digital Read
  pinMode(digitalPin,INPUT);
  digitalWrite(ledPin,HIGH);
  startTime = micros();
  for (x = 0; x < loopCount; x++){
    ar = digitalRead(digitalPin);
  }
  totalTime = micros() - startTime;
  digitalWrite(ledPin,LOW);
  Serial.print(F("Digital Pin Read  Takes About "));
  Serial.print((float)totalTime / (float)loopCount, 4);
  Serial.println(F(" Microseconds."));
  Serial.flush();
  delay(1000);
 
  // Analogue
  digitalWrite(ledPin,HIGH);
  startTime = micros();
  for (x = 0; x < loopCount; x++){
      ar = analogRead(analoguePin);
  }
  totalTime = micros() - startTime;
  digitalWrite(ledPin,LOW);
  Serial.print(F("Analogue Pin Read Takes About "));
  //Serial.print(totalTime / 2);
  //Serial.print(F(" Microseconds And Each 'digitalWrite' Took About "));
  Serial.print((float)totalTime / (float)loopCount, 4);
  Serial.println(F(" Microseconds."));
  Serial.flush();
  delay(1000);

  //AnalogWrite
  digitalWrite(ledPin, HIGH);
  startTime = micros();
  for (x = 0; x < loopCount; x++){
    analogWrite(9, map(x, 0, loopCount, 0, 255));
  }
  totalTime = micros() - startTime;
  digitalWrite(ledPin, LOW);
  Serial.print(F("PWM Write Takes About "));
  //Serial.print(totalTime / 2);
  //Serial.print(F(" Microseconds And Each 'digitalWrite' Took About "));
  Serial.print((float)totalTime / (float)loopCount, 4);
  Serial.println(F(" Microseconds."));
  Serial.println();
  Serial.flush();
  delay(1000);

  //mapping
  startTime = micros();
  for (x = 0; x < loopCount; x++)
  {
    y = map(x, 0, loopCount, 0, 255);
  }
  totalTime = micros() - startTime;
  Serial.print(F("Mapping Takes About "));
  //Serial.print(totalTime / 2);
  //Serial.print(F(" Microseconds And Each 'digitalWrite' Took About "));
  Serial.print((float)totalTime / (float)loopCount, 4);
  Serial.println(F(" Microseconds."));
  Serial.println();
  Serial.flush();
  delay(1000);   
 
}
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: DrDiettrich on Jul 06, 2016, 09:58 am
Provided that the system clock of the 101 is 32MHz, your times can not be correct. When one instruction takes at least 30ns, how can anything execute faster than that, by a factor of 100?
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Mike44449 on Jul 06, 2016, 09:28 pm
I ran the benchmark through 5000 iterations, that is the number on the left, to run through the entire loop. I then proceeded to divide each result by 5000 to get the number on the right. I have not made up any numbers (not implying you are saying that). The numbers above are what I received over serial.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: westfw on Jul 06, 2016, 11:22 pm
Quote
Digital Write:                     1.5634 Microseconds (.31 nanoseconds per execution)
Did you divide by 5000 twice?  1.5634 Microseconds has to be a divided quantity, because nothing measures less than 1us...

Also, your output file doesn't match your source code.

Code: [Select]
  Serial.print(F("Digital Pin Write Takes About "));
  //Serial.print(totalTime / 2);
  //Serial.print(F(" Microseconds And Each 'digitalWrite' Took About "));
  Serial.print((float)totalTime / (float)loopCount / 2.0, 4);

vs
Quote
Digital Write:           1.5634  Microseconds to loop;            0.00031 Microseconds per execution.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: DrDiettrich on Jul 07, 2016, 04:08 am
What's the time for an empty loop? This time should be subtracted from the totalTime of the statements to benchmark.

Also check: will a different loopCount (e.g. 100 or 10000) change the times?

I could imagine that the compiler optimized every loop into a single assignment to x, and a single execution of the loop body. Only a look into the generated assembly code can reveal what's really going on.

As is, the times are bogus :-(
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Mike44449 on Jul 07, 2016, 04:28 am
Also, your output file doesn't match your source code.

It's just a file that I typed up from looking at the Serial monitor.


Did you divide by 5000 twice?
The only explanation I can find is that the sketch is already dividing, I divided each number that I received by the loop count, to get a number like 0.00032, which is .32 nano seconds. I obviously did not go through the program well enough.

As is, the times are bogus :-(
I am quite aware of that
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Mike44449 on Jul 07, 2016, 06:12 am
I had some time to go through, so I corrected my mistakes, with much greater detail.

- I have made my own benchmark sketch, using parts from Riva's code (so some credit goes to Riva)
- I have made a much more detailed file, which includes actual serial output
- I tested 10, 5k, and 10k iterations
- The file has the details at the top, then serial output at the bottom. It is very long so I labeled the line that each set of iterations begins on

The Table:

Code: [Select]
Board: Arduino 101 @ 32 MHz
IDE:   v1.6.9
Buad Rate of Serial: 115,200
Iterations per benchmark: 10 | 5,000 | 10,000

=====Digital Reading====

Iterations: 10
Digital Read of Pin 5 (total)  :         20.000 Microseconds
Digital Read of Pin 5 (per)  :            2.000 Microseconds

Iterations: 5,000
Digital Read of Pin 5 (total)  :      8,920.000 Microseconds
Digital Read of Pin 5 (per)  :            1.784 Microseconds

Iterations: 10,000
Digital Read of Pin 5 (total)  :     17,836.000 Microseconds
Digital Read of Pin 5 (per)  :            1.784 Microseconds

Average Time per Read  :                  1.856 Microseconds

====Digital Writing====

Iterations: 10
Digital Write of Pin 5 (total)  :        18.500 Microseconds
Digital Write of Pin 5 (per)  :           1.850 Microseconds

Iterations: 5,000
Digital Write on Pin 5 (total) :      8,758.000 Microseconds
Digital Write on Pin 5 (per)  :           1.757 Microseconds

Iterations: 10,000
Digital Write on Pin 5 (total)  :    17,514.000 Microseconds
Digital Write on Pin 5 (per)  :           1.751 Microseconds

Average Time per Write  :                 1.786 Microseconds

====Analog Reading====

Iterations: 10
Analog Read on Pin A0 (total)  :        273.000 Microseconds
Analog Read on Pin A0 (per)  :           27.300 Microseconds

Iterations: 5,000
Analog Read on Pin A0 (total) :     140,082.000 Microseconds
Analog Read on Pin A0 (per)  :           28.016 Microseconds

Iterations: 10,000
Digital Read of Pin A0 (total)  :   280,365.000 Microseconds
Digital Read of Pin A0 (per)  :          28.036 Microseconds

Average Time per Read  :                 27.784 Microseconds

====PWM Writing (un-adjusted)====

Iterations: 10
PWM Write of Pin 5 (total)  :            52.500 Microseconds
PWM Write of Pin 5 (per)  :               5.250 Microseconds

Iterations: 5,000
PWM Write on Pin 5 (total)  :        23,805.000 Microseconds
PWM Write on Pin 5 (per)  :               4.761 Microseconds

Iterations: 10,000
Digital Write on Pin 5 (total)  :    47,605.000 Microseconds
Digital Write on Pin 5 (per)  :           4.761 Microseconds

Average Time per Write  :                 4.924 Microseconds

====PWM Writing (adjusted)====

Iterations: 10
PWM Write of Pin 5 (total)  :            28.000 Microseconds
PWM Write of Pin 5 (per)  :               2.800 Microseconds

Iterations: 5,000
PWM Write on Pin 5 (total)  :        12,389.000 Microseconds
PWM Write on Pin 5 (per)  :               2.479 Microseconds

Iterations: 10,000
Digital Write on Pin 5 (total)  :    24,777.000 Microseconds
Digital Write on Pin 5 (per)  :           2.478 Microseconds

Average Time per Write  :                 2.586 Microseconds
  
====Empty Loop====

Iterations: 10
Empty Loop (total)  :                     2.000 Microseconds
Empty Loop (per)  :                       0.200 Microseconds

Iterations: 5,000
Empty Loop (total)  :                   471.000 Microseconds
Empty Loop (per)  :                       0.094 Microseconds

Iterations: 10,000
Empty Loop (total)  :                   938.500 Microseconds
Empty Loop (per)  :                       0.094 Microseconds

Average Time per Loop  :                  0.130 Microseconds

====Mapping 0-5000 to 0-255====

Iterations: 10
Mapping (total)  :                       24.000 Microseconds
Mapping (per)  :                          2.400 Microseconds

Iterations: 5,000
Mapping (total)  :                   11,415.000 Microseconds
Mapping (per)  :                          2.283 Microseconds

Iterations: 10,000
Mapping (total)  :                   22,828.000 Microseconds
Mapping (per)  :                          2.282 Microseconds

Average Time per Map  :                   2.322 Microseconds




The code to get the information:

Code: [Select]

const uint16_t ITERATIONS = 10000;
const uint8_t DIGITAL_PIN = 5;
const uint8_t ANALOG_PIN = A0;

uint32_t startTime, totalTime;
uint16_t loopCount, d_read, a_read, map_test;

const uint16_t SESSION_LENGTH = 401;
uint16_t cycleCount = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial);

  pinMode(ANALOG_PIN, INPUT);
}

void loop() {
  for (int x = 0; x < SESSION_LENGTH; x++)
  {
    TEST_D_READ();
    TEST_D_WRITE();
    TEST_A_READ();
    TEST_A_WRITE();
    TEST_LOOP();
    TEST_MAP();
    
    //delay(500);
    
    cycleCount++;
    Serial.print("Cycle: ");
    Serial.println(cycleCount);    
    Serial.println();
  }
  
  for(;;)
  {}

  
}

void TEST_D_READ() {
  startTime = micros();
  
  for (loopCount = 0; loopCount < ITERATIONS; loopCount++) {
    d_read = digitalRead(DIGITAL_PIN);
  }
  
  totalTime = micros() - startTime;

  Serial.print("Digital Read: ");
  Serial.print((float)totalTime, 4);
  Serial.println(" Microseconds");
  Serial.flush();
}

void TEST_D_WRITE() {
  startTime = micros();
  
  for (loopCount = 0; loopCount < ITERATIONS; loopCount++) {
    digitalWrite(DIGITAL_PIN, HIGH);
    digitalWrite(DIGITAL_PIN, LOW);
  }
  
  totalTime = micros() - startTime;

  Serial.print("Digital Write: ");
  Serial.print((float)totalTime / 2.0, 4);
  Serial.println(" Microseconds");
  Serial.flush();  
}

void TEST_A_READ() {
  startTime = micros();
  
  for (loopCount = 0; loopCount < ITERATIONS; loopCount++) {
    a_read = analogRead(ANALOG_PIN);
  }
  
  totalTime = micros() - startTime;

  Serial.print("Analog Read: ");
  Serial.print((float)totalTime, 4);
  Serial.println(" Microseconds");  
  Serial.flush();  
}

void TEST_A_WRITE() {
  startTime = micros();
  
  for (loopCount = 0; loopCount < ITERATIONS; loopCount++) {
    analogWrite(DIGITAL_PIN, map(loopCount, 0, ITERATIONS, 0, 255));
  }
  
  totalTime = micros() - startTime;

  Serial.print("PWM Write (not adjusted for mapping time): ");
  Serial.print((float)totalTime, 4);
  Serial.println(" Microseconds");
  Serial.flush();  
}

void TEST_LOOP() {
  startTime = micros();
  
  for (loopCount = 0; loopCount < ITERATIONS; loopCount++) {
    
  }
  
  totalTime = micros() - startTime;

  Serial.print("Empty Loop: ");
  Serial.print((float)totalTime, 4);
  Serial.println(" Microseconds");
  Serial.flush();  
}

void TEST_MAP() {
  startTime = micros();
  
  for (loopCount = 0; loopCount < ITERATIONS; loopCount++) {
    map_test = map(loopCount, 0, ITERATIONS, 0, 255);
  }
  
  totalTime = micros() - startTime;

  Serial.print("Mapping: ");
  Serial.print((float)totalTime, 4);
  Serial.println(" Microseconds");
  Serial.flush();  
}

Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: westfw on Jul 07, 2016, 06:35 am
Quote
The only explanation I can find is that the sketch is already dividing
Yes, it is:

Code: [Select]
 Serial.print((float)totalTime / (float)loopCount / 2.0, 4);
The first numbers:
Quote
Digital Write:                     1.5634 Microseconds
Digital Read:                      1.3131 Microseconds
Analog Read:                    27.9999 Microseconds
Analog Write (PWM):           2.2391 Microseconds
Mapping 0-5000 to 0-255:     1.9063 Microseconds
Are pretty reasonable looking for a single execution.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: KatyaS on Oct 09, 2016, 11:20 am
Hi Riva,

These are interesting information.

You did tested for Nucleo STM32F401 board which I also intent to buy this one. But I still confuse that whether this board can be official Arduino supported (the official means that the Arduino core is developed by Arduino or TI)?

Thank you in advance.

Regards,

Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: MAS3 on Oct 09, 2016, 05:08 pm
Hi KatyaS.

Your confusion must be greater than you realise yourself.

STMxxxxxx are STMicro products.
TI has nothing to do with that.
Most Arduino products are based on Atmel ARM technology, but there are different tastes.
There are even Intel based products.

I can understand one would like a single IDE to be used for different products, but how smart would it be to do that ?
You still need to take the chips possibilities in consideration, and how well would an IDE create code if it has to work well with all types of chips ?

I don't know whether there are extensions so the Arduino IDE will work with STM products, but such extensions do exist (You already found out about ESP and such).
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Oct 10, 2016, 08:52 am
You did tested for Nucleo STM32F401 board which I also intent to buy this one. But I still confuse that whether this board can be official Arduino supported (the official means that the Arduino core is developed by Arduino or TI)?
As MAS3 says TI do not do the STM32 series of MCU but it is done by STMicroelectronics (http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-nucleo/nucleo-f401re.html).
Alas the STM32401 series of MCU is not well supported on the Arduino with a custom core so I wrote the benchmark above using it's native mbed (https://developer.mbed.org/platforms/ST-Nucleo-F401RE/) core. There are several other variants of the STM32 that are better supported on the Arduino and I suggest you have a look here (http://www.stm32duino.com/) for more information on what cores are best supported. The STM32 board are usually incredibly cheap to buy and can offer a great performance boost compared to the AVR chips used in a lot of Arduinos.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: westfw on Oct 10, 2016, 09:27 am
The Arduino.org "Star Otto" board uses a STM32F469 - that should be similar to the STM32F401...
(exact status from an availability or "supported by working software" point of view is ... a bt murky.)
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: jnowak1054 on Sep 24, 2018, 05:23 pm
Put together admittedly terrible comparison graphs of the processor performance, definitely best viewed on a computer screen. https://docs.google.com/spreadsheets/d/1sdvYqO1_kOBfyyrNLGrRKf8PxKy810HnX6CFYwvSFqs/edit?usp=sharing
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on Dec 08, 2018, 03:25 pm
Managed to get my hands on a SAMD21 Zero clone and run the benchmark in #1 after converting references of Serial to SerialUSB and am surprised at how slow it is, especially the analogRead.
I have added results to the first post but for reference here, they are repeated.
Code: [Select]

Arduino Zero I/O Speed Tests Over 50000 Iterations. Compiled Using Arduino IDE v1.8.7
Digital Pin Write Takes About 1.6234 Microseconds.
Digital Pin Read  Takes About 1.0264 Microseconds.
Analogue Pin Read Takes About 423.2541 Microseconds.
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: sblantipodi on May 22, 2019, 10:41 am
it would be interesting to see some comparison between the new nanos and the ESP8266/ESP32...
is there something like this on the net, can't find it?
Title: Re: Microcontroller I/O & ADC Benchmarks
Post by: Riva on May 25, 2019, 10:04 am
Have just done the test on an ESP32

Code: [Select]
ESP32 DoIt ESP32 Devkit V1 (80MHz) I/O Speed Tests Over 50000 Iterations. Compiled Using Arduino IDE v1.8.9 and 1.0.2 Core
Digital Pin Write Takes About 0.1199 Microseconds.
Digital Pin Read  Takes About 0.1642 Microseconds.
Analogue Pin Read Takes About 10.3027 Microseconds.