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:- Something to think about
Start driving with
drive_base.drive(200, 0). - Which command helps?
Check
distance_sensor.distance()>100 in awhileloop and calldrive_base.stop()afterwards. - Gap code – fill in the ___
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(___) while ___: wait(___) drive_base.stop() print(___)
Solve it without hints to earn a ⭐ on your progress page.
Show solution🔒 Unlocks after all hints or 2 checks
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.")