The Python Oracle

Python rising/falling edge oscilloscope-like trigger

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Book End

--

Chapters
00:00 Python Rising/Falling Edge Oscilloscope-Like Trigger
00:51 Accepted Answer Score 11
01:24 Answer 2 Score 6
01:57 Answer 3 Score 0
02:26 Thank you

--

Full question
https://stackoverflow.com/questions/5036...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #numpy #edgedetection

#avk47



ACCEPTED ANSWER

Score 11


We could slice one-off and compare against the trigger for smaller than and greater than, like so -

In [41]: data = np.array([-1, -0.5, 0, 0.5, 1, 1.5, 2, 0, 0.5])

In [43]: trigger_val = 0.3

In [44]: np.flatnonzero((data[:-1] < trigger_val) & (data[1:] > trigger_val))+1
Out[44]: array([3, 8])

If you would like to include equality as well, i.e. <= or >=, simply add that into the comparison.

To include for both rising and falling edges, add the comparison the other way -

In [75]: data = np.array([-1, -0.5, 0, 0.5, 1, 1.5, 2, 0.5, 0])

In [76]: trigger_val = 0.3

In [77]: mask1 = (data[:-1] < trigger_val) & (data[1:] > trigger_val)

In [78]: mask2 = (data[:-1] > trigger_val) & (data[1:] < trigger_val)

In [79]: np.flatnonzero(mask1 | mask2)+1
Out[79]: array([3, 8])



ANSWER 2

Score 6


So I was just watching the latest 3Blue1Brown video on convolution when I realized a new way of doing this:

def rising_edge(data, thresh):
    sign = data >= thresh
    pos = np.where(np.convolve(sign, [1, -1]) == 1)
    return pos

So, get all the positions where the data is larger or equal to the threshold, do a convolution over it with [1, -1], and then just find where the convolution returns a 1 for a rising edge. Want a falling edge? Look for -1 instead.

Pretty neat, if I do say so myself. And it's about 5-10% faster.




ANSWER 3

Score 0


The way I made it while programming in microPython for the Raspberry Pi Pico is: I keep reading the state of the signal (HIGH or LOW) and storing it for later. When "later" comes I make a reading again and compare the old and the current signal.

If the old signal was HIGH and the current is LOW I know I had a falling edge. The same way if the old signal was LOW and the current is HIGH I know I had a rising edge.

Here is my take: How can I discriminate the falling edge of a signal with Python?