Macca
04/06/2023, 1:33 AMkasperl
04/06/2023, 4:59 AMDuration.of:
or the lower level Time.monotonic_us
to get a microsecond count.floitsch
04/06/2023, 10:10 AMDuration.of
and pin.wait_for
import gpio
main:
pin := gpio.Pin 32 --input
// Wait for the pulse to start:
pin.wait_for 1
pulse_duration := Duration.of: pin.wait_for 0
print "It took $pulse_duration.in_ms milliseconds"
pin.close
pin.wait_for
has a bit of overhead (because it uses the event-queue, ...), but if you are only interested in milliseconds, you probably won't notice. It's the simplest and will allow other tasks and programs to run.floitsch
04/06/2023, 10:11 AMimport gpio
main:
pin := gpio.Pin 32 --input
while pin.get != 1: null // Wait for the pin to trigger.
start := Time.monotonic_us
while pin.get != 0: null // Wait for the pin to pulse to stop.
end := Time.monotonic_us
diff_us = end - start
print "It took $diff_us us"
pin.close
This program is more precise, but will busy loop. It will put one of your cores to 100%. You should generally only do this, if you know that the pulse is coming soon, doesn't take a long time, and you need a relatively precise measurement. A good example is an ultrasound sensor that puts a pulse onto the 'echo' pin after it was triggered. See https://docs.google.com/document/d/1K-TYea7jbYfj2ecMUmr0T0zd4JDpk5lo0mJNOLPUrhc/edit (search for "Ultrasound Distance").floitsch
04/06/2023, 10:11 AMimport pulse_counter
import gpio
main:
pin := gpio.Pin 32
unit := pulse_counter.Unit
channel := unit.add_channel pin
channel.clear // Reset the pulse count.
sleep --ms=1_000 // Measure for one second.
count := channel.value
frequency := 1_000 / count
print "Frequency is $frequency Hz"
channel.close
unit.close
pin.close
floitsch
04/06/2023, 10:11 AMimport gpio
import rmt
main:
pin := gpio.Pin 32
// The line is considered idle, when the value doesn't change after
// idle_threshold ticks.
// By default a tick is 1us.
// This value must fit int 16bits.
idle_threshold := 30_000
// Pulses that are shorter than filter_ticks are ignored.
filter_ticks := 10
channel := rmt.Channel pin
--input
--idle_threshold=idle_threshold
--filter_ticks = filter_ticks
received_signals := channel.read // Waits for a pulse.
if received_signals.size == 0 or (received_signals.level 0) == 0:
print "Measurement didn't work".
pulse_width := received_signals.period 0
print "Received a pulse of $pulse_width"
channel.close
pin.close