I am trying to help some 8th graders build a robot. They learned about the Raspberry Pi and Python with GPIOZERO in an earlier class.

They have wheels spinning using the Motor class from GPIOZERO and now want to measure speed and distance. They have optical encoders on the inner shafts of the geared motors and infrared optical sensors for each motor. The sensor have Vcc, ground, and output. With Vcc connected to 3v3, the LED on the sensor lights when there is no interruption of the infrared beam and is out if the beam is interrupted. I conjecture that output is about 3.3 volts when the light is on and probably floating when it's off.

There ought to be a way to read this with GPIOZERO, but I've been unable to figure it out. Any help would be much appreciated.

Edit: Let me try to make this a little less vague. The kids have no-name (and no documentation) sensors that look like this:

picture of optical sensor

If I connect Vcc to 3v3, GND to GND and OUT to GPIO 27, the following code works, i.e. tells whether the gap in the sensor is open or occluded.

import RPi.GPIO as GPIO
from time import sleep

pin = 27
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
while True:
    if GPIO.input(pin) == GPIO.HIGH:

My goal is to get the same result using the GPIOZERO library.

(I should probably put a current-limiting resistor between "OUT" and the GPIO pin, and I'll get the kids to do that.)

  • How about gpiozero.readthedocs.io/en/v1.6.2/… This question is too vague and lacking any meaningful data. I doubt if a rotary encoder is the appropriate device.
    – Milliways
    Sep 27, 2023 at 3:39
  • The problem is to count pulses from the optical encoders attached to the wheels by reading the output of the optical encoder using GPIOZERO. It is the latter part that has me stumped. There are many examples using pigpio. And you're right, the rotary encoder isn't the appropriate device.
    – Bob Brown
    Sep 27, 2023 at 11:20
  • Not the answer to the question, but the students are using the Explorer HAT Pro, and can accomplish distance measurement by connecting the sensor's Vcc to 3V3, GND to GND, and OUT to a digital input on the Explorer HAT, then using the on_changed() event to count 'ticks' of the encoder wheel. They are happily computing ticks per centimeter and driving their robots known distances.
    – Bob Brown
    Oct 4, 2023 at 14:52

1 Answer 1


The normal solution to measuring "speed" (at least for relatively slow signals) is to time the period and invert. There are plenty of examples to measure elapsed time on a Pi.

Distance is then calculated by integrating :- S = v * t although you could count pulses and differentiate to get speed.

The appropriate method depends on expected speed.

It is simple to store the time when there is an input and calculate the pulse duration e.g.

Run a function every time the button is pressed:

from gpiozero import Button
from signal import pause

def say_hello():

button = Button(2)

button.when_pressed = say_hello


Again measuring distance is simple - just multiply the number of rotations by the circumference of the wheel.

No one is going to write your code (although if you provide the hardware to test I would). You have to try and see what works.

  • You are correct; measuring time is easy. But one also needs to measure the distance, and that's what the little optical encoder gives us.
    – Bob Brown
    Sep 27, 2023 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.