📡 Level 3 – Advanced Communication

Project 3.5: "IR Controlled Car"

 

🚀 Project 3.5 – IR Controlled Car

🎯 What you’ll learn

  • ✅ Goal 1: Control a two‑motor car using an IR remote (Forward/Back/Left/Right)
  • ✅ Goal 2: Adjust speed with remote buttons and see clear serial feedback
  • ✅ Goal 3: Use pre‑programmed moves and basic obstacle avoidance with simple rules

Key ideas

  • Short definition: An IR remote sends codes; the car maps codes to directions and speed.
  • Real‑world link: Remote‑controlled cars, TV remotes, and robot toys use IR for simple commands.

🧱 Blocks glossary (used in this project)

  • IR receive: Listen for IR codes from a handheld remote.
  • Serial print: Show status (direction, speed, errors) on your computer.
  • Digital output: Set motor direction pins (ON/OFF).
  • PWM output: Set motor speed (0–100% duty cycle).
  • Variable: Store speed, codes, and state (like “moving forward”).
  • if / else: Choose actions based on the received code.
  • Loop: Keep reading commands and controlling the car.

🧰 What you need

PartHow many?Pin connection (D1 R32)
D1 R321USB cable
L298N Motor Driver1ENA → Pin 5 (PWM), IN1 → Pin 23, IN2 → Pin 19
  ENB → Pin 18 (PWM), IN3 → Pin 13, IN4 → Pin 21
IR Receiver Module1Signal → Pin 26
TT Motors (left/right)2Wired to L298N outputs (OUT1/OUT2 left, OUT3/OUT4 right)
  • Use your provided IR hex‑command map (examples):
    • Up: 0x18, Down: 0x52, Left: 0x8, Right: 0x5A, OK: 0x1C, 1: 0x45, 2: 0x46, 3: 0x47, 0: 0x19, #: 0xD, *: 0x16
  • Power L298N from battery or supply per kit; share GND with D1 R32.

🔌 Wiring tip: Tie D1 R32 GND to L298N GND. Keep IR receiver facing forward with clear line of sight.
📍 Pin map snapshot: We use Pins 5 and 18 for PWM speed; 23,19,13,21 for directions; 26 for IR RX.


✅ Before you start

  • Plug in USB and open the serial monitor.
  • Test print shows:
print("Ready!")  # Confirm serial is working

🎮 Microprojects (5 mini missions)

🎮 Microproject 3.5.1 – IR direction control (basic moves)

Goal: Map Up/Down/Left/Right to motor direction pins.

Blocks used:

  • IR receive: Read a code
  • Digital output: Set IN1..IN4 for direction
  • Serial print: Log which direction runs

Block sequence:

  1. Setup IR receiver (Pin 26)
  2. Setup direction pins (23,19,13,21) as outputs
  3. If code is Up → forward; Down → backward; Left/Right → turn
  4. Print action

MicroPython code:

# Microproject 3.5.1 – IR direction control

import irremote                                  # Load IR communication library
import machine                                   # Load hardware pin library
import time                                      # Load time library for delays

ir_rx = irremote.NEC_RX(26, 8)                   # Create IR receiver on Pin 26 with buffer size 8
print("[Init] IR RX on 26 (Up/Down/Left/Right)") # Serial: confirm IR setup

pin23 = machine.Pin(23, machine.Pin.OUT)         # IN1 left motor direction pin
pin19 = machine.Pin(19, machine.Pin.OUT)         # IN2 left motor direction pin
pin13 = machine.Pin(13, machine.Pin.OUT)         # IN3 right motor direction pin
pin21 = machine.Pin(21, machine.Pin.OUT)         # IN4 right motor direction pin
print("[Init] Direction pins set: 23,19,13,21")  # Serial: confirm direction pins

def stop_all():                                  # Define a helper to stop movement
    pin23.value(0)                                # Left IN1 OFF
    pin19.value(0)                                # Left IN2 OFF
    pin13.value(0)                                # Right IN3 OFF
    pin21.value(0)                                # Right IN4 OFF

while True:                                       # Continuous command loop
    if ir_rx.any():                                # If an IR code arrived
        code = ir_rx.code[0]                       # Read first code from buffer
        print("[IR] Code:", hex(code))             # Show code in hex
        if code == 0x18:                           # If Up arrow
            pin23.value(1)                         # Left IN1 ON (forward)
            pin19.value(0)                         # Left IN2 OFF
            pin13.value(1)                         # Right IN3 ON (forward)
            pin21.value(0)                         # Right IN4 OFF
            print("[Move] FORWARD")                # Serial: forward
        elif code == 0x52:                         # If Down arrow
            pin23.value(0)                         # Left IN1 OFF
            pin19.value(1)                         # Left IN2 ON (backward)
            pin13.value(0)                         # Right IN3 OFF
            pin21.value(1)                         # Right IN4 ON (backward)
            print("[Move] BACKWARD")               # Serial: backward
        elif code == 0x8:                          # If Left arrow
            pin23.value(0)                         # Left IN1 OFF
            pin19.value(1)                         # Left IN2 ON (backward)
            pin13.value(1)                         # Right IN3 ON (forward)
            pin21.value(0)                         # Right IN4 OFF
            print("[Turn] LEFT")                   # Serial: left turn
        elif code == 0x5A:                         # If Right arrow
            pin23.value(1)                         # Left IN1 ON (forward)
            pin19.value(0)                         # Left IN2 OFF
            pin13.value(0)                         # Right IN3 OFF
            pin21.value(1)                         # Right IN4 ON (backward)
            print("[Turn] RIGHT")                  # Serial: right turn
        else:                                      # If another code
            stop_all()                              # Stop motors
            print("[Move] STOP (unknown code)")     # Serial: stopped
    else:                                          # If no code this cycle
        stop_all()                                  # Keep motors stopped
        print("[Wait] No IR code")                  # Serial: waiting
    time.sleep_ms(250)                              # Small delay for readability

Reflection: Your car responds to arrow codes—forward, back, and turns.
Challenge:

  • Easy: Add “OK” (0x1C) to stop immediately.
  • Harder: Make Left/Right spin in place faster by adjusting PWM (next microproject).

🎮 Microproject 3.5.2 – IR speed control (PWM)

Goal: Use number buttons to set speed (low/medium/high).

Blocks used:

  • IR receive: Read digits
  • PWM output: Adjust duty cycle
  • Serial print: Show speed percentage

Block sequence:

  1. Setup PWM on ENA (Pin 5) and ENB (Pin 18)
  2. Map codes 1/2/3 to duty levels
  3. Apply duty to both motors
  4. Print speed

MicroPython code:

# Microproject 3.5.2 – Speed control with PWM using IR digits

import irremote                                  # Load IR communication library
import machine                                   # Load hardware/PWM library
import time                                      # Load time library

ir_rx = irremote.NEC_RX(26, 8)                   # IR receiver on Pin 26
print("[Init] IR RX on 26 (digits 1/2/3)")       # Serial: confirm IR setup

pwm5 = machine.PWM(machine.Pin(5))               # PWM on Pin 5 (ENA left motor)
pwm18 = machine.PWM(machine.Pin(18))             # PWM on Pin 18 (ENB right motor)
pwm5.freq(2000)                                  # Set PWM frequency to 2 kHz (quiet tone)
pwm18.freq(2000)                                 # Same PWM frequency for right motor
print("[Init] PWM freq 2000 Hz on 5 and 18")     # Serial: confirm PWM setup

speed = 512                                      # Start at ~50% (ESP32 duty range 0–1023)
pwm5.duty(speed)                                 # Set initial duty for left motor
pwm18.duty(speed)                                # Set initial duty for right motor
print("[Speed] Start =", speed)                  # Serial: initial speed

while True:                                      # Continuous speed control loop
    if ir_rx.any():                               # If an IR code arrived
        code = ir_rx.code[0]                      # Read first code
        print("[IR] Code:", hex(code))            # Show code in hex
        if code == 0x45:                          # If '1'
            speed = 350                           # Low speed duty
            print("[Speed] LOW =", speed)         # Serial: low speed
        elif code == 0x46:                        # If '2'
            speed = 650                           # Medium speed duty
            print("[Speed] MED =", speed)         # Serial: medium speed
        elif code == 0x47:                        # If '3'
            speed = 900                           # High speed duty
            print("[Speed] HIGH =", speed)        # Serial: high speed
        elif code == 0x19:                        # If '0'
            speed = 0                             # Stop speed
            print("[Speed] STOP =", speed)        # Serial: stop speed
        pwm5.duty(speed)                          # Apply duty to left motor
        pwm18.duty(speed)                         # Apply duty to right motor
    else:                                         # If no code this cycle
        print("[Wait] No IR code (speed)")        # Serial: waiting
    time.sleep_ms(250)                            # Small delay for readability

Reflection: You set the car’s speed with number buttons—simple and powerful.
Challenge:

  • Easy: Add “#” (0xD) to set turbo (100%).
  • Harder: Use “*” (0x16) to toggle slow‑mode (cap at 60%).

🎮 Microproject 3.5.3 – Pre‑programmed movements (macros)

Goal: Run short moves on a single button (OK).

Blocks used:

  • IR receive: Detect OK
  • Digital/PWM: Run a timed movement sequence
  • Serial print: Narrate the macro

Block sequence:

  1. On OK (0x1C) → forward for 1 s
  2. Turn right for 0.5 s
  3. Backward for 0.5 s
  4. Stop and print “Macro done”

MicroPython code:

# Microproject 3.5.3 – Pre-programmed macro on OK

import irremote                                  # Load IR communication library
import machine                                   # Load hardware/PWM and pin library
import time                                      # Load time library

ir_rx = irremote.NEC_RX(26, 8)                   # IR receiver on Pin 26
print("[Init] IR RX (macro on OK)")              # Serial: macro mode

pwm5 = machine.PWM(machine.Pin(5))               # PWM left motor enable (ENA)
pwm18 = machine.PWM(machine.Pin(18))             # PWM right motor enable (ENB)
pwm5.freq(2000)                                  # PWM frequency 2 kHz
pwm18.freq(2000)                                 # PWM frequency 2 kHz

pin23 = machine.Pin(23, machine.Pin.OUT)         # IN1 left
pin19 = machine.Pin(19, machine.Pin.OUT)         # IN2 left
pin13 = machine.Pin(13, machine.Pin.OUT)         # IN3 right
pin21 = machine.Pin(21, machine.Pin.OUT)         # IN4 right

def motors_forward():                             # Helper: forward
    pin23.value(1)                                 # Left IN1 ON
    pin19.value(0)                                 # Left IN2 OFF
    pin13.value(1)                                 # Right IN3 ON
    pin21.value(0)                                 # Right IN4 OFF

def motors_backward():                            # Helper: backward
    pin23.value(0)                                 # Left IN1 OFF
    pin19.value(1)                                 # Left IN2 ON
    pin13.value(0)                                 # Right IN3 OFF
    pin21.value(1)                                 # Right IN4 ON

def motors_right():                               # Helper: spin right
    pin23.value(1)                                 # Left IN1 ON
    pin19.value(0)                                 # Left IN2 OFF
    pin13.value(0)                                 # Right IN3 OFF
    pin21.value(1)                                 # Right IN4 ON

def motors_stop():                                # Helper: stop
    pin23.value(0)                                 # Left IN1 OFF
    pin19.value(0)                                 # Left IN2 OFF
    pin13.value(0)                                 # Right IN3 OFF
    pin21.value(0)                                 # Right IN4 OFF

speed = 700                                      # Macro speed duty
pwm5.duty(speed)                                 # Set speed left
pwm18.duty(speed)                                # Set speed right
print("[Speed] Macro duty =", speed)             # Serial: macro speed

while True:                                      # Macro trigger loop
    if ir_rx.any():                               # If code arrived
        code = ir_rx.code[0]                      # Read first code
        print("[IR] Code:", hex(code))            # Show code
        if code == 0x1C:                          # If OK button
            print("[Macro] Start")                # Serial: begin macro
            motors_forward()                      # Step 1: forward
            time.sleep_ms(1000)                   # Run 1 second
            motors_right()                        # Step 2: turn right
            time.sleep_ms(500)                    # Run 0.5 second
            motors_backward()                     # Step 3: backward
            time.sleep_ms(500)                    # Run 0.5 second
            motors_stop()                         # Step 4: stop
            print("[Macro] Done")                 # Serial: macro done
    else:                                         # If no code
        print("[Wait] No IR code (macro)")        # Serial: waiting
    time.sleep_ms(250)                            # Small delay

Reflection: One button runs a whole routine—your first move “combo.”
Challenge:

  • Easy: Create a Left‑biased macro (left → forward → stop).
  • Harder: Chain two macros: OK runs A, then # runs B.

🎮 Microproject 3.5.4 – Basic obstacle avoidance (manual assist)

Goal: If “Up” is held, allow manual stops with “0”.

Blocks used:

  • IR receive: Check Up/0
  • Digital/PWM: Move forward or stop
  • Variable: State flag (forward = True/False)

Block sequence:

  1. On Up → forward state True
  2. On 0 → stop state False
  3. While True, keep moving or stop
  4. Print state

MicroPython code:

# Microproject 3.5.4 – Assisted forward with manual stop

import irremote                                  # Load IR communication library
import machine                                   # Load hardware/PWM and pin library
import time                                      # Load time library

ir_rx = irremote.NEC_RX(26, 8)                   # IR receiver on Pin 26
print("[Init] IR RX (Up=go, 0=stop)")            # Serial: assisted mode

pwm5 = machine.PWM(machine.Pin(5))               # PWM left motor
pwm18 = machine.PWM(machine.Pin(18))             # PWM right motor
pwm5.freq(2000)                                  # PWM 2 kHz
pwm18.freq(2000)                                 # PWM 2 kHz
pwm5.duty(700)                                   # Default forward speed
pwm18.duty(700)                                  # Default forward speed

pin23 = machine.Pin(23, machine.Pin.OUT)         # IN1 left
pin19 = machine.Pin(19, machine.Pin.OUT)         # IN2 left
pin13 = machine.Pin(13, machine.Pin.OUT)         # IN3 right
pin21 = machine.Pin(21, machine.Pin.OUT)         # IN4 right

forward = False                                  # State: moving forward?
print("[State] forward =", forward)              # Serial: initial state

def go_forward():                                 # Helper: forward pins
    pin23.value(1)                                 # Left IN1 ON
    pin19.value(0)                                 # Left IN2 OFF
    pin13.value(1)                                 # Right IN3 ON
    pin21.value(0)                                 # Right IN4 OFF

def stop_all():                                   # Helper: stop pins
    pin23.value(0)                                 # Left IN1 OFF
    pin19.value(0)                                 # Left IN2 OFF
    pin13.value(0)                                 # Right IN3 OFF
    pin21.value(0)                                 # Right IN4 OFF

while True:                                      # Assisted control loop
    if ir_rx.any():                               # If a code arrived
        code = ir_rx.code[0]                      # Read code
        print("[IR] Code:", hex(code))            # Show code
        if code == 0x18:                          # If Up arrow
            forward = True                        # Set forward state
            print("[State] forward =", forward)   # Serial: now True
        elif code == 0x19:                        # If '0' digit
            forward = False                       # Clear forward state
            print("[State] forward =", forward)   # Serial: now False
    if forward:                                    # If moving forward
        go_forward()                               # Apply forward pins
        print("[Move] FORWARD (assist)")           # Serial: forward
    else:                                          # If not moving
        stop_all()                                 # Stop pins
        print("[Move] STOP (assist)")              # Serial: stop
    time.sleep_ms(250)                             # Small delay

Reflection: You combined “go” and “stop” into a safe manual assist mode.
Challenge:

  • Easy: Add “Down” to set reverse assist.
  • Harder: Add a speed toggle using “2” (medium) and “3” (high).

🎮 Microproject 3.5.5 – IR operating modes (driver modes)

Goal: Switch between three modes: Normal, Turbo, Quiet.

Blocks used:

  • IR receive: Use #, *, 0
  • PWM output: Set different duty caps
  • Serial print: Announce current mode

Block sequence:

  1. → Turbo (100%)

    • → Quiet (40%)
  2. 0 → Stop (0%)

MicroPython code:

# Microproject 3.5.5 – Operating modes: Normal/Turbo/Quiet

import irremote                                  # Load IR communication library
import machine                                   # Load hardware/PWM library
import time                                      # Load time library

ir_rx = irremote.NEC_RX(26, 8)                   # IR receiver on Pin 26
print("[Init] IR RX (modes: #, *, 0)")           # Serial: mode control

pwm5 = machine.PWM(machine.Pin(5))               # PWM left motor
pwm18 = machine.PWM(machine.Pin(18))             # PWM right motor
pwm5.freq(2000)                                  # PWM 2 kHz
pwm18.freq(2000)                                 # PWM 2 kHz

mode = "NORMAL"                                  # Start in NORMAL mode
speed = 700                                      # Default duty
pwm5.duty(speed)                                 # Apply duty to left motor
pwm18.duty(speed)                                # Apply duty to right motor
print("[Mode] NORMAL, duty =", speed)            # Serial: mode info

while True:                                      # Mode control loop
    if ir_rx.any():                               # If a code arrived
        code = ir_rx.code[0]                      # Read the code
        print("[IR] Code:", hex(code))            # Show code
        if code == 0xD:                           # If '#'
            mode = "TURBO"                        # Set mode Turbo
            speed = 1023                          # Duty max
            print("[Mode] TURBO, duty =", speed)  # Serial: turbo
        elif code == 0x16:                        # If '*'
            mode = "QUIET"                        # Set mode Quiet
            speed = 410                           # Duty ~40%
            print("[Mode] QUIET, duty =", speed)  # Serial: quiet
        elif code == 0x19:                        # If '0'
            mode = "STOP"                         # Set mode Stop
            speed = 0                             # Duty stop
            print("[Mode] STOP, duty =", speed)   # Serial: stop
        pwm5.duty(speed)                          # Apply duty left
        pwm18.duty(speed)                         # Apply duty right
    else:                                         # If no code now
        print("[Wait] No IR code (mode)")         # Serial: waiting
    time.sleep_ms(300)                            # Small delay

Reflection: Modes make the car feel different—quiet indoor vs. full‑speed outdoor.
Challenge:

  • Easy: Add “2” to set Normal (700).
  • Harder: Display mode on LCD (if available) using your LCD blocks.

✨ Main project – IR remote car with speed and modes

🔧 Blocks steps (with glossary)

  • IR receive: Read arrow/digit/mode codes
  • Digital output: Set direction pins (IN1..IN4)
  • PWM output: Set speed (ENA/ENB)
  • Variable: Track speed and mode
  • if / else: Map codes to actions

Block sequence:

  1. Setup IR RX (Pin 26), direction pins (23,19,13,21), PWM (5,18)
  2. Arrows: Up/Down/Left/Right set direction pins
  3. Digits: 1/2/3/0 set speed duty
  4. Modes: # → Turbo, * → Quiet
  5. Print clear serial logs for each action

🐍 MicroPython code (mirroring blocks)

# Project 3.5 – IR Remote Car: Directions, Speed, and Modes

import irremote                                  # Load IR communication library
import machine                                   # Load hardware/PWM and pin library
import time                                      # Load time library

ir_rx = irremote.NEC_RX(26, 8)                   # IR receiver on Pin 26
print("[Init] IR RX on 26")                      # Serial: IR init

pin23 = machine.Pin(23, machine.Pin.OUT)         # IN1 left motor
pin19 = machine.Pin(19, machine.Pin.OUT)         # IN2 left motor
pin13 = machine.Pin(13, machine.Pin.OUT)         # IN3 right motor
pin21 = machine.Pin(21, machine.Pin.OUT)         # IN4 right motor
print("[Init] Direction pins: 23,19,13,21")      # Serial: direction pins set

pwm5 = machine.PWM(machine.Pin(5))               # PWM on Pin 5 (ENA left)
pwm18 = machine.PWM(machine.Pin(18))             # PWM on Pin 18 (ENB right)
pwm5.freq(2000)                                  # PWM frequency 2 kHz (quiet)
pwm18.freq(2000)                                 # PWM frequency 2 kHz
print("[Init] PWM freq set to 2000 Hz")          # Serial: PWM init

speed = 650                                      # Start medium duty
mode = "NORMAL"                                  # Start in NORMAL mode
pwm5.duty(speed)                                 # Apply start duty left
pwm18.duty(speed)                                # Apply start duty right
print("[State] mode:", mode, "| speed:", speed)  # Serial: initial state

def stop_all():                                  # Helper: stop movement
    pin23.value(0)                                # Left IN1 OFF
    pin19.value(0)                                # Left IN2 OFF
    pin13.value(0)                                # Right IN3 OFF
    pin21.value(0)                                # Right IN4 OFF

while True:                                      # Main control loop
    if ir_rx.any():                               # If a code arrived
        code = ir_rx.code[0]                      # Read first buffered code
        print("[IR] Code:", hex(code))            # Show code in hex

        if code == 0x18:                          # Up → forward
            pin23.value(1)                        # Left forward ON
            pin19.value(0)                        # Left backward OFF
            pin13.value(1)                        # Right forward ON
            pin21.value(0)                        # Right backward OFF
            print("[Move] FORWARD")               # Serial: forward

        elif code == 0x52:                        # Down → backward
            pin23.value(0)                        # Left forward OFF
            pin19.value(1)                        # Left backward ON
            pin13.value(0)                        # Right forward OFF
            pin21.value(1)                        # Right backward ON
            print("[Move] BACKWARD")              # Serial: backward

        elif code == 0x8:                         # Left → turn left
            pin23.value(0)                        # Left backward ON for spin
            pin19.value(1)                        # Left backward ON
            pin13.value(1)                        # Right forward ON
            pin21.value(0)                        # Right backward OFF
            print("[Turn] LEFT")                  # Serial: turn left

        elif code == 0x5A:                        # Right → turn right
            pin23.value(1)                        # Left forward ON
            pin19.value(0)                        # Left backward OFF
            pin13.value(0)                        # Right backward ON
            pin21.value(1)                        # Right backward ON
            print("[Turn] RIGHT")                 # Serial: turn right

        elif code == 0x1C:                        # OK → stop
            stop_all()                             # Stop all directions
            print("[Move] STOP (OK)")             # Serial: stop

        elif code == 0x45:                        # '1' → low speed
            speed = 350                           # Duty low
            print("[Speed] LOW =", speed)         # Serial: speed set

        elif code == 0x46:                        # '2' → medium speed
            speed = 650                           # Duty medium
            print("[Speed] MED =", speed)         # Serial: speed set

        elif code == 0x47:                        # '3' → high speed
            speed = 900                           # Duty high
            print("[Speed] HIGH =", speed)        # Serial: speed set

        elif code == 0x19:                        # '0' → speed stop
            speed = 0                             # Duty zero
            stop_all()                             # Stop directions too
            print("[Speed] STOP =", speed)        # Serial: speed stop

        elif code == 0xD:                         # '#' → turbo mode
            mode = "TURBO"                        # Set mode turbo
            speed = 1023                          # Duty max
            print("[Mode] TURBO | speed =", speed)# Serial: turbo

        elif code == 0x16:                        # '*' → quiet mode
            mode = "QUIET"                        # Set mode quiet
            speed = 410                           # Duty ~40%
            print("[Mode] QUIET | speed =", speed)# Serial: quiet

        else:                                     # Unknown code
            print("[Warn] Unknown code")          # Serial: warn

        pwm5.duty(speed)                          # Apply duty left
        pwm18.duty(speed)                         # Apply duty right
    else:                                         # If no code this cycle
        print("[Wait] No IR code")                # Serial: waiting
    time.sleep_ms(250)                            # Loop delay for readability

📖 External explanation

  • What it teaches: Mapping IR codes to directions, speeds, and modes—your first full remote car controller.
  • Why it works: Direction pins choose forward/back for each motor; PWM sets speed. The IR code decides which action to run.
  • Key concept: Small hex codes (like 0x18) trigger big behaviors when mapped cleanly.

✨ Story time

Your robot just learned to drive with a TV‑style remote. Tap arrows to steer, numbers to set speed, and hash/star to change personality—turbo or quiet.


🕵️ Debugging (2)

🐞 Debugging 3.5.A – Lost commands

Problem: Pressing a button sometimes does nothing.
Clues: Serial shows “No IR code” often; actions feel delayed.

Broken code:

if ir_rx.any():
    pass  # Missing read and action; loop runs too fast without delay

Fixed code:

if ir_rx.any():                              # Check code exists
    code = ir_rx.code[0]                     # Read first buffered code
    print("[IR] Code:", hex(code))           # Log the code
    # Handle action here (direction/speed)   # Do the mapped behavior
time.sleep_ms(250)                           # Add a small delay for stability

Why it works: Reading the buffer and adding a short delay reduces missed events.
Avoid next time: Always read code[0] and keep logs compact.


🐞 Debugging 3.5.B – Slow response

Problem: Car feels sluggish after button presses.
Clues: Very large delays or too many prints clog the loop.

Broken code:

time.sleep_ms(1200)        # Delay is too large for responsive driving
print("Lots of text...")   # Excessive printing every loop

Fixed code:

time.sleep_ms(250)         # Keep delays short (150–300 ms)
print("[Move] FORWARD")    # Print single, clear status lines

Why it works: Short delays + concise logs keep the control loop snappy.
Avoid next time: Avoid long sleeps and repeated verbose prints.


✅ Final checklist

  • Up/Down/Left/Right control directions correctly
  • Numbers set speed levels (low/med/high/stop)
  • Modes (# turbo, * quiet) change behavior
  • Serial logs are clear and short
  • Motors stop safely on OK or 0

📚 Extras

  • 🧠 Student tip: Practice gentle button taps—single presses control better than holding.
  • 🧑‍🏫 Instructor tip: Verify GND is shared between D1 R32 and L298N before testing.
  • 📖 Glossary:
    • PWM (duty): How much power the motor sees (0–1023).
    • Direction pins: Choose forward/back for each motor.
    • Hex code: Base‑16 number used by the IR remote protocol.
  • 💡 Mini tips:
    • Keep IR receiver away from bright lights.
    • Align the remote to the sensor window.
    • Test directions with wheels lifted first.
On this page