# pupdevices – Powered Up Devices¶

LEGO® Powered Up motor, sensors, and lights.

## Motors without Rotation Sensors¶

Figure 18 Powered Up motors without rotation sensors. The arrows indicate the default positive direction.

class DCMotor(port, positive_direction=Direction.CLOCKWISE)

Generic class to control simple motors without rotation sensors, such as train motors.

Parameters: port (Port) – Port to which the motor is connected. positive_direction (Direction) – Which direction the motor should turn when you give a positive duty cycle value.
dc(duty)

Rotates the motor at a given duty cycle (also known as “power”).

Parameters: duty (percentage: %) – The duty cycle (-100.0 to 100).
stop()

Stops the motor and lets it spin freely.

The motor gradually stops due to friction.

brake()

Passively brakes the motor.

The motor stops due to friction, plus the voltage that is generated while the motor is still moving.

## Motors with Rotation Sensors¶

Figure 19 Powered Up motors with rotation sensors. The arrows indicate the default positive direction. See the hubs module for default directions of built-in motors.

class Motor(port, positive_direction=Direction.CLOCKWISE, gears=None)

Generic class to control motors with built-in rotation sensors.

Parameters: port (Port) – Port to which the motor is connected. positive_direction (Direction) – Which direction the motor should turn when you give a positive speed value or angle. gears (list) – List of gears linked to the motor. For example: [12, 36] represents a gear train with a 12-tooth and a 36-tooth gear. Use a list of lists for multiple gear trains, such as [[12, 36], [20, 16, 40]]. When you specify a gear train, all motor commands and settings are automatically adjusted to account for the resulting gear ratio. The motor direction remains unchanged by this.

Measuring

speed()

Gets the speed of the motor.

Returns: Motor speed. rotational speed: deg/s
angle()

Gets the rotation angle of the motor.

Returns: Motor angle. angle: deg
reset_angle(angle=None)

Sets the accumulated rotation angle of the motor to a desired value.

If you don’t specify an angle, the absolute angle will be used if your motor supports it.

Parameters: angle (angle: deg) – Value to which the angle should be reset.

Stopping

stop()

Stops the motor and lets it spin freely.

The motor gradually stops due to friction.

brake()

Passively brakes the motor.

The motor stops due to friction, plus the voltage that is generated while the motor is still moving.

hold()

Stops the motor and actively holds it at its current angle.

Action

run(speed)

Runs the motor at a constant speed.

The motor accelerates to the given speed and keeps running at this speed until you give a new command.

Parameters: speed (rotational speed: deg/s) – Speed of the motor.
run_time(speed, time, then=Stop.HOLD, wait=True)

Runs the motor at a constant speed for a given amount of time.

The motor accelerates to the given speed, keeps running at this speed, and then decelerates. The total maneuver lasts for exactly the given amount of time.

Parameters: speed (rotational speed: deg/s) – Speed of the motor. time (time: ms) – Duration of the maneuver. then (Stop) – What to do after coming to a standstill. wait (bool) – Wait for the maneuver to complete before continuing with the rest of the program.
run_angle(speed, rotation_angle, then=Stop.HOLD, wait=True)

Runs the motor at a constant speed by a given angle.

Parameters: speed (rotational speed: deg/s) – Speed of the motor. rotation_angle (angle: deg) – Angle by which the motor should rotate. then (Stop) – What to do after coming to a standstill. wait (bool) – Wait for the maneuver to complete before continuing with the rest of the program.
run_target(speed, target_angle, then=Stop.HOLD, wait=True)

Runs the motor at a constant speed towards a given target angle.

The direction of rotation is automatically selected based on the target angle. It does matter if speed is positive or negative.

Parameters: speed (rotational speed: deg/s) – Speed of the motor. target_angle (angle: deg) – Angle that the motor should rotate to. then (Stop) – What to do after coming to a standstill. wait (bool) – Wait for the motor to reach the target before continuing with the rest of the program.
run_until_stalled(speed, then=Stop.COAST, duty_limit=None)

Runs the motor at a constant speed until it stalls.

Parameters: speed (rotational speed: deg/s) – Speed of the motor. then (Stop) – What to do after coming to a standstill. duty_limit (percentage: %) – Torque limit during this command. This is useful to avoid applying the full motor torque to a geared or lever mechanism. Angle at which the motor becomes stalled. angle: deg
dc(duty)

Rotates the motor at a given duty cycle (also known as “power”).

This method lets you use a motor just like a simple DC motor.

Parameters: duty (percentage: %) – The duty cycle (-100.0 to 100).

track_target(target_angle)

Tracks a target angle. This is similar to run_target(), but the usual smooth acceleration is skipped: it will move to the target angle as fast as possible. This method is useful if you want to continuously change the target angle.

Parameters: target_angle (angle: deg) – Target angle that the motor should rotate to.
control

The motors use PID control to accurately track the speed and angle targets that you specify. You can change its behavior through the control attribute of the motor. See The Control Class for an overview of available methods.

## Color and Distance Sensor¶

Show/hide examples

Example 1: Measuring color

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

while True:
color = sensor.color()

# Print the measured color.
print(color)

# Move the sensor around and see how
# well you can detect colors.

# Wait so we can read the value.
wait(100)


Example 2: Waiting for a color

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

# This is a function that waits for a desired color.
def wait_for_color(desired_color):
# While the color is not the desired color, we keep waiting.
while sensor.color() != desired_color:
wait(20)

# Now we use the function we just created above.
while True:

# Here you can make your train/vehicle go forward.

print("Waiting for red ...")
wait_for_color(Color.RED)

# Here you can make your train/vehicle go backward.

print("Waiting for blue ...")
wait_for_color(Color.BLUE)


Example 3: Measuring distance

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

# Repeat forever.
while True:

# If the sensor sees an object nearby.
if sensor.distance() <= 40:

# Then blink the light red/blue 5 times.
for i in range(5):
sensor.light.on(Color.RED)
wait(30)
sensor.light.on(Color.BLUE)
wait(30)
else:
# If the sensor sees nothing
# nearby, just wait briefly.
wait(10)

class ColorDistanceSensor(port)

LEGO® Powered Up Color and Distance Sensor.

Parameters: port (Port) – Port to which the sensor is connected.
color()

Scans the color of a surface.

Returns: Detected color. Color, or None if no color is detected.
reflection()

Measures the reflection of a surface.

Returns: Reflection, ranging from 0.0 (no reflection) to 100.0 (high reflection). percentage: %
ambient()

Measures the ambient light intensity.

Returns: Ambient light intensity, ranging from 0 (dark) to 100 (bright). percentage: %
distance()

Measures the relative distance between the sensor and an object using infrared light.

Returns: Relative distance ranging from 0 (closest) to 100 (farthest). relative distance: %

Show/hide examples

Example 1: Reading hue, saturation, and value

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

# Show the default color map.
print(sensor.color_map())

while True:
h, s, v = sensor.hsv()

# Read the corresponding color based on the existing settings.
color = sensor.color()

# Print the measured values.
print("Hue:", h, "Sat:", s, "Val:", v, "Col:", color)

# Wait so we can read the value.
wait(100)


Example 2: Modifying the default color map

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

# Get the current color settings.
hues, saturation, values = sensor.color_map()

# Let's say we have used the hsv() method to determine
# that the orange hue is 10. We can add it like this.
hues[Color.ORANGE] = 10

# Also, let's say that we are not interested in blue.
# So, we remove it from the hues dictionary.
hues.pop(Color.BLUE)

# Now save the new settings
sensor.color_map(hues, saturation, values)

# Now use the color() method as usual. Now it can also detect ORANGE
# and it will not report BLUE, because we removed it from the hues.
while True:
print(sensor.color())
wait(100)


Example 3: Providing a whole new color map

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

# Here we choose only red, yellow, green, and blue, and provide the hues.
hues = {
Color.RED: 350,
Color.YELLOW: 30,
Color.GREEN: 110,
Color.BLUE: 210
}

# Save the updated settings. The values dictionary is empty because we don't
# need to detect black/white in this demo application.
sensor.color_map(hues, 50, {})

# color() works as usual, but it only returns red/yellow/green/blue, or None.
# This avoids accidentally detecting black on the dark gray train tracks.
while True:
print(sensor.color())
wait(100)

hsv()

Scans the hue, saturation and brightness value of a surface.

Returns: Tuple with the hue, saturation, and value (brightness) of the color. (hue: deg, percentage: %, percentage: %)
color_map(hues, saturation, values)

Configures how color() selects a Color based on a hsv() measurement.

Specify only colors that you wish to detect in your application. This way, measurements are rounded to the nearest expected color, and other colors are ignored.

If you give no arguments, the current settings will be returned as a tuple.

Parameters: hues (dict) – A dictionary that maps Color to hues. When the saturation is high, color() will return one of these colors, whichever has the nearest hue. saturation (percentage: %) – Minimum saturation of a proper color. values (percentage: %) – A dictionary that maps Color.WHITE, Color.GRAY, Color.BLACK and None to brightness values. When the saturation is low, color() will return one of these colors, whichever has the nearest value.

Built-in light

This sensor has a built-in light. You can make it red, green, blue, or turn it off. If you use the sensor to measure something afterwards, the light automatically turns back on at the default color for that sensing method.

Show/hide examples

from pybricks.pupdevices import ColorDistanceSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait

# Initialize the sensor.
sensor = ColorDistanceSensor(Port.A)

# Repeat forever.
while True:

# If the sensor sees an object nearby.
if sensor.distance() <= 40:

# Then blink the light red/blue 5 times.
for i in range(5):
sensor.light.on(Color.RED)
wait(30)
sensor.light.on(Color.BLUE)
wait(30)
else:
# If the sensor sees nothing
# nearby, just wait briefly.
wait(10)

light.on(color)

Turns on the light at the specified color.

Parameters: color (Color) – Color of the light. The light turns off if you choose None or a color that is not available.
light.off()

Turns off the light.

Power Functions 1.0 Control

remote(channel, button_1=None, button_2=None)

Makes the sensor act like a Power Functions 1.0 IR remote.

Choose a channel and up to two buttons to “press”. The infrared receiver behaves just as if responding to the real remote.

The sensor keeps sending the signal (as if you keep pressing the buttons). It keeps going until you call this method again with different buttons or no buttons at all.

Parameters: channel (int) – Channel number of the remote. button_1 (Button) – Button of the Power Functions 1.0 IR remote. Choose None if you don’t want to press any button. button_2 (Button) – Button of the Power Functions 1.0 IR remote. Choose None if you don’t want to press any button.

## Color Sensor¶

class ColorSensor(port)

LEGO® SPIKE Color Sensor.

Parameters: port (Port) – Port to which the sensor is connected.
color(surface=True)

Scans the color of a surface or an external light source.

Parameters: surface (bool) – Choose true to scan the color of objects and surfaces. Choose false to scan the color of screens and other external light sources. Detected color. Color, or None if no color is detected.
hsv(surface=True)

Scans the hue, saturation and brightness value of a surface or an external light source.

Parameters: surface (bool) – Choose true to scan the color of objects and surfaces. Choose false to scan the color of screens and other external light sources. Tuple with the hue, saturation, and value (brightness) of the color. (hue: deg, percentage: %, percentage: %)
color_map(hues, saturation, values)

Configures how color() selects a Color based on a hsv() measurement.

Specify only colors that you wish to detect in your application. This way, measurements are rounded to the nearest expected color, and other colors are ignored.

If you give no arguments, the current settings will be returned as a tuple.

Parameters: hues (dict) – A dictionary that maps Color to hues. When the saturation is high, color() will return one of these colors, whichever has the nearest hue. saturation (percentage: %) – Minimum saturation of a proper color. values (percentage: %) – A dictionary that maps Color.WHITE, Color.GRAY, Color.BLACK and None to brightness values. When the saturation is low, color() will return one of these colors, whichever has the nearest value.
ambient()

Measures the ambient light intensity.

Returns: Ambient light intensity, ranging from 0 (dark) to 100 (bright). percentage: %
reflection()

Measures the reflection of a surface.

Returns: Reflection, ranging from 0.0 (no reflection) to 100.0 (high reflection). percentage: %

Built-in lights

This sensor has 3 built-in lights. You can adjust the brightness of each light. If you use the sensor to measure something, the lights will be turned on or off as needed for the measurement.

lights.on(*brightness)

Turns on the lights at the specified brightness.

Parameters: *brightness (brightness: %, …) – Brightness of each light, in the order shown above. If you give only one value, all lights will get that same brightness.
lights.off()

Turns off all the lights.

## Ultrasonic Sensor¶

Show/hide examples

Example 1: Measuring distance and switching on the lights

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

# Initialize the sensor.
eyes = UltrasonicSensor(Port.A)

while True:
# Print the measured distance.
print(eyes.distance())

# If an object is detected closer than 500mm:
if eyes.distance() < 500:
# Turn the lights on.
eyes.lights.on(100)
else:
# Turn the lights off.
eyes.lights.off()

# Wait some time so we can read what is printed.
wait(100)


Example 2: Using math to gradually change the brightness of the lights

from pybricks.pupdevices import UltrasonicSensor
from pybricks.parameters import Port
from pybricks.tools import wait, StopWatch

# The math module is part of standard MicroPython:
# https://docs.micropython.org/en/latest/library/math.html
from math import pi, sin

# Initialize the sensor.
eyes = UltrasonicSensor(Port.A)

# Initialize a timer.
watch = StopWatch()

# We want one full light cycle to last three seconds.
PERIOD = 3000

while True:
# The phase is where we are in the unit circle now.
phase = watch.time()/PERIOD*2*pi

# Each light follows a sine wave with a mean of 50, with an amplitude of 50.
# We offset this sine wave by 90 degrees for each light, so that all the
# lights do something different.
brightness = [sin(phase + offset*pi/2) * 50 + 50 for offset in range(4)]

# Set the brightness values for all lights. The * symbol unpacks the list
# of brightness values into separate arguments.
eyes.lights.on(*brightness)

# Wait some time.
wait(50)

class UltrasonicSensor(port)

LEGO® SPIKE Color Sensor.

Parameters: port (Port) – Port to which the sensor is connected.
distance()

Measures the distance between the sensor and an object using ultrasonic sound waves.

Returns: Measured distance. If no valid distance was measured, it returns 2000 mm. distance: mm
presence()

Checks for the presence of other ultrasonic sensors by detecting ultrasonic sounds.

Returns: True if ultrasonic sounds are detected, False if not. bool

Built-in lights

This sensor has 4 built-in lights. You can adjust the brightness of each light.

lights.on(*brightness)

Turns on the lights at the specified brightness.

Parameters: *brightness (brightness: %, …) – Brightness of each light, in the order shown above. If you give only one value, all lights will get that same brightness.
lights.off()

Turns off all the lights.

## Force Sensor¶

class ForceSensor(port)

LEGO® SPIKE Force Sensor.

Parameters: port (Port) – Port to which the sensor is connected.
force()

Measures the force exerted on the sensor.

Returns: Measured force (up to approximately 10.00 N). force: N
distance()

Measures by how much the sensor button has moved.

Returns: How much the sensor button has moved (up to approximately 8.00 mm). distance: mm
pressed(force=3)

Checks if the sensor button is pressed.

Parameters: force (force: N) – Minimum force to be considered pressed. True if the sensor is pressed, False if it is not. bool
touched()

Checks if the sensor is touched.

This is similar to pressed(), but it detects slight movements of the button even when the measured force is still considered zero.

Returns: True if the sensor is touched or pressed, False if it is not. bool

## Infrared Sensor¶

Show/hide example

Example: Measuring distance, object count, and reflection

from pybricks.pupdevices import InfraredSensor
from pybricks.parameters import Port
from pybricks.tools import wait

# Initialize the sensor.
ir = InfraredSensor(Port.A)

while True:
# Read all the information we can get from this sensor.
dist = ir.distance()
count = ir.count()
ref = ir.reflection()

# Print the values
print("Distance:", dist, "Count:", count, "Reflection:", ref)

# Move the sensor around and move your hands in front
# of it to see what happens to the values.

# Wait some time so we can read what is printed.
wait(200)

class InfraredSensor(port)

LEGO® Powered Up Infrared Sensor.

Parameters: port (Port) – Port to which the sensor is connected.
distance()

Measures the relative distance between the sensor and an object using infrared light.

Returns: Relative distance ranging from 0 (closest) to 100 (farthest). relative distance: %
reflection()

Measures the reflection of a surface using an infrared light.

Returns: Reflection, ranging from 0.0 (no reflection) to 100.0 (high reflection). percentage: %
count()

Counts the number of objects that have passed by the sensor.

Returns: Number of objects counted. int

## Tilt Sensor¶

Show/hide example

Example: Measuring pitch and roll

from pybricks.pupdevices import TiltSensor
from pybricks.parameters import Port
from pybricks.tools import wait

# Initialize the sensor.
accel = TiltSensor(Port.A)

while True:
# Read the tilt angles relative to the horizontal plane.
pitch, roll = accel.tilt()

# Print the values
print("Pitch:", pitch, "Roll:", roll)

# Wait some time so we can read what is printed.
wait(100)

class TiltSensor(port)

LEGO® Powered Up Tilt Sensor.

Parameters: port (Port) – Port to which the sensor is connected.
tilt()

Measures the tilt relative to the horizontal plane.

Returns: Tuple of pitch and roll angles. (angle: deg, angle: deg)

## Light¶

Show/hide examples

Example 1: Making the light blink

from pybricks.pupdevices import Light
from pybricks.parameters import Port
from pybricks.tools import wait

# Initialize the light.
light = Light(Port.A)

while True:
# Turn the light on at 100% brightness.
light.on(100)
wait(500)

# Turn the light off.
light.off()
wait(500)


Example 2: Using math to gradually change the brightness of the light

from pybricks.pupdevices import Light
from pybricks.parameters import Port
from pybricks.tools import wait, StopWatch

# The math module is part of standard MicroPython:
# https://docs.micropython.org/en/latest/library/math.html
from math import pi, cos

# Initialize the light and a StopWatch.
light = Light(Port.A)
watch = StopWatch()

# Cosine pattern properties.
PERIOD = 2000
MAX = 100

# Make the brightness fade in and out.
while True:
# Get phase of the cosine.
phase = watch.time()/PERIOD*2*pi

# Evaluate the brightness.
brightness = (0.5 - 0.5*cos(phase))*MAX

# Set light brightness and wait a bit.
light.on(brightness)
wait(10)

class Light(port)

LEGO® Powered Up Light.

Parameters: port (Port) – Port to which the device is connected.
on(brightness=100)

Turns on the light at the specified brightness.

Parameters: brightness (brightness: %) – Brightness of the light.
off()

Turns off the light.