MojoScale Studio Docs
API Reference

pulse

Hardware pulse counter module.

Studio Docs Sensors & I/O

import pulse

The pulse module creates ESP-IDF PCNT-backed counters for flow meters, tachometers, energy meter pulse outputs, rain gauges, production counters, and other GPIO pulse sources. Counting happens in hardware; Berry configures the counter and reads count, frequency, period, RPM, rate, and scaled totals.

Quick example

import pulse
import system

fan = pulse.counter(pin=4, pull="up", filter_us=50)
fan.start()

def report():
    print(fan.count())
    print(fan.frequency())

system.schedule("fan", 1000, 1000, -1, report)

water = pulse.counter(
    pin=5,
    pull="up",
    filter_us=100,
    pulses_per_unit=450,
    unit="liter",
)
water.start()
print(water.total())
print(water.rate())

importpulse

Hardware pulse counter module.

The pulse module creates ESP-IDF PCNT-backed counters for flow meters, tachometers, energy meter pulse outputs, rain gauges, production counters, and other GPIO pulse sources. Counting happens in hardware; Berry configures the counter and reads count, frequency, period, RPM, rate, and scaled totals.

API 17 available

pulse.counter(pin: int, edge: str = None, pull: str = None, filter_us: int = None, pulses_per_unit: float = None, unit: str = None, window_ms: int = None, control_pin: int = None, direction: str = None) -> pulse_counter

Create a hardware-backed pulse counter object.

Parameters
Name Type Pass as Required Description
pin int positional or keyword Yes GPIO receiving the pulse signal.
edge str positional or keyword No Optional edge to count. Use "rising", "falling", or "both". Defaults to "rising".
pull str positional or keyword No Optional input pull mode. Use "up", "down", or "none". Defaults to "none".
filter_us int positional or keyword No Optional glitch filter in microseconds. Pulses shorter than this are ignored by PCNT hardware. Defaults to 0.
pulses_per_unit float positional or keyword No Optional scaling factor for total(), rate(), and rpm(). For example, 450 pulses per liter. Defaults to no scaling.
unit str positional or keyword No Optional display unit name returned by read(), such as "liter".
window_ms int positional or keyword No Optional smoothing window reserved for firmware frequency measurement behavior. Defaults to 1000.
control_pin int positional or keyword No Optional GPIO used as a direction/control level.
direction str positional or keyword No Optional count direction. Use "up", "down", or "control". Defaults to "up".
Returns

pulse_counter pulse_counter object.

pulse.counter().start() -> bool

Enable the PCNT unit and begin counting pulses.

pulse.counter().stop() -> bool

Stop counting without clearing the accumulated count.

pulse.counter().pause() -> bool

Alias for stop().

pulse.counter().resume() -> bool

Alias for start().

pulse.counter().reset() -> bool

Clear the count and restart elapsed-time tracking.

pulse.counter().close() -> bool

Release the native PCNT unit.

pulse.counter().count() -> int

Return the current signed pulse count.

pulse.counter().frequency() -> float

Return the measured pulse frequency in Hz.

pulse.counter().period_us() -> int

Return the estimated period between pulses in microseconds.

pulse.counter().elapsed_ms() -> int

Return elapsed milliseconds since the counter started or reset.

pulse.counter().running() -> bool

Return True when the counter is running.

pulse.counter().read() -> dict

Return count, frequency, period, elapsed time, total, rate, unit, and running state.

pulse.counter().total() -> number

Return count scaled by pulses_per_unit.

pulse.counter().rate() -> number

Return scaled units per second.

pulse.counter().rpm(pulses_per_revolution=1) -> float

Return revolutions per minute using the pulse scaling.

Parameters
Name Type Pass as Required Description
pulses_per_revolution float positional or keyword No Optional value. Defaults to 1.

pulse.counter().info() -> dict

Return pin, running state, unit name, and counter configuration.