Page 1 of 1

Interrupt Delays and read_timed

Posted: Fri Nov 20, 2020 6:41 pm
by machdisk
I am trying to synchronize an external trigger with the start of the read_timed function into a buffer. The issue that I'm having is that the start of the read_timed function appears to be delayed from the timing of the interrupt pin. My mechanism of testing this is to have the start of the input waveform (not the trigger) have an abnormally high value. The oddity is that this high level appears at the end of the buffer and not the beginning. Also, the index at which the high level is recorded varyies slightly between triggers. This brings up a few questions:

Does this mean the buffer is always running?

How much of delay is there between the IRQ event and the start of the read_timed function?

I believe I'm missing something critical and would appreciate any insights. Ideally, there would be a mechanism to acquire a circular buffer and mark when a trigger arrives and simply roll the array. In short, I'd like to realize some sort of scope type function as my application requires multiple signal averaging events to obtain decent signal to noise ratio.

PYBD SF3W 1.12 with the ulab library
Other pertinent details include setting the system frequency in machine.freq(216000000)

Other relevant posts that don't fully address the issue:
viewtopic.php?f=16&t=9163&p=51609&hilit ... lay#p51609
viewtopic.php?f=6&t=4700&p=27229&hilit= ... upt#p27229

Code: Select all

import micropython
from pyb import ExtInt, Pin, LED
import ulab as np
import gc

trigCount = 0

adc = pyb.ADC('X1')
buf = np.zeros(10000)
sumBuf = np.zeros(10000)
timerADC = pyb.Timer(4, freq=200000) 

def sumCB(arg):
    So the question is whether or not we disable IRQs during this operation?
    What if another trigger comes?
    Ultimately to be used for signal averaging
    global sumBuf
    global buf
    sumBuf = buf+sumBuf
    # gc.collect()

def readCB(arg):
    global trigCount
    # gc.collect()
    micropython.schedule(sumCB, 'Sum Arrays')

ex1 = ExtInt('X9', ExtInt.IRQ_RISING, Pin.PULL_UP, readCB)  

Re: Interrupt Delays and read_timed

Posted: Sat Nov 21, 2020 5:27 am
by machdisk
After stepping away from this issue for a few hours, I had a few realizations (many of which turned out not to be quite right), but a key finding is that there was sufficient ringing on the input trigger to also trigger a second acquisition using read_timed on the falling edge. To be clear, I was using an input 50% duty cycle square wave as the trigger to start the acquistion which also triggered my external waveform generator. This realization allowed me to better define my test setup and as a result I am happy to say that I'm now capturing the trigger at the correct time. There is a little shaving off of the front end following the trigger (maybe 4-8 us) which I attribute to a few compute cycles. As you can see new waveforms capture the input pulse adequately now, though the first part of the rising edge is clipped (this is ok for me).

Down the road if there is a way to simply read ADC into a circular buffer linked to a timer, that is modifiy the read timed version to simply keep cycling through the buffer and not only fill it once, it would be awesome to simply have an interrupt timer stop the read and the it would be a relatively simply exercise to roll the array to get the full waveform with little to no delay. I know this is basically DMA but that level is a bit beyond my skill set.

Well, I hope this helps someone else out in the future--or at least help them avoid some of my same mistakes. In the future I'll put a resistor on the trigger input to avoid triggering on the falling edge and also be sure to give plenty of time for the read_timed function to finish before the next trigger arrives.


Re: Interrupt Delays and read_timed

Posted: Sat Nov 21, 2020 10:20 am
by pythoncoder
The issue of nonblocking, DMA-driven, ADC (and DAC) operation has been discussed from time to time but has not yet been implemented. It would be an excellent enhancement.