Interrupt Delays and read_timed

The official PYBD running MicroPython, and its accessories.
Target audience: Users with a PYBD
Post Reply
machdisk
Posts: 16
Joined: Sun May 22, 2016 1:35 am

Interrupt Delays and read_timed

Post by machdisk » Fri Nov 20, 2020 6:41 pm

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 boot.py: 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=2&t=6840&hilit=trigger+delay&start=10
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
micropython.alloc_emergency_exception_buf(100)

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):
    n=adc.read_timed(buf,timerADC)
    global trigCount
    trigCount+=1
    # gc.collect()
    micropython.schedule(sumCB, 'Sum Arrays')


ex1 = ExtInt('X9', ExtInt.IRQ_RISING, Pin.PULL_UP, readCB)  
Attachments
PYBD_ADC_v1.png
PYBD_ADC_v1.png (118.88 KiB) Viewed 2612 times
PYBD_ADC_END_v1.png
PYBD_ADC_END_v1.png (93.68 KiB) Viewed 2612 times

machdisk
Posts: 16
Joined: Sun May 22, 2016 1:35 am

Re: Interrupt Delays and read_timed

Post by machdisk » Sat Nov 21, 2020 5:27 am

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.

Cheers
Attachments
PYBD_ADC_v2.png
PYBD_ADC_v2.png (21.75 KiB) Viewed 2589 times
PYBD_ADC_v2_Zoom.png
PYBD_ADC_v2_Zoom.png (14.58 KiB) Viewed 2589 times

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Interrupt Delays and read_timed

Post by pythoncoder » Sat Nov 21, 2020 10:20 am

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.
Peter Hinch
Index to my micropython libraries.

Post Reply