Skip to content

Robot Electronics Overview

Reference Document | Understanding the Hardware You're Programming

This document explains how the Yahboom Pico Robot is built from an electronics perspective. As EE students, understanding the hardware helps you debug issues, appreciate design trade-offs, and connect software behavior to physical reality.

Full Robot Schematic (PDF) — pin-level circuit diagram of the entire robot board.


System Block Diagram

┌─────────────────────────────────────────────────────────────────────────────┐
│                         YAHBOOM PICO ROBOT                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌──────────────┐     ┌──────────────────────────────────────────────────┐ │
│  │   BATTERY    │     │              RASPBERRY PI PICO 2 W               │ │
│  │   18650      │     │  ┌─────────────────────────────────────────────┐ │ │
│  │   3.7V       │     │  │  RP2350 (Dual Cortex-M33 @ 150MHz)          │ │ │
│  │   ~2600mAh   │     │  │  520KB SRAM, 4MB Flash                      │ │ │
│  └──────┬───────┘     │  │  WiFi/BT (CYW43439)                         │ │ │
│         │             │  └─────────────────────────────────────────────┘ │ │
│         ▼             │                                                   │ │
│  ┌──────────────┐     │   GPIO ──────► Motor Driver (TB6612)             │ │
│  │  POWER MGMT  │     │   GPIO ──────► WS2812B LEDs                      │ │
│  │  3.3V + 5V   │─────│   I2C  ──────► IMU (BMI160) + OLED               │ │
│  │  regulators  │     │   ADC  ──────► Line Sensors + Battery Monitor   │ │
│  └──────────────┘     │   GPIO ──────► Ultrasonic (Trigger/Echo)         │ │
│                       │   GPIO ──────► IR Receiver                        │ │
│                       └──────────────────────────────────────────────────┘ │
│                                                                             │
│  ┌──────────────┐     ┌──────────────┐     ┌──────────────────────────┐   │
│  │  TB6612FNG   │     │  2× DC MOTOR │     │  SENSORS                 │   │
│  │  H-BRIDGE    │◄────│  w/ GEARBOX  │     │  • 5× Optocouplers (line)│   │
│  │  MOTOR DRIVER│     │  ~200 RPM    │     │  • HC-SR04 (ultrasonic)  │   │
│  └──────────────┘     └──────────────┘     │  • BMI160 (IMU)          │   │
│                                            │  • IR receiver            │   │
│                                            └──────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────┘

Power System

Battery: 18650 Li-ion Cell

Specification Value Notes
Nominal Voltage 3.7V Ranges 3.0V (empty) to 4.2V (full)
Capacity ~2600 mAh Typical for quality cells
Chemistry Li-ion Requires protection circuit
Discharge Rate 1-2C Sufficient for motors

Why 18650? - Ubiquitous, cheap, replaceable - Good energy density - Handles motor current spikes - Trade-off: Single cell = low voltage, needs boost converter

Voltage Regulation

Battery (3.0-4.2V)
       ├───► Boost Converter ───► 5V rail (motors, some sensors)
       │     (typically MT3608)
       └───► LDO Regulator ───► 3.3V rail (Pico, logic)
             (typically AMS1117-3.3)
Rail Voltage Consumers Notes
VBAT 3.0-4.2V Battery monitor ADC Raw battery
5V 5.0V Motors, HC-SR04, WS2812 Boosted from battery
3.3V 3.3V Pico, I2C devices, line sensors Regulated

Trade-offs:

Aspect This Design Alternative Trade-off
Single cell Simple, light 2S (7.4V) Lower voltage but simpler charging
Boost converter 5V for motors Buck from 2S Efficiency vs complexity
Linear 3.3V LDO Simple, low noise Switching Wastes power as heat but cleaner

Battery Monitoring

The robot monitors battery voltage via ADC:

VBAT ────┬──[R1]──┬──► GP29 (ADC)
         │        │
        [R2]     [C]
         │        │
        GND      GND

Voltage divider: V_adc = VBAT × R2/(R1+R2)
Typically: R1=10k, R2=10k → V_adc = VBAT/2

Why voltage divider? - Battery can reach 4.2V - ADC max is 3.3V - Divider scales 4.2V → 2.1V (safe for ADC)

Code connection:

import machine
adc = machine.ADC(29)
raw = adc.read_u16()
voltage = (raw / 65535) * 3.3 * 2  # ×2 for divider

What's NOT Included

This robot does NOT include: - Battery charging circuit (charge externally) - Low-voltage cutoff (protect in software!) - Fuel gauge IC (estimate from voltage only)

Production designs would add these for safety and UX.


Motor Driver: TB6612FNG

What is an H-Bridge?

An H-bridge allows bidirectional DC motor control:

       VCC                    VCC
        │                      │
    ┌───┴───┐              ┌───┴───┐
    │  Q1   │              │  Q2   │
    │ (HIGH)│              │ (LOW) │
    └───┬───┘              └───┬───┘
        │      ┌───────┐       │
        ├──────┤ MOTOR ├───────┤
        │      └───────┘       │
    ┌───┴───┐              ┌───┴───┐
    │  Q3   │              │  Q4   │
    │ (LOW) │              │ (HIGH)│
    └───┬───┘              └───┬───┘
        │                      │
       GND                    GND

Q1+Q4 ON → Current flows LEFT to RIGHT → Motor spins CW
Q2+Q3 ON → Current flows RIGHT to LEFT → Motor spins CCW

TB6612FNG Specifications

Parameter Value Notes
Channels 2 (dual H-bridge) One per motor
Voltage 4.5-13.5V (motor), 2.7-5.5V (logic) 5V motor rail
Current 1.2A continuous, 3.2A peak Per channel
PWM Frequency Up to 100 kHz We use ~1 kHz
Control IN1, IN2, PWM per channel Direction + speed

Control Logic

IN1 IN2 PWM Motor Action
0 0 X Coast (free spin)
1 0 duty Forward at duty%
0 1 duty Reverse at duty%
1 1 X Brake (short circuit)

Why TB6612 instead of L298N?

Aspect TB6612FNG L298N
Technology MOSFET Bipolar transistor
Voltage drop ~0.5V ~2V
Efficiency ~90% ~60-70%
Heat Minimal Needs heatsink
Size Small Large
Cost ~$2 ~$1

Trade-off: TB6612 is more efficient and compact, but slightly more expensive. For battery-powered robots, efficiency wins.

Pin Connections

Pico GPIO       TB6612          Motor
─────────────────────────────────────
GP12 (PWM) ───► AIN1 ──┐
GP13 (PWM) ───► AIN2 ──┴──► Motor A (Left)
                PWMA ───► (tied to IN or separate)

GP10 (PWM) ───► BIN1 ──┐
GP11 (PWM) ───► BIN2 ──┴──► Motor B (Right)
                PWMB ───► (tied to IN or separate)

                STBY ───► 3.3V (always enabled)
PWM on Direction Pins

This robot uses PWM directly on IN1/IN2 rather than separate PWM pins. - Simpler wiring (fewer GPIOs needed) - Trade-off: Can't use "fast decay" brake mode easily


Sensors

Line Sensors (5× Optocouplers)

           ┌─────────────┐
    VCC ───┤    LED      │    IR light
           │   (emit)    ├────────►
           └─────────────┘        │
                                  │ reflects off surface
           ┌─────────────┐        │
    ADC ◄──┤ Phototrans. │◄───────┘
           │  (receive)  │
           └──────┬──────┘
                 GND
Parameter Value Notes
Type Reflective IR TCRT5000 or similar
Output Analog (0-3.3V) Proportional to reflectance
Count 5 sensors Left-outer, Left, Center, Right, Right-outer
ADC Pins GP26, GP27, GP28 Only 3 ADC channels used

Why analog instead of digital? - Analog gives proportional position (how far off-center) - Digital only gives "on line" or "off line" - Trade-off: More complex code, but smoother control

Why only 3 ADC pins for 5 sensors? - RP2350 has limited ADC channels - Outer sensors may use digital threshold - Or multiplexing (not on this robot)

Ultrasonic Sensor (HC-SR04)

         ┌─────────────────────────────┐
 TRIG ──►│  Trigger pulse (10µs)       │
         │                             │
         │  ┌──────┐      ┌──────┐     │
         │  │ TX   │ )))  │  RX  │     │
         │  └──────┘      └──────┘     │
         │                             │
 ECHO ◄──│  Echo pulse (proportional)  │
         └─────────────────────────────┘

Distance = (Echo pulse width × Speed of sound) / 2
         = (pulse_us × 343 m/s) / 2
         = pulse_us × 0.0343 / 2 cm
         ≈ pulse_us / 58 cm
Parameter Value Notes
Range 2-400 cm Practical: 5-200 cm
Resolution ~3 mm Limited by timing precision
Beam angle ~15° Cone, not laser
Voltage 5V Needs level shifting for 3.3V MCU

Level Shifting Issue: - HC-SR04 ECHO is 5V - Pico GPIO is 3.3V max! - Solutions: 1. Voltage divider on ECHO (simple, used here) 2. Level shifter IC (cleaner) 3. 3.3V-compatible HC-SR04P (drop-in replacement)

HC-SR04 ECHO ──[1kΩ]──┬──► GP1 (Pico)
                    [2kΩ]
                     GND

Divider: 5V × 2k/(1k+2k) = 3.3V ✓

IMU (BMI160)

Parameter Value Notes
Type 6-axis (3-accel, 3-gyro) No magnetometer
Interface I2C (address 0x68 or 0x69) Shared bus with OLED
Gyro range ±125 to ±2000 °/s Configurable
Accel range ±2g to ±16g Configurable
Sample rate Up to 1600 Hz We use ~100 Hz

Why BMI160?

Aspect BMI160 MPU6050 Trade-off
Power Lower Higher BMI160 better for battery
Noise Lower Higher BMI160 cleaner data
Availability Good Excellent MPU6050 more common
Cost ~$3 ~$2 Slight premium

Calibration Required: - Gyro has bias (reads non-zero when stationary) - Accelerometer has offset and scale errors - Must calibrate at startup or use stored values

WS2812B (NeoPixel) LEDs

Parameter Value Notes
Count 4-8 LEDs Daisy-chained
Data pin GP6 Single wire protocol
Voltage 5V But 3.3V data usually works
Protocol 800 kHz, 24-bit GRB Timing-critical!

Why single-wire protocol? - Fewer wires in cable runs - Daisy-chain simplifies PCB - Trade-off: Timing-critical (needs PIO or careful bitbang)

Voltage Level Concern: - WS2812 spec: VIH > 0.7 × VDD = 0.7 × 5V = 3.5V - Pico output: 3.3V (below spec!) - Why it works: Most WS2812s tolerate it - Robust solution: Level shifter on data line


I2C Bus

The robot uses I2C for multiple devices on a shared bus:

      Pico                I2C Bus (GP14=SDA, GP15=SCL)
    ┌──────┐                      │
    │ GP14 ├──────────────────────┼───────┬───────┐
    │ (SDA)│                      │       │       │
    │      │                   ┌──┴──┐ ┌──┴──┐ ┌──┴──┐
    │ GP15 ├───────────────────┤ IMU │ │OLED │ │ ... │
    │ (SCL)│                   │0x68 │ │0x3C │ │     │
    └──────┘                   └─────┘ └─────┘ └─────┘
                                   │       │       │
                               ┌───┴───────┴───────┴───┐
                               │        4.7kΩ          │
                               │     Pull-up to 3.3V   │
                               └───────────────────────┘
Parameter Value Notes
Speed 400 kHz (Fast mode) Could use 100 kHz standard
Pull-ups 4.7 kΩ to 3.3V On robot PCB
Devices IMU (0x68), OLED (0x3C) Possibly more

I2C Scan (discover devices):

from machine import I2C, Pin
i2c = I2C(1, sda=Pin(14), scl=Pin(15), freq=400000)
devices = i2c.scan()
print([hex(d) for d in devices])  # ['0x3c', '0x68']

Why I2C? - Only 2 wires for multiple devices - Standardized, well-supported - Trade-off: Slower than SPI, shared bus can cause conflicts


What This Robot Has vs. Professional Solutions

Why This Matters

This is a ~€30 educational robot. Understanding what's "missing" compared to a €300 hobbyist or €3000 industrial solution teaches you: - What trade-offs engineers make for cost - When cheap solutions are "good enough" - When you NEED the professional solution

Cost Tiers in Embedded Design

┌─────────────────────────────────────────────────────────────────────────────┐
│  COST vs FEATURES SPECTRUM                                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  €30 Educational        €150 Hobbyist         €500+ Professional            │
│  (This robot)           (Quality kit)         (Industrial/Competition)      │
│                                                                             │
│  ✗ No encoders          ✓ Basic encoders      ✓ High-res encoders          │
│  ✗ No current sense     ◐ Basic current       ✓ Per-motor current          │
│  ✗ No charging IC       ✓ Onboard charging    ✓ BMS + fuel gauge           │
│  ✗ Basic IMU            ✓ Better IMU          ✓ IMU + magnetometer         │
│  ✗ Simple H-bridge      ✓ Better driver       ✓ Smart motor driver         │
│  ✗ No protection        ◐ Basic protection    ✓ Full protection            │
│                                                                             │
│  Good for: Learning     Good for: Projects    Good for: Competition/Prod   │
└─────────────────────────────────────────────────────────────────────────────┘

Detailed Trade-off Analysis

1. Motor Feedback: No Encoders

What this robot has: No motor feedback. Open-loop control only.

What's missing:

                    ┌─────────────────────────────────────────┐
   ENCODER          │  Quadrature encoder on motor shaft      │
   (missing)        │  Provides: pulses per revolution        │
                    │  Enables: closed-loop speed control     │
                    └─────────────────────────────────────────┘

Aspect This Robot With Encoders
Speed control PWM duty (hope it's right) Actual measured RPM
Straight driving Guess + IMU compensation True odometry
Position control Not possible Dead reckoning
Cost €0 +€5-15 per motor

Why it's OK for learning: - Forces you to understand open-loop limitations - IMU provides alternative (gyro-based) heading correction - Line sensors provide closed-loop feedback for line following

When you'd need encoders: - Precise distance travel ("move 50cm forward") - Competition robots (need reproducibility) - Mapping/SLAM applications

Professional alternative: Magnetic encoders (AS5048), optical encoders (E6B2)


2. Power: No Battery Management System (BMS)

What this robot has: - Single 18650 cell - Voltage divider for monitoring - External charging

What's missing:

Feature This Robot Professional BMS
Charging External charger Onboard USB-C charging
Protection None (hope battery has it) Over-charge, over-discharge, short circuit
Fuel gauge Voltage estimation only Coulomb counting (accurate %)
Cell balancing N/A (single cell) Required for multi-cell
Low-voltage cutoff Software only (if you code it!) Hardware cutoff
THIS ROBOT:                          PROFESSIONAL:

Battery ──► Boost ──► 5V             Battery ──► BMS IC ──► Boost ──► 5V
   │                                     │         │
   └──► ADC (monitor)                    │         ├── Charging circuit
                                         │         ├── Protection FETs
        (hope battery has               │         ├── Fuel gauge (I2C)
         internal protection!)           │         └── Balancing (multi-cell)
                                         └──► ADC (accurate SOC)

Why it's OK for learning: - Most 18650 cells have internal protection - Short lab sessions, not continuous operation - Easy to swap/charge batteries externally

When you'd need proper BMS: - Product that end-users charge - LiPo packs (more dangerous chemistry) - Need accurate battery percentage display - Regulatory compliance (CE, UL)

Professional components: BQ24072 (charging), BQ27441 (fuel gauge), BQ76920 (protection)


3. Motor Driver: No Current Sensing

What this robot has: TB6612 H-bridge, no feedback

What's missing:

Feature This Robot Smart Motor Driver
Current sensing None Per-motor mA reading
Stall detection Can't detect (motor burns?) Automatic shutoff
Torque control Not possible Current = torque
Diagnostics "Motor stopped, dunno why" "Motor stalled at 1.2A"
THIS ROBOT:                          PROFESSIONAL:

PWM ──► TB6612 ──► Motor             PWM ──► DRV8871 ──► Motor
        (no idea what current                   ├── Current sense (ADC)
         motor is drawing)                      ├── Fault output (GPIO)
                                                └── Thermal protection

Why it's OK for learning: - TB6612 has thermal protection (won't burn up) - Learn to recognize stall by other means (sound, heat, behavior) - Focus on control, not diagnostics

When you'd need current sensing: - Torque-limited applications (grippers) - Stall detection for safety - Efficiency optimization - Load estimation

Professional drivers: DRV8871 (current sense), TMC2209 (stepper, full diagnostics)


4. Sensors: Basic vs. Professional

Line Sensors

Aspect This Robot Professional
Type IR reflective RGB color sensor or camera
Output Analog threshold Calibrated values
Ambient rejection Poor Good (modulated IR)
Line color Black on white only Any color detection

Professional alternative: QTRX-HD series (Pololu), TCS34725 (color sensor), camera + CV

Distance Sensor

Aspect HC-SR04 (This Robot) Professional
Technology Ultrasonic ToF Laser ToF (VL53L0X)
Accuracy ±3mm ±1mm
Range 2-400cm 5-200cm (more accurate)
Speed ~60ms per reading ~30ms
Beam Wide cone (15°) Narrow beam (25°)
Cost €1 €5-10

Professional alternative: VL53L1X (laser ToF), TFmini (LiDAR), structured light

IMU

Aspect BMI160 (This Robot) Professional
Axes 6 (accel + gyro) 9 (+ magnetometer)
Heading Gyro integration (drifts) Magnetic compass (absolute)
Calibration Manual Factory calibrated
Fusion DIY in software Onboard sensor fusion (BNO055)

Professional alternative: BNO055 (9-axis + fusion), ICM-20948


5. Protection Circuits: Almost None

What this robot has: - Battery's internal protection (hopefully) - TB6612 thermal shutdown - That's about it

What's missing:

Protection This Robot Professional
Reverse polarity ❌ None P-MOSFET or ideal diode
ESD protection ❌ None TVS diodes on I/O
Overcurrent (system) ❌ None Resettable fuse (PTC)
Motor back-EMF ✓ TB6612 internal Dedicated flyback diodes
Overvoltage ❌ None Voltage clamps
PROFESSIONAL PROTECTION:

Battery ──► Reverse ──► Fuse ──► Regulator ──► Power rails
            polarity    (PTC)
            (P-FET)

GPIO ──► ESD ──► Level ──► External device
         TVS    shift

Why it's OK for learning: - Indoor lab environment (low ESD risk) - Supervised use (won't reverse polarity... hopefully) - Disposable if something breaks

When you'd need protection: - Any product with end users - Outdoor/industrial environment - Regulatory compliance - Expensive components downstream


6. Level Shifting: Marginal Design

What this robot has: - 3.3V MCU directly driving 5V-expecting devices - Voltage dividers for 5V → 3.3V inputs - "Works most of the time"

What's proper:

Signal This Robot Professional
WS2812 data 3.3V direct (out of spec!) Level shifter (74HCT125)
HC-SR04 echo Resistor divider Level shifter or 3.3V sensor
I2C Direct (OK, open drain) OK as-is
PROPER LEVEL SHIFTING:

3.3V MCU                    5V Device
    │                           │
    └──► 74HCT125 buffer ───────┘
         (3.3V in → 5V out)

         or

    └──► BSS138 bidirectional ──┘
         (for I2C, SPI)

Why the cheap way often works: - Many 5V devices actually trigger at 2.0-2.4V (TTL thresholds) - WS2812 has wide input tolerance in practice - Voltage dividers work for slow signals

When it fails: - Long cable runs (noise margin reduced) - Fast signals (divider RC time constant) - Cold temperatures (thresholds shift) - Device-to-device variation


Design Trade-offs Summary Table

System This Robot (€30) Better (€100+) Why Cheap is OK for Learning
Motor feedback None Encoders Learn open-loop limitations
Power management External charge, voltage ADC BMS + fuel gauge Simpler, swap batteries
Motor driver TB6612 (no sensing) DRV8871 + current Focus on control, not diagnostics
Line sensors IR analog RGB/camera Sufficient for basic line following
Distance HC-SR04 ultrasonic VL53L1X laser Adequate for obstacle detection
IMU 6-axis (drift) 9-axis + fusion Learn calibration, filtering
Protection Minimal Full protection Lab environment, supervised
Level shifting Marginal/none Proper shifters Usually works, learn why it shouldn't

When "Cheap" Becomes a Problem

The educational robot's limitations become real issues when:

Scenario Why Cheap Fails What You'd Need
Competition Reproducibility, reliability Encoders, current sensing
Outdoor use ESD, weather, abuse Protection circuits
Product Safety, regulations, users BMS, protection, proper design
Precision Drift, noise, tolerance Better sensors, calibration
Long runtime Battery life, efficiency Power management, sleep modes

The Engineer's Takeaway

Design is About Trade-offs

There is no "best" design. There are only designs that: - Meet requirements - Stay within budget - Ship on time

This €30 robot makes many compromises. Understanding them teaches you: 1. What can be cut for cost savings 2. What breaks when you cut too much 3. What matters for your specific application

A professional engineer doesn't always use the "best" components. They use the right components for the constraints.


Common Failure Points and Beginner Mistakes

Hardware Failures (Robot Issues)

Failure Symptom Cause Fix
Motors don't run No movement Dead battery, STBY pin low Check voltage, STBY
One motor weaker Curves constantly Motor damage, wiring Swap motors to isolate
Erratic behavior Random movements Low battery (brownout) Charge battery
I2C timeout Device not responding Wrong address, wiring I2C scan, check connections
LEDs wrong color Colors shifted GRB vs RGB confusion Check library settings
Ultrasonic reads 0 No distance 5V→3.3V divider missing Add voltage divider
IMU drift Heading creeps Gyro bias not calibrated Calibrate at startup

Typical Beginner Mistakes (Learn From Others!)

These are the mistakes almost everyone makes at least once:

1. Power Mistakes

Mistake What Happens Lesson
Reversing battery polarity Magic smoke, dead components Check twice, add protection in future designs
Powering from USB while motors run USB brownout, PC disconnect USB can't supply motor current; use battery
Ignoring voltage ratings 3.3V device on 5V → dead Always check datasheet voltage range
No decoupling capacitors Random resets, noise Add 100nF caps near power pins
Sharing power with motors MCU resets when motors start Separate power rails or big capacitors
WRONG:                           RIGHT:

USB ──┬──► Pico                  USB ──► Pico (programming only)
      └──► Motors (draws 2A!)    Battery ──► Motors + Pico
           ↑                              (adequate current)
      USB can only supply 500mA!

2. GPIO Mistakes

Mistake What Happens Lesson
Floating inputs Undefined readings (on RP2350: stuck 0 or 1 due to leakage current errata) Always use pull-up/pull-down
Forgetting to set direction Pin doesn't work Pin.OUT for output, Pin.IN for input
Shorting output to ground Excessive current, damage Never connect output directly to GND or VCC
5V into 3.3V input Damage over time Use level shifter or voltage divider
Too much current from GPIO Pin damage, weak signal GPIO max ~12mA; use transistor for more
WRONG:                           RIGHT:

GPIO ──────────► LED ──► GND     GPIO ──► Resistor ──► LED ──► GND
       ↑                                  (330Ω-1kΩ limits current)
  No resistor!
  LED may burn, GPIO stressed

3. Motor Control Mistakes

Mistake What Happens Lesson
PWM too slow Audible whine, inefficient Use 1kHz+ for DC motors
PWM too fast FETs don't fully switch Stay under 100kHz for simple drivers
Both H-bridge inputs HIGH Shoot-through (short circuit) Never set IN1=IN2=HIGH unless braking
No flyback protection Voltage spikes damage driver H-bridge ICs have this; discrete needs diodes
Starting at 100% duty Current spike, brownout Ramp up PWM gradually
WRONG:                           RIGHT:

motor.duty(100%)  # Instant!     for duty in range(0, 100, 5):
                                     motor.duty(duty)
Current spike causes                 time.sleep_ms(10)
brownout, resets MCU              # Gradual ramp, smooth start

4. I2C Mistakes

Mistake What Happens Lesson
Missing pull-ups No communication I2C needs 4.7kΩ to VCC
Wrong address Device not found I2C scan to discover addresses
SDA/SCL swapped Nothing works Double-check wiring
Multiple devices, same address Conflicts Change address or use multiplexer
Speed too high Errors, corruption Start at 100kHz, increase if stable
# ALWAYS scan first!
import machine
i2c = machine.I2C(1, sda=machine.Pin(14), scl=machine.Pin(15))
print([hex(addr) for addr in i2c.scan()])
# Expected: ['0x3c', '0x68'] for OLED + IMU

5. Sensor Mistakes

Mistake What Happens Lesson
Not calibrating Wrong readings, bad control Calibrate at startup or store values
Ignoring noise Jittery behavior Filter readings (average, median)
Blocking reads System freezes Use non-blocking or timeouts
Trusting first reading Startup garbage Discard first N samples
Wrong units Calculations off by 1000× Check: ms vs µs, cm vs mm, °/s vs rad/s
# WRONG: Trust first IMU reading
gyro_z = imu.read_gyro_z()  # Often garbage at startup!

# RIGHT: Calibrate
samples = [imu.read_gyro_z() for _ in range(100)]
gyro_bias = sum(samples) / len(samples)
# Now subtract bias from readings

6. Timing Mistakes

Mistake What Happens Lesson
Using sleep() everywhere System unresponsive Use non-blocking timing
Printing in tight loops Loop slows to ~10Hz Buffer logs, print later
Forgetting timing varies Works sometimes, fails others Measure actual timing
No timeout on blocking ops Hangs forever Always set timeouts
Microsecond precision in Python Doesn't work Python is ~500µs per operation; use hardware
# WRONG: Blocks everything
while True:
    read_sensors()
    time.sleep(0.1)  # Nothing else can happen!

# RIGHT: Non-blocking
last_read = time.ticks_ms()
while True:
    if time.ticks_diff(time.ticks_ms(), last_read) >= 100:
        last_read = time.ticks_ms()
        read_sensors()
    # Other code can run here!

7. Software/Hardware Boundary Mistakes

Mistake What Happens Lesson
Bit-banging fast protocols Protocol fails Use hardware (PIO, SPI, I2C)
Ignoring hardware limits Unexpected behavior Read the datasheet
Not checking return values Silent failures Always check for errors
Assuming instant response Race conditions Hardware takes time; add delays if needed

The "Magic Smoke" Hall of Fame

Things that permanently damage hardware:

Action Result Prevention
Reverse polarity Dead ICs instantly Protection diode, check before power
5V to 3.3V input Slow death or instant Level shifter, voltage divider
Short output to ground Burned GPIO pin Series resistor, careful wiring
Motor stall for too long Burned windings, driver Current sensing, timeout
Static discharge Random failures later Ground yourself, handle by edges
Overvoltage to motor driver Dead H-bridge Check VM max rating
The Golden Rule

When something doesn't work, check power first.

90% of "mysterious" embedded failures are: 1. Dead/low battery 2. Wrong voltage 3. Loose connection 4. Ground not connected

Check these before debugging code!


Schematic Reading Exercise

For EE Students

Practice tracing signals from the MCU to the actuator/sensor.

Exercise 1: Motor Path Starting from GP12, trace the signal path to the left motor: 1. GP12 → TB6612 AIN1 → ... 2. What determines motor direction? 3. What determines motor speed?

Exercise 2: Sensor Path Starting from a line sensor phototransistor: 1. Light reflects → phototransistor conducts → voltage at ADC pin 2. What determines the voltage range? 3. Why does black read different from white?

Exercise 3: Power Path Trace power from battery to motor: 1. Battery → boost converter → 5V rail → TB6612 VM → motor 2. What happens if battery is low? 3. Where is current limited?


Further Reading