Can't get input capture to work.

I’m trying to measure the pulses coming from an LV-MaxSonar-EZ1 ultrasound rangefinder. The pulse width is proportional to the distance. Scoping the signal from the rangefinder verifies its presence and that it changes appropriately with distance. I’ve put comments in my code to indicate what is and isn’t happening. Here is my code:

#   Use input capture to measure pulse width from LV-MaxSonar-EZ1.

from pyb import Pin, Timer

startTime = 0
pulseWidth = 0
ic_pin = Pin("P3", Pin.IN, Pin.PULL_NONE)

def sonarHandler(timer):
#   Never gets called!
    global startTime, pulseWidth, ic_pin

    print("*")  # debug
    if ic_pin.value():  # Caught rising edge
        print("R")  # debug
        startTime = ic.capture()
    else:               # Caught falling edge
        print("F")  # debug
        pulseWidth = ic.capture() - startTime & 0x0FFFFFFF

timer1 = Timer(1, freq=10000)   # 100 us period
ic =, Timer.IC, pin=ic_pin, polarity=Timer.BOTH)

while (True):
    # P3 changes between 0 and 1 as expected. startTime and pulseWidth atre always zero.
    print("P3: %d, Start: %d, Pulse Width: %d" % (ic_pin.value(), startTime, pulseWidth))
    # ic.capture() always reads a constant value like 7306 or 695.

TIA for any advice,

Ibrahim will have to look into this for you. Our PYB support isn’t the best. I’ve never tested the input capture modes.

Sorry about this.

Hi, please use any other timer, TIM1/CH1 is reserved for the sensor clock. You can use timer 2 or 4. Here’s a small script to test timer callbacks:

import pyb, time

tim = pyb.Timer(2)  # create a timer object using timer 2
tim.init(freq=1)    # trigger at 1Hz
tim.callback(lambda t:pyb.LED(2).toggle())

while (True):

Thanks for your quick reply.
I was hoping to use P3 (which requires timer1 for input capture functionality).
However, as per your suggestion, I’m using timer2 and connecting the LV-MaxSonar-EZ1 to P6.
It works beautifully.
Thanks again,