STARLEAP / SPIKE PRIME PYTHON / 2026–27
Build 2026.09.22-090630-0400
On this page
- Step 1: Make One Short Ride
- Step 2: Change Speed, Keep The Amount
- Step 3: Name The Setting
- Step 4: Calculate A New Setting
- Step 5: Put A Ride In A Function
- Step 6: Give The Function A Speed
- Step 7: Repeat Three Rides Without Buttons
- Step 8: Increase Speed Each Time
- Step 9: Read Buttons With The Motors Stopped
- Step 10: Make One Press Count Once
- Step 11: Limit The Three Modes
- Step 12: Ride After Confirming
- Teacher Check
- Optional Challenges
Project 19: Smart Bike Speed Modes
You need: a LEGO SPIKE Prime set, the SPIKE App Python editor, and the Smart Bike with both Bike and Biker built. Connect its motors to C and E. Keep its support wheels and use a clear, level floor.
Make short rides that get faster automatically in a for loop. Then use the left hub button to choose a setting and the right button to start. Start here in the Smart Bike route: 19 -> 20 -> 17 -> 21 or 22. Project numbers from earlier packets have stayed the same.
Use the motor-pair ideas from Project 03 and the function-argument practice from Project 09. Stop the program before each edit. Gray lines are already there; dark lines are new or changed. Keep four spaces inside a function.
Step 1: Make One Short Ride
Create a new Python project named Bike Speed Modes. Type this starter:
from hub import port
import motor_pair
import runloop
bike_motor = port.C
rider_motor = port.E
async def main():
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
await motor_pair.move_for_degrees(
motor_pair.PAIR_1, 360, 0, velocity=100)
motor_pair.stop(motor_pair.PAIR_1)
runloop.run(main())
bike_motor names the bike motor on C; rider_motor names the rider motor on E. Define these port variables after the imports, before any functions. Use the names in commands so the code tells you which parts it controls.
Run the program on the clear floor. The bike should make one short forward ride and stop. The 360 is motor degrees, not centimetres. The 0 requests straight movement. Check the build and C/E wiring with your teacher if it does not travel forward; do not try random port changes.
Step 2: Change Speed, Keep The Amount
Change only the velocity to 150:
await motor_pair.move_for_degrees(
motor_pair.PAIR_1, 360, 0, velocity=150)
Predict: Will the bike request more motor rotation, or complete the same rotation faster?
Run the program from the same mark. The requested amount is still 360 degrees. Compare how long it takes. Small differences in the stopping place can come from the physical bike and floor.
Step 3: Name The Setting
Replace main() with this version. Keep the imports and final start call:
async def main():
speed = 150
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
await motor_pair.move_for_degrees(
motor_pair.PAIR_1, 360, 0, velocity=speed)
motor_pair.stop(motor_pair.PAIR_1)
Run the program. It should behave as before. speed is a variable inside main(); its value is a requested motor velocity in degrees per second.
Step 4: Calculate A New Setting
Insert the dark line immediately after the assignment:
speed = 150
speed = speed + 50
Predict the value of speed after both lines. Run the program and compare the ride with Step 3. Python calculates the right side first, then stores the new value. The result is 200, not a second motor command.
Step 5: Put A Ride In A Function
Add this definition below the port variables and above main():
async def ride():
await motor_pair.move_for_degrees(
motor_pair.PAIR_1, 360, 0, velocity=200)
motor_pair.stop(motor_pair.PAIR_1)
Replace main() with these lines. This removes the old movement so the bike does not ride twice:
async def main():
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
await ride()
Run the program. The one short ride should stay the same. The definition describes the job; await ride() calls it and waits for it to finish.
Step 6: Give The Function A Speed
Replace the whole ride() definition:
async def ride(chosen_speed):
await motor_pair.move_for_degrees(
motor_pair.PAIR_1, 360, 0, velocity=chosen_speed)
motor_pair.stop(motor_pair.PAIR_1)
Then replace main():
async def main():
speed = 100
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
await ride(speed)
Run the program. The bike should use the slower setting. The argument speed passes 100 into the parameter chosen_speed. Without a parameter, our old function always used 200. Point to where the supplied number reaches the motor command.
Step 7: Repeat Three Rides Without Buttons
Replace main() with this version. Keep the port variables, ride(chosen_speed), and the final start call:
async def main():
speed = 100
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
for ride_number in range(3):
print(speed)
await ride(speed)
await runloop.sleep_ms(1000)
range(3) repeats the indented block three times. ride_number is the loop variable; it takes the values 0, 1, and 2. We do not need to use it inside this block yet. The print, ride, and pause are all eight spaces in, so all three happen on each repeat.
Before you run: Clear enough floor for three short rides in the same direction. Each ride requests 360 motor degrees, so this program travels farther than the one-ride version. Keep hands away and use the SPIKE App stop control if needed.
Run the program without touching any buttons. Watch three rides with a one-second pause after each. The console should show 100 three times. The loop repeats the movement, but it does not change speed yet.
Step 8: Increase Speed Each Time
Add a variable beside speed, before the loop:
speed = 100
speed_increase = 50
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
Then add the dark line after the pause, still eight spaces in, inside the loop:
await ride(speed)
await runloop.sleep_ms(1000)
speed = speed + speed_increase
Predict the three numbers that will print. The starting assignment is outside the loop, so it runs once. The addition is inside the loop, so it runs after every ride and pause.
Run the program on the clear three-ride route. The console should show 100, 150, then 200. Each ride still requests 360 motor degrees, but the rides should take less time as the speed increases. The loop finishes after three rides. Its last addition makes speed 250, but there is no fourth ride using that value.
Change only speed_increase to 25. Predict, run, and compare: the three settings should be 100, 125, and 150. Restore 50 after testing. Keep three repeats for these tests.
Fix it: If every ride uses 100, check that the starting assignment is above the loop and the addition is inside it. If the console changes but the bike does not, check that await ride(speed) passes the variable into the function.
Save this automatic version as Bike Automatic Speeds before continuing. Keep it for your teacher check and optional challenges. Continue editing a separate copy named Bike Speed Modes; the next step replaces the automatic loop with a button test.
Step 9: Read Buttons With The Motors Stopped
Replace the first import:
from hub import port, button
Temporarily replace main() with this button test. Keep the ride(chosen_speed) definition, but do not call it:
async def main():
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
motor_pair.stop(motor_pair.PAIR_1)
for test in range(30):
print(button.pressed(button.LEFT))
await runloop.sleep_ms(100)
Run the program. Hold and release the left hub button while watching the console. A pressed reading is nonzero; a released reading is zero. The bike stays still. Thirty short pauses give you roughly three seconds to test.
Step 10: Make One Press Count Once
Replace main() with this selector test. The bike still stays stopped:
async def main():
speed = 100
motor_pair.pair(motor_pair.PAIR_1, bike_motor, rider_motor)
motor_pair.stop(motor_pair.PAIR_1)
print(speed)
while not button.pressed(button.RIGHT):
if button.pressed(button.LEFT):
speed = speed + 50
print(speed)
while button.pressed(button.LEFT):
await runloop.sleep_ms(50)
await runloop.sleep_ms(50)
print("selection finished")
Run the program. Tap left, then hold it. Each press should add 50 only once because the inner while waits for release. Press right after releasing left to finish. not means the outer loop continues while right is not pressed. The pauses let the program yield between checks.
Step 11: Limit The Three Modes
Add this if immediately after the addition and before print(speed):
speed = speed + 50
if speed > 200:
speed = 200
print(speed)
Run the program. The settings should be 100, 150, then 200. More left presses should leave it at 200. These are our slow, medium and fast modes for this short test. They are motor settings, not measured road speeds. Restart to choose 100 again. Finish with right.
Step 12: Ride After Confirming
Replace the final print("selection finished") with these lines, indented four spaces inside main(), after the selection loop:
while button.pressed(button.RIGHT):
await runloop.sleep_ms(50)
await runloop.sleep_ms(1000)
await ride(speed)
Before you run: Clear the floor. After you press and release right, the bike waits one second, then rides once. Move your hands away during that pause. The right button is a start button here, not an emergency stop while moving; use the SPIKE App stop control if needed.
Run the program three times, starting at the same mark. Choose 100, 150 and 200 on separate runs. The degree amount stays 360 in every mode.
Fix it: If one hold changes the setting repeatedly, check the inner release loop. If the function reports a missing argument, check both ride(chosen_speed) and await ride(speed). If the bike starts during selection, check that the call is after the loop, not inside it.
Teacher Check
Show your teacher:
- the saved automatic loop making three rides at increasing speeds without buttons
- the predicted and observed speeds for increments of 50 and 25
- three button-selected speed settings with the same requested motor rotation
- a held left button counting once, and repeated presses staying at 200
- the argument passed from
main()intochosen_speed - why this program waits for the right button to be released
Optional Challenges
Choose either challenge. Work out your own program and show your teacher the result. Revisit this project's automatic loop and Project 02 if you need a refresher.
- Speed up, then slow down: Make the bike increase its speed in steps, then decrease its speed in steps, and finish stopped.
- Return in reverse: Make the bike travel away from its starting point, then return to that point in reverse and stop.
Save your program. Continue to Project 20 to calculate rides in centimetres.