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 useHOLD.
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), advancedpython
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 decinewtonshub 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 greenPutting 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.