šŸš€ Basic Program Structure

ā–¼

Essential Imports

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor, ColorSensor, UltrasonicSensor, ForceSensor
from pybricks.parameters import Port, Direction, Color, Button, Stop, Icon
from pybricks.robotics import DriveBase
from pybricks.tools import wait

Initialize Hub

# Initialize hub
hub = PrimeHub()
# Your code here

šŸŽÆ Hub Commands

ā–¼

šŸ’” Lights

hub.light.on(Color.RED)           # Turn on light
hub.light.off()                   # Turn off light
hub.light.blink(Color.BLUE, [500, 500])  # Blink pattern

šŸ“ŗ Display

hub.display.number(42)            # Show number (0-99)
hub.display.char("A")             # Show character
hub.display.text("Hi!")           # Scroll text
hub.display.icon(Icon.HAPPY)      # Show icon
hub.display.pixel(row, col, 100)  # Light pixel (0-4, 0-4, brightness%)
hub.display.off()                 # Clear display

šŸ”Š Sound

hub.speaker.beep()                # Simple beep
hub.speaker.beep(500, 1000)       # Frequency (Hz), Duration (ms)
hub.speaker.volume(50)            # Set volume (0-100)

šŸ”˜ Buttons

pressed = hub.buttons.pressed()
if Button.CENTER in pressed:
    # Do something

šŸŽÆ IMU (Motion Sensor)

up_side = hub.imu.up()            # Which side is up?
pitch, roll = hub.imu.tilt()      # Get tilt angles

āš™ļø Motor Commands

ā–¼

šŸ”§ Setup

motor = Motor(Port.A)                              # Basic
motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)  # Reversed

šŸƒ Basic Movement

motor.run(500)              # Run at 500 deg/s
motor.stop()                # Coast to stop
motor.brake()               # Brake to stop
motor.hold()                # Hold position
motor.dc(50)                # Run at 50% power

šŸŽÆ Precise Movement

motor.run_time(500, 2000)   # Speed (deg/s), Time (ms)
motor.run_angle(500, 360)   # Speed (deg/s), Angle (deg)
motor.run_target(500, 90)   # Speed (deg/s), Target position (deg)

šŸ“Š Reading Motor Data

angle = motor.angle()       # Current angle
speed = motor.speed()       # Current speed
motor.reset_angle(0)        # Reset angle to 0
if motor.stalled():         # Check if stuck
    print("Motor stuck!")

šŸš— DriveBase (Robot Movement)

ā–¼

šŸ”§ Setup

left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B)
# Basic setup
robot = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=112)

# With gyro for better turning accuracy (recommended for FLL)
robot = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=112)
robot.use_gyro(True)  # Enable gyro for more accurate turns

# Configure DriveBase settings
robot.settings(
    straight_speed=200,     # mm/s for straight driving
    straight_acceleration=100,  # mm/s² acceleration
    turn_rate=90,          # deg/s for turning
    turn_acceleration=200   # deg/s² turn acceleration
)

šŸŽ® Commands

robot.straight(200)         # Drive 200mm forward
robot.turn(90)              # Turn 90° right
robot.drive(100, 30)        # Speed (mm/s), Turn rate (deg/s)
robot.stop()                # Stop driving

# Advanced DriveBase commands
robot.curve(radius=200, angle=90)  # Drive in arc (radius in mm)
robot.drive_time(100, 0, 2000)     # Drive for specific time (2 seconds)

# Get current state
distance = robot.distance()        # Total distance traveled
angle = robot.angle()              # Total angle turned
state = robot.state()              # Current driving state (tuple)

# Reset measurements
robot.reset()                      # Reset distance and angle to 0

# Non-blocking movements (for parallel tasks)
robot.straight(200, wait=False)    # Start moving, don't wait
while not robot.done():            # Check if movement complete
    # Do other things while moving
    pass

šŸ“” Sensors

ā–¼

🌈 Color Sensor

sensor = ColorSensor(Port.C)
color = sensor.color()              # Detect color
reflection = sensor.reflection()    # Light reflection (0-100%)
ambient = sensor.ambient()          # Room brightness (0-100%)
h, s, v = sensor.hsv()              # Get HSV values

# Check specific color
if sensor.color() == Color.RED:
    print("Red detected!")

šŸ“ Ultrasonic Sensor

sensor = UltrasonicSensor(Port.D)
distance = sensor.distance()        # Distance in mm
if sensor.presence():               # Other ultrasonic nearby?
    print("Another sensor detected")
sensor.lights.on(100)               # Control lights (0-100%)
sensor.lights.off()

šŸ‘† Force Sensor

sensor = ForceSensor(Port.E)
if sensor.pressed():                # Is it pressed?
    print("Pressed!")
if sensor.touched():                # Even light touch
    print("Touched!")
    
force = sensor.force()              # Force in Newtons
distance = sensor.distance()        # Button travel in mm

šŸ”„ Loops & Conditions

ā–¼

šŸ” While Loop

while True:                         # Forever
    # Your code
    if Button.CENTER in hub.buttons.pressed():
        break                       # Exit loop

šŸ”¢ For Loop

for i in range(5):                  # Repeat 5 times
    print(i)                        # Prints 0,1,2,3,4

ā“ If Statements

if distance < 100:
    print("Too close!")
elif distance < 200:
    print("Getting close")
else:
    print("All clear")

⚔ Parallel Programming

ā–¼

⚔ Quick Parallel (Simple)

# Run two motors together
left_motor.run_angle(500, 360, wait=False)
right_motor.run_angle(500, 360)

šŸ”€ Async/Await (Advanced)

from pybricks.tools import multitask, run_task, wait

# Basic parallel tasks
async def move_arm():
    await arm_motor.run_angle(500, 360)

async def drive_forward():
    await robot.straight(200)

async def main():
    # Run multiple tasks simultaneously
    await multitask(move_arm(), drive_forward())

# DriveBase with async movements
async def complex_movement():
    # These can be awaited for async operation
    await robot.straight(200, wait=False)  # Start moving
    await arm_motor.run_angle(300, 90)     # Move arm while driving
    await robot.turn(90)                   # Turn after both complete

# Parallel sensor monitoring
async def monitor_color():
    while True:
        if color_sensor.color() == Color.RED:
            hub.light.on(Color.RED)
        await wait(10)

async def drive_mission():
    await robot.straight(500)
    await robot.turn(90)

# Run driving while monitoring sensors
async def mission():
    await multitask(
        monitor_color(),
        drive_mission()
    )

run_task(main())

šŸŽØ References

ā–¼

šŸŽØ Colors

Color.BLACK
Color.VIOLET
Color.BLUE
Color.CYAN
Color.GREEN
Color.YELLOW
Color.ORANGE
Color.RED
Color.WHITE
Color.NONE
Color.BROWN
Color.MAGENTA
# Custom color
my_color = Color(h=120, s=100, v=50)  # Hue, Saturation, Value

šŸŽ­ Icons

Icon.ARROW_UP
Icon.ARROW_DOWN
Icon.ARROW_LEFT
Icon.ARROW_RIGHT
Icon.HAPPY
Icon.SAD
Icon.HEART
Icon.SQUARE
Icon.CIRCLE
Icon.TRIANGLE
Icon.DIAMOND
Icon.UP
Icon.DOWN
Icon.LEFT
Icon.RIGHT
Icon.NO

ā±ļø Timing

wait(1000)                          # Wait 1 second (1000ms)

from pybricks.tools import StopWatch
timer = StopWatch()
timer.time()                        # Get elapsed time
timer.pause()                       # Pause timer
timer.resume()                      # Resume timer
timer.reset()                       # Reset to 0

šŸ”§ Common Patterns

ā–¼

šŸ“ Line Following

while True:
    if color_sensor.reflection() < 30:  # On black line
        robot.drive(100, -30)            # Turn left
    else:                                # On white
        robot.drive(100, 30)             # Turn right

🚧 Obstacle Avoidance

while True:
    if distance_sensor.distance() < 200:
        robot.stop()
        robot.turn(90)
    else:
        robot.drive(150, 0)

šŸ”˜ Button Control

while True:
    pressed = hub.buttons.pressed()
    
    if Button.LEFT in pressed:
        motor.run(-500)
    elif Button.RIGHT in pressed:
        motor.run(500)
    elif Button.CENTER in pressed:
        break
    else:
        motor.stop()

šŸ“ Square to Wall (FLL Alignment)

# Square up against a wall for consistent positioning
robot.drive(-50, 0)  # Drive backward slowly
wait(2000)           # Push against wall for 2 seconds
robot.stop()         # Now perfectly aligned
robot.straight(50)   # Back up to starting position

šŸŽÆ Proportional Line Following

# Smoother line following with proportional control
target = 50  # Target reflection value (edge of line)
kp = 1.5     # Proportional gain

while robot.distance() < 500:  # Follow for 500mm
    error = color_sensor.reflection() - target
    turn_rate = kp * error
    robot.drive(100, turn_rate)

šŸ”„ Gyro Turn (Precise Angles)

# Use gyro for accurate turns
robot.use_gyro(True)  # Enable gyro
robot.turn(90)        # Precisely 90 degrees

# Or manual gyro control
hub.imu.reset_heading(0)  # Reset gyro
while abs(hub.imu.heading()) < 90:
    robot.drive(0, 50)  # Turn at 50 deg/s
robot.stop()

šŸ Mission Template

def mission_1():
    \"\"\"Complete mission 1 and return to base\"\"\"
    # Navigate to mission
    robot.straight(300)
    robot.turn(45)
    
    # Complete mission action
    arm_motor.run_angle(500, 180)
    
    # Return to base
    robot.turn(-45)
    robot.straight(-300)
    
    return True  # Mission success

# Run mission with error handling
try:
    success = mission_1()
    if success:
        hub.speaker.beep(1000, 100)  # Success sound
except:
    hub.light.on(Color.RED)  # Error indicator
    robot.stop()

āš ļø Error Handling

ā–¼

Safe Sensor Reading

# Handle potential None values from sensors
distance = ultrasonic.distance()
if distance is not None and distance < 100:
    robot.stop()

# Try-except for robust code
try:
    # Attempt sensor reading
    color = color_sensor.color()
    if color == Color.RED:
        robot.stop()
except:
    # Handle sensor disconnection
    print("Sensor error - continuing")
    robot.stop()  # Safe default action

Motor Stall Detection

# Check if motor is stalled
if motor.control.stalled():
    motor.stop()
    print("Motor stalled!")
    
# Safe motor movement with timeout
try:
    motor.run_until_stalled(500, Stop.HOLD, duty_limit=50)
except:
    print("Motor couldn't complete movement")
    motor.stop()

Button Safety

# Emergency stop with center button
while True:
    if Button.CENTER in hub.buttons.pressed():
        robot.stop()
        break  # Exit program
    
    # Your mission code here
    robot.straight(100)

šŸ“Š Data Logging

ā–¼

DataLog Setup

from pybricks.tools import DataLog, StopWatch

# Create data logger
data = DataLog('time', 'distance', 'color', name='mission_log')
timer = StopWatch()

# Log data during mission
while timer.time() < 10000:  # Run for 10 seconds
    distance = ultrasonic.distance()
    color = color_sensor.color()
    
    # Log the data
    data.log(timer.time(), distance, color)
    
    # Your mission code
    robot.drive(100, 0)
    wait(100)  # Log every 100ms

# Data is saved automatically

StopWatch Usage

from pybricks.tools import StopWatch

# Create and start timer
timer = StopWatch()

# Measure operation time
timer.reset()  # Start timing
robot.straight(500)
elapsed = timer.time()  # Get time in milliseconds
print(f"Movement took {elapsed}ms")

# Pause and resume
timer.pause()
# Do something else
timer.resume()

# Use for timeout
timer.reset()
while timer.time() < 5000:  # 5 second timeout
    if color_sensor.color() == Color.RED:
        break
    wait(10)

Performance Monitoring

# Monitor battery and performance
print(f"Battery: {hub.battery.voltage()}mV")
print(f"Current: {hub.battery.current()}mA")

# Log motor performance
data = DataLog('time', 'angle', 'speed')
timer = StopWatch()

while timer.time() < 5000:
    data.log(
        timer.time(),
        motor.angle(),
        motor.speed()
    )
    wait(50)

šŸ’” Tips & Tricks

ā–¼

šŸ› Debug with Print

print("Distance:", distance)       # See values in terminal

šŸ“ Remember Units

Angles: degrees (360° = full rotation)
Speed: deg/s for motors, mm/s for DriveBase
Time: milliseconds (1000ms = 1 second)
Distance: millimeters (10mm = 1cm)
Force: Newtons

šŸ”¢ Common Values

Wheel diameter: Usually 56mm or 88mm
Axle track: Measure between wheel centers
Motor speed: 100-1000 deg/s typical
Drive speed: 50-300 mm/s typical

šŸ”§ Quick Fixes

Motor runs wrong way

Add Direction.COUNTERCLOCKWISE

Robot turns wrong way

Swap motor ports or directions

Nothing happens

Check port connections

Program won't stop

Hold CENTER button 3 seconds

Can't connect

Check Bluetooth is on

šŸŽÆ FLL Competition Tips

1. Test values

Colors and distances change with lighting

2. Calibrate

Test sensor values at competition table

3. Battery

Low battery = slower motors

4. Attachments

Test with wait=False or async

5. Reliability

Add error handling for sensors

6. Speed

Balance speed vs accuracy

7. Gyro Drift

Reset hub.imu before each run

8. Start Position

Use jigs for consistent placement

9. Mission Functions

Modular code = easier debugging

10. Time Management

2.5 min matches - plan wisely

11. use_gyro(True)

Enable for accurate turns

12. Data Logging

Record runs to find issues

⚔ Performance Optimizations

# Faster acceleration for time-critical missions
robot.settings(
    straight_acceleration=500,  # Faster acceleration
    turn_acceleration=500       # Faster turn acceleration
)

# Pre-compile functions for speed
def fast_grab():
    claw_motor.run_target(1000, 0, Stop.HOLD, wait=False)
    
# Use constants instead of calculations
MISSION_1_DISTANCE = 456  # Pre-measured
TURN_ANGLE = 87           # Fine-tuned

# Parallel operations save time
async def quick_mission():
    await multitask(
        robot.straight(MISSION_1_DISTANCE, wait=False),
        arm_motor.run_angle(500, 180, wait=False)
    )

šŸ“ Program Template

ā–¼

šŸš€ Complete Template

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor, ColorSensor
from pybricks.parameters import Port, Direction, Button
from pybricks.robotics import DriveBase
from pybricks.tools import wait

# Initialize
hub = PrimeHub()
left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B)
robot = DriveBase(left_motor, right_motor, 56, 112)
robot.use_gyro(True)  # Enable gyro for accurate turns
color_sensor = ColorSensor(Port.C)

# Main program
def main():
    while True:
        # Your code here
        
        # Exit on center button
        if Button.CENTER in hub.buttons.pressed():
            break
    
    # Cleanup
    robot.stop()
    hub.light.off()

# Run
main()
Remember: Start simple, test often, and have fun! šŸš€