Performance of ADC with micropython and pico #12899
Replies: 2 comments 4 replies
-
I can assure you that the full 500 ksps are not a problem at all. Either using DMA into a buffer of a given size - singleshot. But by simply using the tools Micropython gives you, quite a good speed can be achieved. #!/usr/bin/python3
# -*- coding: UTF-8 -*-
# vim:fileencoding=UTF-8:ts=4
from array import array
from machine import ADC
from time import ticks_ms, ticks_diff, sleep_ms
def measure(data):
index = 0
adc = ADC(ADC.CORE_TEMP)
f = adc.read_u16
t0 = ticks_ms()
while index < NUM:
data[index] = f()
index += 1
t1 = ticks_ms()
td_µs = ticks_diff(t1, t0) * 1e3
print(f'{td_µs/NUM:6.2f} µs/conversion {1e6/td_µs*NUM:6.0f} sps')
sleep_ms(20)
@micropython.native
def measure_native(data):
index = 0
adc = ADC(ADC.CORE_TEMP)
f = adc.read_u16
t0 = ticks_ms()
while index < NUM:
data[index] = f()
index += 1
t1 = ticks_ms()
td_µs = ticks_diff(t1, t0) * 1e3
print(f'{td_µs/NUM:6.2f} µs/conversion {1e6/td_µs*NUM:6.0f} sps')
sleep_ms(20)
@micropython.viper
def measure_viper(data):
d: ptr16 = ptr16(data)
_num: int = int(NUM)
index: int = 0
adc = ADC(ADC.CORE_TEMP)
f = adc.read_u16
t0: int = ticks_ms()
while index < _num:
d[index] = int(f())
index += 1
t1: int = ticks_ms()
td_µs = ticks_diff(t1, t0) * 1e3
print(f'{td_µs/NUM:6.2f} µs/conversion {1e6/td_µs*NUM:6.0f} sps')
sleep_ms(20)
NUM = const(10_000)
data = array('H', (0 for _ in range(NUM)))
print('start')
measure(data)
measure_native(data)
measure_viper(data) Edit: Forgot the results… |
Beta Was this translation helpful? Give feedback.
-
I have successfully digitized 250 ksps using micropython.viper mode code. This is running the ADC in its continuous mode, but to get this speed, I run it in a thread on the second core, and monitor the FIFO overrun bits to make sure it is keeping up. If I try to run any faster, I get overruns This gives a complete, python-only and no DMA solution. You can use DMA to run at the full speed. Note that the 250 ksps speed I can get includes real-time IQ demodulating the signal (using a sine lookup table), so I am doing a fair amount of math on the fly. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello all,
I have just started to dig in micropython with a raspberry pico w.
I wanted to see the performance of the ADC module, to see the maximum sampling rate at which it could acquire a signal.
I have made a simple test with this function:
(EDIT: I have also tested with array.array and deque but I got similar results)
I am using the timed_function decorator from the micropython documentation.
I am quite disappointed with the result, around 110us with the frequency at 125 Mhz. I guess with this result, the maximum sampling rate would be around 5kHz and considering only one channel...
I am not so familiar with microcontroller. Is this limit due to 125 Mhz frequency? Or because of micropython itself? Or is something sub-optimal in my simple function?
I (maybe naively) thought I would easily be able to have a sample rate of 100kHz or even 1 Mhz if using only one channel. Do you think it would be possible to reach such sampling rate using another board? I would not have to post-process the data within the microcontroller (even if it would be better), I could forward the data to the PC via ethernet and then post-process there (but not sure if Python on PC runs faster to post-process all the data).
Beta Was this translation helpful? Give feedback.
All reactions