micropython-samples/rp2/measure_pulse/measure_pulse.py

69 wiersze
1.8 KiB
Python

# measure_pulse.py Measure a pulse train with PIO
# Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2025 Peter Hinch
# Link GPIO16-GPIO17 to test
from machine import Pin, PWM
import rp2
import time
@rp2.asm_pio(set_init=rp2.PIO.IN_LOW, autopush=True, push_thresh=32)
def period():
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")[1] # unconditional
label("next")
jmp(pin, "low_high") # while pin is high
label("low") # pin is low
jmp(x_dec, "nxt")
label("nxt")
jmp(pin, "done") # pin has gone high: all done
jmp("low")
label("done")
in_(x, 32) # Auto push: SM stalls if FIFO full
wrap()
@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")[1] # unconditional
label("next")
jmp(pin, "low_high") # while pin is high
in_(x, 32) # Auto push: SM stalls if FIFO full
wrap()
ck = 100_000_000 # Clock rate in Hz.
pin16 = Pin(16, Pin.IN, Pin.PULL_UP)
sm0 = rp2.StateMachine(0, period, in_base=pin16, jmp_pin=pin16, freq=ck)
sm0.active(1)
sm1 = rp2.StateMachine(1, mark, in_base=pin16, jmp_pin=pin16, freq=ck)
sm1.active(1)
# Clock is 100MHz. 3 cycles per iteration, so unit is 30.0ns
def scale(v):
return (1 + (v ^ 0xFFFFFFFF)) * 3000 / ck # Scale to ms
# ***** TEST WITH PWM *****
pwm = PWM(Pin(17))
pwm.freq(1000)
pwm.duty_u16(0xFFFF // 3)
while True:
period = scale(sm0.get())
mark = scale(sm1.get())
print(f"Period {period}ms Mark {mark}ms m/s {100*mark / (period - mark):5.2f}%")
time.sleep(0.2)