Skip to content
BetaDE
Lesson 3 of 8Robotics with LEGO SPIKE

Robotics with LEGO SPIKE · Lesson 3 · 30 minutes

Sensors – colour, distance, force

What you'll learn

  • Read the colour sensor, ultrasonic sensor and force sensor
  • Use the pattern “measure, check, react”
  • Combine driving and measuring

The code in this lesson comes from the book “Python for Robots”, chapter 2.6, and runs unchanged in the simulator. German edition on Amazon ↗

The robot gets senses

Motors alone don’t make a clever robot. Only with sensors can it react to its surroundings. The book introduces three – and all three follow the same pattern: measure, check, react.

The colour sensor

The colour sensor looks down at the floor. color() returns a colour, reflection() the brightness from 0 (black) to 100 (white). In the simulator the sensor is currently on a red square:

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import ColorSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait

hub = PrimeHub()
color_sensor = ColorSensor(Port.C)

for _ in range(10):
    detected_color = color_sensor.color()          # e.g. Color.RED, Color.BLUE ...
    brightness = color_sensor.reflection()         # 0 (dark) to 100 (bright)

    print(f"Color: {detected_color}, Reflection: {brightness}%")

    if detected_color == Color.RED:
        print("Red line detected - Stop!")

    wait(300)

The ultrasonic sensor

The ultrasonic sensor measures the distance ahead in millimetres. In the simulator you can see its beam as a turquoise line:

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import UltrasonicSensor
from pybricks.parameters import Port
from pybricks.tools import wait

hub = PrimeHub()
distance_sensor = UltrasonicSensor(Port.D)

while True:
    distance_mm = distance_sensor.distance()   # distance in millimeters
    print(f"Distance: {distance_mm} mm")

    if distance_mm < 100:
        print("Watch out, obstacle very close!")
        break   # exit the loop

    wait(200)

The robot is standing still, so it always measures the same distance. Press Stop to end the program – or read on to find out how to combine driving and measuring.

The force sensor

The force sensor is a button with feeling: force() measures the force in newtons, pressed() simply says yes or no. In the simulator you press it with the Press force sensor button next to the hub – or the robot drives into an obstacle with its bumper.

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import ForceSensor
from pybricks.parameters import Port
from pybricks.tools import wait

hub = PrimeHub()
force_sensor = ForceSensor(Port.E)

while True:
    force_newton = force_sensor.force()     # force in Newtons
    pressed = force_sensor.pressed()      # True/False - over threshold?

    print(f"Force: {force_newton} N, pressed: {pressed}")

    if pressed:
        print("Contact! Reacting now.")
        break

    wait(100)

Remember: Create the sensor object on the right port, then read it regularly in a loop and react with if. This pattern is in almost every robot program.

Your task

Your turn

Make the robot drive off with drive_base.drive(200, 0). Measure the distance again and again in a loop and stop with drive_base.stop() as soon as the obstacle is closer than 100 mm. Then print Obstacle! Stopped. The robot must not touch the obstacle.

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor, UltrasonicSensor
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase
from pybricks.tools import wait

hub = PrimeHub()
left_motor = Motor(Port.A, positive_direction=Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B, positive_direction=Direction.CLOCKWISE)
drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=114)
distance_sensor = UltrasonicSensor(Port.C)

# Drive off, measure, stop in time:

Solve it without hints to earn a ⭐ on your progress page.

Show solution

Try it yourself first – mistakes teach you the most. Here is one possible solution:

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor, UltrasonicSensor
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase
from pybricks.tools import wait

hub = PrimeHub()
left_motor = Motor(Port.A, positive_direction=Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B, positive_direction=Direction.CLOCKWISE)
drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=114)
distance_sensor = UltrasonicSensor(Port.C)

drive_base.drive(200, 0)
while distance_sensor.distance() > 100:
    wait(10)
drive_base.stop()
print("Obstacle! Stopped.")