Skip to content

Motors & Sensors

A practical reference for the SPIKE 3 Python API, organized by module. All examples assume this wiring: left wheel A, right wheel E, attachment motor C, color sensor F, distance sensor D, force sensor B.

motor: single motors

python
import motor
from hub import port

motor.run(port.C, 500)                          # spin at 500 deg/s (non-blocking)
motor.stop(port.C)                              # stop
await motor.run_for_degrees(port.C, 180, 400)   # turn 180° (await = finish first)
await motor.run_for_time(port.C, 1000, 400)     # run 1 second
await motor.run_to_absolute_position(port.C, 0, 300)   # go to the 0 mark
await motor.run_to_relative_position(port.C, 90, 300)  # go to relative position 90

motor.relative_position(port.C)                 # read accumulated degrees
motor.reset_relative_position(port.C, 0)        # zero the accumulated count
motor.absolute_position(port.C)                 # read the absolute mark (-180~179)
motor.velocity(port.C)                          # read current speed
  • Speed unit is degrees/second: large motor max ~1050, medium ~1110. Everyday range 300-800.
  • Negative speed or degrees = reverse.
  • Stop behavior: pass stop=motor.BRAKE / motor.HOLD / motor.COAST. Arms holding weight use HOLD.

Attachment example: raise arm 90°, lower it

python
await motor.run_for_degrees(port.C, 90, 300, stop=motor.HOLD)
await runloop.sleep_ms(500)
await motor.run_for_degrees(port.C, -90, 200)

motor_pair: the drive base

Pair once (top of the program), then move:

python
import motor_pair
from hub import port

motor_pair.pair(motor_pair.PAIR_1, port.A, port.E)   # left, right

# steering style: -100 (spin left) ~ 0 (straight) ~ 100 (spin right)
motor_pair.move(motor_pair.PAIR_1, 0, velocity=400)              # drive straight (non-blocking)
await motor_pair.move_for_degrees(motor_pair.PAIR_1, 720, 0, velocity=400)   # 720 wheel degrees
await motor_pair.move_for_time(motor_pair.PAIR_1, 2000, 0, velocity=400)     # 2 seconds

# tank style: set each wheel's velocity - for fine control / custom line following
motor_pair.move_tank(motor_pair.PAIR_1, 400, 300)                # left faster = right arc
await motor_pair.move_tank_for_degrees(motor_pair.PAIR_1, 360, 400, -400)    # spin right

motor_pair.stop(motor_pair.PAIR_1)

Centimeter conversion is on you (the API only speaks degrees):

python
WHEEL_CM = 17.5                       # wheel circumference, calibrated
def cm_to_deg(cm):
    return int(cm / WHEEL_CM * 360)

await motor_pair.move_for_degrees(motor_pair.PAIR_1, cm_to_deg(50), 0, velocity=400)

color_sensor

python
import color_sensor, color
from hub import port

color_sensor.reflection(port.F)      # reflected light 0-100, for line following
color_sensor.color(port.F)           # returns color.BLACK / color.RED / ...; -1 if none
color_sensor.rgbi(port.F)            # raw (R, G, B, intensity), advanced
python
if color_sensor.color(port.F) == color.RED:
    ...

distance_sensor

python
import distance_sensor
from hub import port

d = distance_sensor.distance(port.D)    # millimeters; -1 when no target
if d != -1 and d < 80:                  # within 8 cm
    ...

Always check for -1 first, or "no target" reads as "extremely close".

force_sensor

python
import force_sensor
from hub import port

force_sensor.pressed(port.B)     # True / False
force_sensor.force(port.B)       # 0-100, in decinewtons

hub built-ins

python
import color
from hub import motion_sensor, light_matrix, button, sound, light

motion_sensor.reset_yaw(0)
yaw = motion_sensor.tilt_angles()[0] / 10     # to degrees; right turn positive

await light_matrix.write("Go")                # scrolling text
light_matrix.show_image(light_matrix.IMAGE_HAPPY)
light_matrix.clear()

button.pressed(button.LEFT)                   # ms held so far, 0 = not pressed (truthy as a condition)
sound.beep(440, 200, 100)                     # frequency Hz, duration ms, volume
light.color(light.POWER, color.GREEN)         # center button light to green

Putting it together: a team function library

Translate your Word Blocks-era My Blocks into Python functions - your team's standard library:

python
import runloop, motor_pair, color_sensor, motor
from hub import port, motion_sensor

WHEEL_CM = 17.5
BLACK = 35

motor_pair.pair(motor_pair.PAIR_1, port.A, port.E)

def cm_to_deg(cm):
    return int(cm / WHEEL_CM * 360)

def yaw():
    return motion_sensor.tilt_angles()[0] / 10

async def straight(cm, velocity=400):
    await motor_pair.move_for_degrees(motor_pair.PAIR_1, cm_to_deg(cm), 0, velocity=velocity)

async def turn(angle, velocity=200):
    motion_sensor.reset_yaw(0)
    steering = 100 if angle > 0 else -100
    motor_pair.move(motor_pair.PAIR_1, steering, velocity=velocity)
    if angle > 0:
        await runloop.until(lambda: yaw() > angle - 2)
    else:
        await runloop.until(lambda: yaw() < angle + 2)
    motor_pair.stop(motor_pair.PAIR_1)

async def main():
    await straight(50)
    await turn(90)
    await straight(30)
    await motor.run_for_degrees(port.C, 180, 300)   # attachment action
    await straight(-60, velocity=700)               # reverse home fast

runloop.run(main())

Next lesson: Advanced: async & PID - what await really does, plus competition-grade line following.