๐Ÿ’ก Level 1 โ€“ Fundamentals

Project 1.9: "Speed Control"

ย 

๐Ÿš€ Project 1.9 โ€“ Speed Control


๐ŸŽฏ What Youโ€™ll Learn

  • โœ… Goal 1: Control motor speed gradually.
  • โœ… Goal 2: Create smooth acceleration and variable speed curves.
  • โœ… Goal 3: Simulate terrain changes with automatic speed adjustment.

Key Ideas

  • PWM duty cycle: Controls motor speed.
  • Loops: Change speed step by step.
  • Logic: Adjust speed based on conditions.

๐Ÿงฑ Blocks Glossary (used in this project)

  • pwmX = machine.PWM(machine.Pin(X)) โ†’ Motor speed control.
  • pwmX.freq(2000) โ†’ Set PWM frequency.
  • pwmX.duty(value) โ†’ Set duty cycle (0โ€“1023).
  • pinX = machine.Pin(X, machine.Pin.OUT) โ†’ Motor direction.
  • pinX.value(1) โ†’ Forward.
  • pinX.value(0) โ†’ Backward.
  • time.sleep() โ†’ Delay.
  • for i in range(...) โ†’ Loop for gradual changes.

๐Ÿงฐ What You Need

PartHow many?Pin connection
D1 R321USB cable
L298N Driver1IN1=Pin 2, IN2=Pin 4, ENA=Pin 5; IN3=Pin 12, IN4=Pin 13, ENB=Pin 14
Motors2Connected to L298N outputs

๐Ÿ”Œ Wiring tip: Motor A = pins 2/4/5, Motor B = pins 12/13/14.


โœ… Before You Start

  • USB cable connected
  • Motors wired correctly
  • Test print shows:
print("Ready!")  # Confirm serial is working

๐ŸŽฎ Microprojects (5 Mini Missions)


๐ŸŽฎ Microproject 1.9.1 โ€“ Gradual speed

Blocks used: PWM, Loop, Delay
Block sequence:

  1. Setup motor PWM
  2. Increase duty cycle step by step
  3. Observe gradual speed

MicroPython Code:

import machine, time                          # Import modules

pin2 = machine.Pin(2, machine.Pin.OUT)        # Motor A IN1
pin4 = machine.Pin(4, machine.Pin.OUT)        # Motor A IN2
pwm5 = machine.PWM(machine.Pin(5))            # Motor A ENA PWM

pwm5.freq(2000)                               # Set PWM frequency to 2 kHz
pin2.value(1)                                 # Motor A forward IN1 HIGH
pin4.value(0)                                 # Motor A forward IN2 LOW

for duty in range(0, 1024, 128):              # Loop from 0 to 1023 step 128
    pwm5.duty(duty)                           # Set duty cycle
    print("Motor speed duty:", duty)          # Serial log
    time.sleep(0.5)                           # Delay for observation

Reflection: Motor speed increases gradually.
Challenge: Try smaller steps (64) for smoother acceleration.


๐ŸŽฎ Microproject 1.9.2 โ€“ Smooth acceleration

Blocks used: PWM, Loop, Delay
Block sequence:

  1. Setup motor PWM
  2. Increase duty cycle slowly
  3. Create smooth acceleration

MicroPython Code:

import machine, time                          # Import modules

pin12 = machine.Pin(12, machine.Pin.OUT)      # Motor B IN3
pin13 = machine.Pin(13, machine.Pin.OUT)      # Motor B IN4
pwm14 = machine.PWM(machine.Pin(14))          # Motor B ENB PWM

pwm14.freq(2000)                              # Set PWM frequency to 2 kHz
pin12.value(1)                                # Motor B forward IN3 HIGH
pin13.value(0)                                # Motor B forward IN4 LOW

for duty in range(0, 1024, 64):               # Loop from 0 to 1023 step 64
    pwm14.duty(duty)                          # Set duty cycle
    print("Motor B speed duty:", duty)        # Serial log
    time.sleep(0.3)                           # Delay for smoother acceleration

Reflection: Motor accelerates smoothly.
Challenge: Try decreasing duty for smooth deceleration.


๐ŸŽฎ Microproject 1.9.3 โ€“ Variable speed curves

Blocks used: PWM, Loop, Delay
Block sequence:

  1. Setup motor PWM
  2. Alternate duty cycles
  3. Create speed curve pattern

MicroPython Code:

import machine, time                          # Import modules

pin2 = machine.Pin(2, machine.Pin.OUT)        # Motor A IN1
pin4 = machine.Pin(4, machine.Pin.OUT)        # Motor A IN2
pwm5 = machine.PWM(machine.Pin(5))            # Motor A ENA PWM

pwm5.freq(2000)                               # Set PWM frequency
pin2.value(1)                                 # Motor A forward
pin4.value(0)                                 # Motor A forward

curve = [256, 512, 768, 1023, 512, 256]       # Speed curve values

for duty in curve:                            # Loop through curve
    pwm5.duty(duty)                           # Set duty cycle
    print("Curve duty:", duty)                # Serial log
    time.sleep(0.5)                           # Delay

Reflection: Motor follows variable speed curve.
Challenge: Try designing your own curve.


๐ŸŽฎ Microproject 1.9.4 โ€“ Simulated distance control

Blocks used: PWM, Loop, Delay
Block sequence:

  1. Setup motor PWM
  2. Run at different speeds for โ€œdistanceโ€
  3. Stop after loop

MicroPython Code:

import machine, time                          # Import modules

pin12 = machine.Pin(12, machine.Pin.OUT)      # Motor B IN3
pin13 = machine.Pin(13, machine.Pin.OUT)      # Motor B IN4
pwm14 = machine.PWM(machine.Pin(14))          # Motor B ENB PWM

pwm14.freq(2000)                              # Set PWM frequency
pin12.value(1)                                # Motor B forward
pin13.value(0)                                # Motor B forward

for duty in [256, 512, 768]:                  # Different speeds
    pwm14.duty(duty)                          # Set duty cycle
    print("Motor B duty:", duty)              # Serial log
    time.sleep(2)                             # Run for 2 seconds

pwm14.duty(0)                                 # Stop motor
print("Motor stopped")                        # Serial log

Reflection: Motor simulates distance with speed changes.
Challenge: Try longer times for each speed.


๐ŸŽฎ Microproject 1.9.5 โ€“ Automatic speed by โ€œterrainโ€

Blocks used: PWM, Logic, Delay
Block sequence:

  1. Setup motor PWM
  2. If terrain = flat โ†’ medium speed
  3. If terrain = hill โ†’ high speed

MicroPython Code:

import machine, time                          # Import modules

pin2 = machine.Pin(2, machine.Pin.OUT)        # Motor A IN1
pin4 = machine.Pin(4, machine.Pin.OUT)        # Motor A IN2
pwm5 = machine.PWM(machine.Pin(5))            # Motor A ENA PWM

pwm5.freq(2000)                               # Set PWM frequency
pin2.value(1)                                 # Motor A forward
pin4.value(0)                                 # Motor A forward

terrain = "hill"                              # Simulated terrain

if terrain == "flat":                         # If terrain is flat
    pwm5.duty(512)                            # Medium speed
    print("Flat terrain: duty 512")           # Serial log
elif terrain == "hill":                       # If terrain is hill
    pwm5.duty(768)                            # Higher speed
    print("Hill terrain: duty 768")           # Serial log

time.sleep(3)                                 # Run for 3 seconds
pwm5.duty(0)                                  # Stop motor
print("Motor stopped")                        # Serial log

Reflection: Motor speed changes with terrain condition.
Challenge: Add more terrain types.


ย 

โœจ Main Project โ€“ Speed Control

๐Ÿ”ง Blocks Steps (with glossary)

  • PWM: Control motor speed.
  • Loops: Gradual changes.
  • Logic: Adjust speed by conditions.

Block sequence:

  1. Setup motors with PWM.
  2. Gradually increase speed.
  3. Smooth acceleration.
  4. Variable curves.
  5. Terrain simulation.

๐Ÿ MicroPython Code (mirroring blocks)

# Project 1.9 โ€“ Speed Control

import machine, time                          # Import required modules

# Motor A setup
pin2 = machine.Pin(2, machine.Pin.OUT)        # Motor A IN1
pin4 = machine.Pin(4, machine.Pin.OUT)        # Motor A IN2
pwm5 = machine.PWM(machine.Pin(5))            # Motor A ENA PWM

# Motor B setup
pin12 = machine.Pin(12, machine.Pin.OUT)      # Motor B IN3
pin13 = machine.Pin(13, machine.Pin.OUT)      # Motor B IN4
pwm14 = machine.PWM(machine.Pin(14))          # Motor B ENB PWM

# Configure PWM frequency
pwm5.freq(2000)                               # Set PWM frequency for motor A
print("Motor A PWM freq: 2000 Hz")            # Serial log
pwm14.freq(2000)                              # Set PWM frequency for motor B
print("Motor B PWM freq: 2000 Hz")            # Serial log

# Forward direction for both motors
pin2.value(1)                                 # Motor A forward
pin4.value(0)                                 # Motor A forward
pin12.value(1)                                # Motor B forward
pin13.value(0)                                # Motor B forward
print("Motors set to forward")                # Serial log

# Gradual speed increase
for duty in range(0, 1024, 128):              # Loop from 0 to 1023 step 128
    pwm5.duty(duty)                           # Motor A duty cycle
    pwm14.duty(duty)                          # Motor B duty cycle
    print("Duty cycle:", duty)                # Serial log
    time.sleep(0.5)                           # Delay

# Smooth acceleration
for duty in range(0, 1024, 64):               # Smaller steps for smoothness
    pwm5.duty(duty)                           # Motor A duty cycle
    pwm14.duty(duty)                          # Motor B duty cycle
    print("Smooth duty:", duty)               # Serial log
    time.sleep(0.3)                           # Delay

# Variable speed curve
curve = [256, 512, 768, 1023, 512, 256]       # Curve values
for duty in curve:                            # Loop through curve
    pwm5.duty(duty)                           # Motor A duty cycle
    pwm14.duty(duty)                          # Motor B duty cycle
    print("Curve duty:", duty)                # Serial log
    time.sleep(0.5)                           # Delay

# Terrain simulation
terrain = "hill"                              # Simulated terrain
if terrain == "flat":                         # If terrain is flat
    pwm5.duty(512)                            # Medium speed
    pwm14.duty(512)                           # Medium speed
    print("Flat terrain: duty 512")           # Serial log
elif terrain == "hill":                       # If terrain is hill
    pwm5.duty(768)                            # Higher speed
    pwm14.duty(768)                           # Higher speed
    print("Hill terrain: duty 768")           # Serial log

time.sleep(3)                                 # Run for 3 seconds
pwm5.duty(0)                                  # Stop motor A
pwm14.duty(0)                                 # Stop motor B
print("Motors stopped")                       # Serial log

๐Ÿ“– External Explanation

This project shows how PWM controls motor speed.

  • Gradual increase teaches duty cycle basics.
  • Smooth acceleration uses smaller steps.
  • Curves simulate speed profiles.
  • Terrain logic shows conditional control.

โœจ Story Time

Imagine your robot as a car ๐Ÿš—. On a flat road, it cruises at medium speed. On a hill, it accelerates harder. By programming speed curves, you choreograph how your robot โ€œfeelsโ€ the terrain.


๐Ÿ•ต๏ธ Debugging (2 Common Problems)

๐Ÿž Debugging 1.9.A โ€“ Speed does not change

Problem: Motor runs at same speed.
Clues: Duty cycle not updated.
Broken code:

pwm5.duty(512)   # Always same duty

Fixed code:

for duty in range(0, 1024, 128):
    pwm5.duty(duty)

Why it works: Loop updates duty cycle step by step.
Avoid next time: Always use loops for gradual changes.


๐Ÿž Debugging 1.9.B โ€“ Sudden movement

Problem: Motor jumps to high speed.
Clues: Duty cycle set too high at once.
Broken code:

pwm14.duty(1023)   # Max speed instantly

Fixed code:

for duty in range(0, 1024, 64):
    pwm14.duty(duty)

Why it works: Smaller increments create smooth acceleration.
Avoid next time: Use gradual loops instead of single max duty.


โœ… Final Checklist

  • Gradual speed increase works.
  • Smooth acceleration implemented.
  • Variable speed curves tested.
  • Terrain simulation logic applied.
  • Motors stop correctly.

๐Ÿ“š Extras

  • ๐Ÿง  Student tip: Try designing your own speed curve.
  • ๐Ÿง‘โ€๐Ÿซ Instructor tip: Show how duty cycle values map to speed.
  • ๐Ÿ“– Glossary: PWM, duty cycle, acceleration, terrain simulation.
  • ๐Ÿ’ก Mini tip: Always test with small duty values before max speed.
On this page