ADC performance of MicroPython boards

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
rcolistete
Posts: 139
Joined: Thu Dec 31, 2015 3:12 pm
Location: Brazil

ADC performance of MicroPython boards

Post by rcolistete » Sun Nov 20, 2016 7:12 pm

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.

User avatar
rcolistete
Posts: 139
Joined: Thu Dec 31, 2015 3:12 pm
Location: Brazil

Re: ADC performance of MicroPython boards

Post by rcolistete » Sun Nov 27, 2016 4:24 am

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.

cadcam
Posts: 2
Joined: Thu Dec 08, 2016 3:45 pm

Re: ADC performance of MicroPython boards

Post by cadcam » Thu Dec 08, 2016 4:12 pm

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

ckuehnel
Posts: 6
Joined: Sat Feb 02, 2019 3:09 pm

Re: ADC performance of MicroPython boards

Post by ckuehnel » Sun Feb 10, 2019 2:47 pm

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]

User avatar
Roberthh
Posts: 1418
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: ADC performance of MicroPython boards

Post by Roberthh » Sun Feb 10, 2019 3:10 pm

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.

Post Reply