I think the IRQ feature could be used to achieve this.
And yes! Your sample code using IRQ. The 200ms sleep act like the timeout.
Code: Select all
from machine import Pin, Timer
from rp2 import PIO, StateMachine, asm_pio
import time
Counter = 0
gotCounter = False
def smIrqHandler(sm):
global Counter
global gotCounter
_counter = sm.get()
if not gotCounter:
Counter = 1 + ( _counter ^ 0xffffffff) # 2's complement
gotCounter = True
@rp2.asm_pio(set_init=rp2.PIO.IN_LOW, autopush=True, push_thresh=32)
def mark():
wrap_target()
set(x, 0)
wait(0, pin, 0) # Wait for pin to go low
wait(1, pin, 0) # Low to high transition
label('low_high')
jmp(x_dec, 'next') # unconditional
label('next')
jmp(pin, 'low_high') # while pin is high
in_(x, 32) # Auto push: SM stalls if FIFO full
irq(0)
wrap()
pin16 = Pin(16, Pin.IN, Pin.PULL_UP)
sm0 = rp2.StateMachine(0, mark, in_base=pin16, jmp_pin=pin16)
sm0.irq(smIrqHandler)
sm0.active(1)
#pin17 = Pin(17, Pin.OUT)
#tim = Timer(freq=1000, mode=Timer.PERIODIC, callback=lambda _: pin17(not pin17( )))
maxval = 0
minval = 1000_000
while True:
if gotCounter:
a = Counter
maxval = max(maxval, a)
minval = min(minval, a)
print(a, maxval, minval)
gotCounter=False
else:
print(0)
time.sleep_ms(200)