Page 1 of 2

ADC performance of MicroPython boards

Posted: Sun Nov 20, 2016 7:12 pm
by rcolistete
ADC performance tests of MicroPython boards :

- 'ADC_timedtimer_Pyboard.py' as only Pyboard has "ADC.read.timed()" method to ADC read burst into buffer in high speed. Test with 20 thousand readings, mean speed in ksample/s :
* Pyboard v1.1 (12 bits ADC) with MicroPython v1.8.6 : 1,604;
* Pyboard Lite v1.0 (12 bits) with MicroPython v1.8.6 : 899.6;

- 'ADC_loop' (download here for different boards) with 20 thousand readings, mean speed in ksample/s :
* Pyboard v1.1 (12 bits ADC) with MicroPython v1.8.6 : 34.9;
* Pyboard Lite v1.0 (12 bits) with MicroPython v1.8.6 : 20.1;
* WiPy 1.0 (12 bits) with MicroPython v1.8.2-103 : 62.5;
* ESP8266 (10 bits) with MicroPython v1.8.6-7 : 5.44 (80 MHz) / 7.34 (160 MHz);
* BBC Micro:bit (10 bits) with MicroPython v1.7.9 : 6.51;
* LoPy (12* bits) with MicroPython 0.9.6.b1 : 21.2.
* WiPy2 (12* bits) with MicroPython 0.9.6.b1 : 21.3.
* Teensy 3.2 (16 bits) with MicroPython v1.8.6 : 59.6;
* Teensy 3.5 (16 bits) with MicroPython v1.8.6 : 62.3;
* Teensy 3.6 (16 bits) with MicroPython v1.8.6 : 107.
(*) : this firmware is limiting the ADC to only 10 bits, 0-1V.
For example, "ADC_loop_Pyboard.py" :

Code: Select all

# ADC_loop_Pyboard.py
# Reads the Pyboard ADC and measures the time and speed to read 20000 samples.
import pyb
def ADCloopBenchmark():
    adc = pyb.ADC('X1')
    adcread = adc.read
    t1=pyb.micros()
    for i in range(20000):
        val = adcread()
    t2=pyb.micros()
    print("20000 ADC readings done after %u us." %(t2-t1))
    print("Mean time for each ADC reading = %15.13f us" % ((t2-t1)/20000.0))
    print("ADC reading = %15.13f ksamples/s" % (1000/((t2-t1)/20000.0)))
ADCloopBenchmark()
Pyboard (v1.1) is the champion MicroPython board, with 1.6 Msamples/s, for ADC burst reading ! :shock: Followed by Pyboard Lite with 0.9 Msamples/s in this mode.

For continuously ADC reading inside a loop, Teensy board and WiPy 1.0 are the fastest, followed by the Pyboard's. BBC Micro:bit surprised me, as its MCU is nRF51822 with ARM Cortex-M0 @ 16MHz.

Re: ADC performance of MicroPython boards

Posted: Sun Nov 27, 2016 4:24 am
by rcolistete
Updated the ADC benchmark on LoPy and WiPy 2 using firmware 0.9.6.b1.

See historic evolution of these benchmarks for LoPy and WiPy 2.

Re: ADC performance of MicroPython boards

Posted: Thu Dec 08, 2016 4:12 pm
by cadcam
the use of micropython as the basis of a multi-channel datalogger is really interesting, however most effort.benchmarking seems to have been done for single channel aquisition. I may have missed it but has anyone being working on a general system that will allow simple acquisition of multiple channels with logging syncronously to buffers[ straight/dual or ring]/flash/sd card or even to usb/uart/wifi?

Ideally a series of simple set up calls to

a) Allocate channels to pins
e.g. adc_channel_pins(12,13,8,6...)
b) Which channels to log , destination, dataformat, datarate, n_samples
e.g. adc_log([1,2,4,5], buf, H,1000,50000) or adc_log([1,2,4,5]. sd/data.csv,csv,500,10000)

Of course other ideals would be a trigger/pretrigger, DMA (where available) + possibly warning message re predicted jitter, for a particular system, time stamping [To allow interleaving with other data from I2C etc]

Obviously a large number of ideals but there seems to have been some previous work on various aspects however I haven't seen a plan for a standard set of routines or have I missed it (many apologies if I have)


Regards

Re: ADC performance of MicroPython boards

Posted: Sun Feb 10, 2019 2:47 pm
by ckuehnel
Here is the ADC performance for an ESP32_Core_board v2:

20000 ADC reading done after 995697 us.<br/>
Mean time for each ADC reading = 49.7848510742188 us<br/>
ADC reading = 20.0864315032959 ksamples/s</t>

[code]
# ADC_loop_ESP32.py
# Reads the ESP32 ADC and measures the time and speed to read 20000 samples.
# based on http://www.robertocolistete.net/MicroPy ... C_loop.zip

import machine
from machine import Pin
from machine import ADC
import time

def ADCloopBenchmark():
adc = machine.ADC(Pin(32))
adcread = adc.read()
t1 = time.ticks_us()
for i in range(20000):
adcread = adc.read()
t2 = time.ticks_us()
print("20000 ADC readings done after %u us." %(t2-t1))
print("Mean time for each ADC reading = %15.13f us" % ((t2-t1)/20000.0))
print("ADC reading = %15.13f ksamples/s" % (1000/((t2-t1)/20000.0)))

ADCloopBenchmark()
[/code]

Re: ADC performance of MicroPython boards

Posted: Sun Feb 10, 2019 3:10 pm
by Roberthh
Did the same on a ESP32 without SPIRAM with PyCom's WiPy firmware. Some figures:
- Simple loop as yours, ~60 µs iteration. If you deduct the time the loop control and assignment, the net time is ~52µs. The ESP32 runs at 160MHz
- Stuffing the loop with code to store the data in a ring buffer: Loop iteration take ~72µs.
Still, this kind of code is not useful for sampling any signal beyond 1 kHz, given that in real code a significant jitter has to be expected.

These are raw values, precise enough for the purpose.

Re: ADC performance of MicroPython boards

Posted: Wed Apr 08, 2020 3:56 pm
by sibir
The PyBoard's ADC.read.timed() should not have jitter since it's timer based.
But because it's blocking you cannot use it for sustained data logging.
For an oscilloscope-like application where you only need one trace at a time it should be sufficient however.

Can anyone with a D-series PyBoard and/or a Teensy 4.0 run these tests and report back?

Re: ADC performance of MicroPython boards

Posted: Thu Apr 09, 2020 7:59 pm
by P@T
Hi all,

Beware of the adc of esp32 they are bad
-7 +7 LSB
That's huge

Thank you for the test

Re: ADC performance of MicroPython boards

Posted: Thu May 21, 2020 2:33 am
by sibir
Here is a sawtooth sampled with ESP32. Note the non-linearity:
ESP32.png
ESP32.png (10.48 KiB) Viewed 10617 times
The same looks better (more linear and less noisy) on the ESP8266
ESP8266.png
ESP8266.png (11.08 KiB) Viewed 10617 times
But in both cases there are periodic outliers.
One could probably run slightly faster by optimizing the code. I simply used:

Code: Select all

for i in range(1000): data.append(adc.read())

Re: ADC performance of MicroPython boards

Posted: Thu May 21, 2020 3:56 am
by tve
To be fair: MP doesn't use the esp32's IDF calibration routines...

Re: ADC performance of MicroPython boards

Posted: Tue Nov 17, 2020 10:36 pm
by machdisk
Report on the Pyboard-D SF3W running Micropython 1.13-173:

With machine.freq(48000000) the code at http://www.robertocolistete.net/MicroPy ... Pyboard.py yields sample rates that vary between 435 and 477 kSps.

@ machine.freq(216000000) the script yeilds rates that hover just around 2147 kSps.

The standard loop script (i.e. the ADC benchmark loop): 36.6 kSps

With that said, running the PYBD with the readtimed function appears to be quite impressive. I will throw in a waveform and report back later.