Interrupt handling for ADC reading at fixed sample rates #11610
-
@peterhinch, thank you for writing these great docs about asyncio and interrupts! Still I need some expert advice...
Is this the right way to do it to avoid race conditions and to have a fixed sample rate? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
Your |
Beta Was this translation helpful? Give feedback.
-
I would use a from machine import Pin, ADC, Timer
import array
import uasyncio as asyncio
from threadsafe import ThreadSafeQueue
adc = ADC(Pin(1))
timer = Timer(0)
buffer_size = 100
buffer = array.array('H')
tsq = ThreadSafeQueue(buffer)
timer.init(freq=10_000, mode=Timer.PERIODIC, callback= isr)
def isr(_): # Interrupt handler
tsq.put_sync(adc.read_u16()) # Put ADC value on queue
async def run():
async for item in tsq:
# process the data item
asyncio.run(run()) This offers no protection against items arriving faster than you can process them. The docs suggest ways of dealing with this, but inevitably data will be discarded. A 10KHz rate is very demanding. There are two issues. Firstly ESP32 does not support hard interrupts, so if a garbage collect is in progress IRQ's will be missed. Platforms like RP2 (and STM if you can get it) support hard IRQ's and are better suited to high speed work. Secondly, it's a high rate for micropython: you need your processing code to run very quickly to match the throughput. |
Beta Was this translation helpful? Give feedback.
I would use a
ThreadSafeQueue
. This simplifies the code and avoids needless RAM allocations. See the doc. Something along these lines:This offers no protection against items arriving faster than you can process them. T…