guild icon
Toit
#Measure time
Thread channel in help
Macca
Macca 04/06/2023 01:33 AM
I am looking to measure the time that a pin is high with a pulse. I am unable to find any reference to time now in milliseconds.
bitphlipphar
bitphlipphar 04/06/2023 04:59 AM
You can use Duration.of: or the lower level Time.monotonic_us to get a microsecond count.
floitsch
floitsch 04/06/2023 10:10 AM
Depending on your requirements there are multiple different ways. (All examples are untested. If something looks off, please let me know and I fix the post).

The easiest is to just measure with Duration.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
floitsch 04/06/2023 10:11 AM
If you need higher precision, you can start a busy look and use Time.monotonic_us:
import 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").
Get Started with Toit This document provides simple instructions on how to get started with Toit. It is loosely inspired by Makerfab's MicroPython course and uses the same hardware. In Europe the kits are available here: https://hitechchain.se/en/makerfabs/29-iot/makepython-esp32-dev-kit If you ...
floitsch
floitsch 04/06/2023 10:11 AM
If you are dealing with repeated pulses (like from a flow-meter), then another approach is to count the amount of pulses (but not their length) over time and divide the measured duration by the pulse-count.
import 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
floitsch 04/06/2023 10:11 AM
Finally, if you have a single pulse and need high precision, then the RMT library does what you want.
The ultrasound package doesn't use the busy loop from above, but uses the RMT library instead: https://github.com/lask/toit-hc-sr04/blob/c740e8341179fe45b377db826222c23d223629b9/src/driver.toit#L57

import 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
Contribute to lask/toit-hc-sr04 development by creating an account on GitHub.
6 messages in total