Non-blocking, With Interval Measurement Too
While imp GPIO pins can be set to count pulses for a specified period, this process blocks Squirrel while the count is taken. To count pulses asynchronously, you can employ one of the imp’s UARTs instead. This approach uses the UART’s ‘a byte received’ callback to count pulses manually. The callback is triggered on the falling edge of the pulse read on the UART’s RX pin.
The example code below shows this technique in action on the imp006, though it’s readily convertible to other imps by referencing different UART and PWM pins. The PWM pin is used as the pulse signal source.
A special feature of imp UARTs that you can enable when you configure the bus is interval timing: the microsecond period between each received byte, up to a maximum of just over eight seconds. This mode is enabled with the TIMING_ENABLED UART configuration flag; each interval is placed in bits 31 through 8 of the integer passed into the UART byte-received callback; bits t through 0 are the received byte itself. Because we’re timing pulses not valid UART signals, we can ignore the data and simply make use of the interval.
You will need to configure the UART’s speed so that the minimum temporal resolution is more than one bit. For example, a 3kHz signal requires a sample rate of 3000bps or more. The code specifies 115,200bps, which is more than sufficient.
The following device code counts pulses issued by the imp’s own pulse width modulation (PWM) output (pin J) to simulate pulses received by a real-world application. The pulses are counted on the UART (pin B). The UART is configured with the TIMING_ENABLED flag so that the integer byte value passed into the callback, counter(), is stamped with the interval in microseconds since the last byte was received.
The counter() function extracts the interval and adds it to a total of all the intervals measured. When the count period is complete, the code calculates an average interval when it reports the number of pulses it counted over the specified duration (set as the COUNT_DURATION constant).
The code runs on the imp006, but can be readily ported to other imps: just change the UART and pin references in lines 25 and 26. You will need to connect the PWM output pin to the UART RX pin.