Advanced I/O

Lesson 99: Using pulseInLong()

Learn how pulseInLong() measures longer pulse widths with timeout control and when to choose it over pulseIn().

Progress indicator

Lesson 99 of 99

Learning Objectives

  • Understand what pulseInLong() measures and how it differs from pulseIn().
  • Learn pulseInLong() syntax with pin, state, and timeout parameters.
  • Measure longer pulse widths safely using timeout-based logic.
  • Interpret pulseInLong() return values and handle timeout cases correctly.
  • Apply best practices for stable long-pulse timing workflows.
  • Tune timeout and unit conversion logic for accurate real-world measurements.

Concept Explanation

What is pulseInLong()

pulseInLong() measures how long a digital signal stays in a target state (HIGH or LOW) and returns the duration in microseconds.

It is designed for cases where pulse durations may be long and you want more reliable long timing behavior.

pulseInLong() Syntax

  • pulseInLong(pin, value);
  • pulseInLong(pin, value, timeout);

pin is the input pin, value is HIGH or LOW, and timeout is the maximum wait time in microseconds.

Example: pulseInLong(18, HIGH, 2000000) waits for a HIGH pulse on pin 18 and allows up to 2 seconds total wait.

How pulseInLong() Works

  1. Waits until the signal enters the target state.
  2. Starts timing while the signal remains in that state.
  3. Stops timing when the signal changes state.
  4. Returns measured pulse width in microseconds.
  5. Returns 0 if timeout occurs before a complete pulse is captured.

Beginner view: it works like a stopwatch for a digital level, with a built-in maximum waiting limit.

pulseInLong() vs pulseIn() (Comparison)

  • pulseIn(): good for short-to-medium pulse timing in many beginner scenarios.
  • pulseInLong(): preferred when pulses may be long or you need stronger long duration handling.

Practical rule: if your signal can stay HIGH/LOW for a long time, use pulseInLong().

If your signal is always short and fast, pulseIn() may still be enough. For mixed or uncertain timing windows, pulseInLong() gives safer margin.

Measuring Long Pulses

Long pulses can happen in slow sensors, custom protocols, or event-based timing signals.

Using pulseInLong() with a suitable timeout helps avoid lockups and keeps loop behavior predictable.

  • Remote control or low-frequency pulse protocols.
  • Event duration signals from external modules.
  • Timing windows that can extend into hundreds of milliseconds or seconds.

Timeout Parameter Explained

Timeout sets the maximum wait window. Example: pulseInLong(SIGNAL_PIN, HIGH, 2000000) means wait up to 2,000,000 us (2 seconds).

If no valid pulse is completed inside the timeout, return value becomes 0.

Timeout tuning strategy: start with a safe larger value while testing, then reduce gradually until system remains responsive and still captures valid pulses.

pulseInLong() Return Value

  • > 0: measured pulse width (microseconds).
  • 0: timeout/no full pulse measured.

Store result in unsigned long and check zero before converting or printing final derived values.

For human-readable display, convert microseconds to milliseconds using value / 1000.0.

When to Use pulseInLong()

  • Long pulse measurement signals.
  • Slow event timing with large microsecond windows.
  • Situations where pulseIn() may be less suitable for long durations.
  • Projects that must avoid false readings from missing/late pulses.

Example Code

This example measures a long HIGH pulse and prints both microseconds and milliseconds.

const int SIGNAL_PIN = 18;

void setup() {
  pinMode(SIGNAL_PIN, INPUT);
  Serial.begin(115200);
}

void loop() {
  unsigned long highPulse = pulseInLong(SIGNAL_PIN, HIGH, 2000000);

  if (highPulse == 0) {
    Serial.println("Timeout: no pulse detected");
  } else {
    Serial.print("Pulse width (us): ");
    Serial.println(highPulse);
    float pulseMs = highPulse / 1000.0;
    Serial.print("Pulse width (ms): ");
    Serial.println(pulseMs);
  }

  delay(300);
}

Example Code Explanation

  1. SIGNAL_PIN defines the input pin for pulse timing.
  2. pinMode(SIGNAL_PIN, INPUT) prepares the pin for digital signal reading.
  3. pulseInLong(SIGNAL_PIN, HIGH, 2000000) measures HIGH pulse with 2-second timeout.
  4. If return value is 0, code reports timeout clearly in Serial Monitor and avoids invalid calculations.
  5. If pulse is valid, code prints raw pulse width in microseconds.
  6. Code converts microseconds to milliseconds for easier human reading.
  7. This conversion helps beginners compare pulse duration visually with delay() or time-based logic.
  8. Final delay keeps logs readable and prevents too-fast console flooding.

What Happens Inside

  1. Loop starts and calls pulseInLong() on target signal pin.
  2. Runtime waits for signal transition into target state.
  3. Microsecond timer runs while state remains active.
  4. Timer stops on state change or timeout expiration.
  5. Measured value is returned to user code.
  6. Code branches: timeout path (0) or valid pulse path (>0).
  7. Valid pulse path prints raw and converted values for interpretation.
  8. Loop delay creates stable sampling cadence for repeated measurements.
Internal flow: wait for edge -> track pulse duration -> return microseconds -> branch on timeout vs valid measurement.

Common Mistakes with pulseInLong()

  • Forgetting timeout and causing long blocking behavior.
  • Using wrong pin mode or wrong target state (HIGH vs LOW).
  • Ignoring 0 return value and treating timeout as valid data.
  • Confusing units (us vs ms) in conversion and calculations.
  • Setting timeout too short, causing frequent false timeout results.
  • Setting timeout too long, making the loop feel stuck when signal is missing.

Best Practices for pulseInLong()

  • Always set explicit timeout based on expected pulse range.
  • Use unsigned long for pulse storage and keep conversions clear.
  • Branch on timeout (0) before any derived math.
  • Use Serial logs during calibration to verify pulse stability.
  • Calibrate timeout against real sensor behavior, not only theoretical values.
  • Keep signal wiring clean and stable to reduce random timing noise.

Try it now

Open the simulator workspace and test long pulse width values with timeout-safe behavior.

Run in Simulator