This project is a low-cost differential-drive robot platform built for students learning mechatronics and embedded programming. It combines practical robot assembly with staged MicroPython challenges, from basic wall-following PID to competition-style rescue behavior.
- Web Simulator: https://tempehs.github.io/AIDriver_MicroPython_Challanges/
- MicroPython Lab: https://lab-micropython.arduino.cc/
All parts are available from common suppliers (for example, AliExpress), with chassis parts made by laser cutting and 3D printing.
- Laser-cut chassis file and 3 mm plywood
- 3D-printed components (see manufacturing_files)
- RP2040 Uno development board
- Seeed Grove Base Shield V2.0 (UNO form factor)
- 2x Seeed Grove Ultrasonic Ranger (front and side, default distance backend)
- 2x VL53L0X ToF distance sensors (optional alternative distance backend)
- Seeed Grove LSM6DS3 6-axis accelerometer + gyroscope
- Omni wheel
- L298N(H) motor shield
- 4x Seeed Grove 4-pin cables
- 2x TT tyres
- 2x TT DC geared motors
- 5.5x2.1 mm barrel jack
- 6x AA battery holder with switch
- 6x AA batteries
Note
This build uses Grove sensors on a Grove Base Shield. The default classroom path uses Grove ultrasonic sensors for front/side distance and an LSM6DS3 for closed-loop gyro turns.
Distance backend choice is simple: use 2x Ultrasonic sensors OR 2x ToF sensors.
Default GPIO map used by AIDriver (all pin numbers are RP2040 GP values).
| Function | Pin |
|---|---|
| Right motor PWM/speed | GP3 |
| Right motor direction | GP12 |
| Right motor brake | GP9 |
| Left motor PWM/speed | GP11 |
| Left motor direction | GP13 |
| Left motor brake | GP8 |
| Mode | Front Sensor Pins | Side Sensor Pins | Notes |
|---|---|---|---|
| Ultrasonic (Grove default) | GP6 SIG | GP4 SIG | Single-wire Grove interface |
| ToF (VL53L0X) | GP29 SDA, GP28 SCL | GP6 SDA, GP5 SCL | Separate SoftI2C buses; both sensors use address 0x29 |
Note
In ToF mode, the front and side VL53L0X sensors are on separate SoftI2C buses, so both can use 0x29 without an address conflict.
The front ToF bus was moved from GP26/GP27 (Uno A0/A1) to GP28/GP29 (Uno A2/A3) because A0/A1 are physically wired to the Arduino Motor Shield's current-sensing outputs (see Pin Summary below). Bit-banging SoftI2C on those pins fought with the shield's analog current-sense lines and caused unreliable ToF readings. Do not reuse A0/A1 (GP26/GP27) for anything else — pick free pins instead.
| Device | Interface | Pins | I2C Address |
|---|---|---|---|
| LSM6DS3 gyroscope | SoftI2C | SDA GP16, SCL GP17 | 0x6A |
| TCS34725 color sensor | SoftI2C + INT | SDA GP16, SCL GP17, INT GP7 | 0x29 |
| SSD1306 OLED display | SoftI2C | SDA GP16, SCL GP17 | 0x3C |
| Rescue-kit servo (optional) | PWM | Unassigned by default | - |
| Function | Pin |
|---|---|
| Firmware recovery/reset | GP2 -> GND during boot |
| Onboard status LED | GP25 |
Note
GP16 and GP17 form one shared bit-banged SoftI2C bus for the gyro (0x6A), color sensor (0x29), and OLED (0x3C). GP7 is used for the color sensor interrupt line.
The controller board is an RP2040 chip on an Uno form-factor board, so every pin has both a MicroPython machine.Pin GPIO number and a silkscreened Uno header name (D0-D13, A0-A5). Dn maps directly to GPn. Only 4 GPIOs on the RP2040 are ADC-capable, so the Uno analog header only exposes 4 real analog pins: A0=GP26, A1=GP27, A2=GP28, A3=GP29. A4/A5 are not wired to RP2040 ADC pins.
The Arduino Motor Shield (L298N) is a fixed-function shield: it hardwires the pins below to its H-bridge and current-sense circuitry whether or not the code reads them. This table lists every pin the shield uses, including the A0/A1 current-sense lines that previously conflicted with the front ToF SoftI2C bus.
| Uno Pin | GPIO | Motor Shield Function | Used By AIDriver |
|---|---|---|---|
| D3 | GP3 | PWM Channel A (speed) | Right motor speed |
| D8 | GP8 | Brake Channel B | Left motor brake |
| D9 | GP9 | Brake Channel A | Right motor brake |
| D11 | GP11 | PWM Channel B (speed) | Left motor speed |
| D12 | GP12 | Direction Channel A | Right motor direction |
| D13 | GP13 | Direction Channel B | Left motor direction |
| A0 | GP26 | Current sense Channel A | Free — do not reuse for I2C/SoftI2C |
| A1 | GP27 | Current sense Channel B | Free — do not reuse for I2C/SoftI2C |
Warning
A0 (GP26) and A1 (GP27) are physically connected to the Motor Shield's analog current-sense outputs. Even though AIDriver never reads them, bit-banging SoftI2C (or anything else) on these two pins caused unreliable readings for the front ToF sensor. This is why the front ToF SoftI2C bus was moved to A2/A3 (GP28/GP29). Avoid A0/A1 for any new sensor wiring.
All other pins used by this project (Grove ultrasonic, ToF, IMU, color sensor, OLED, status LED, recovery pin) sit outside the Uno D0-D13/A0-A5 header and are only available via this board's extra GPIO breakout:
| Function | GPIO | Uno Header Equivalent |
|---|---|---|
| Front ultrasonic SIG | GP6 | D6 |
| Front ultrasonic ECHO (legacy) | GP7 | D7 |
| Side ultrasonic SIG | GP4 | D4 |
| Side ultrasonic ECHO (legacy) | GP5 | D5 |
| Front ToF SoftI2C SDA | GP29 | A3 |
| Front ToF SoftI2C SCL | GP28 | A2 |
| Side ToF SoftI2C SDA | GP6 | D6 |
| Side ToF SoftI2C SCL | GP5 | D5 |
| IMU/color/OLED SoftI2C SDA | GP16 | none (extra breakout) |
| IMU/color/OLED SoftI2C SCL | GP17 | none (extra breakout) |
| Color sensor interrupt | GP7 | D7 |
| Firmware recovery/reset | GP2 | D2 |
| Onboard status LED | GP25 | none (extra breakout) |
Note
TempeHS senior software engineering students may have already completed these steps.
See Assembly_Instructions.md for full assembly and hardware test steps.
The build system produces firmware with AIDriver libraries frozen for fast import while keeping main.py on the device filesystem for easy IDE editing.
Quick build:
cd /workspaces/AIDriver_MicroPython_Challanges/.devcontainer
./build_firmware.shRecovery mode:
- If
main.pyis corrupted, hold GPIO2 low (connect GP2 to GND) during boot. - Recovery restores default
main.pyand clearsevent_log.txt.
Full guide: Build_Custom_MicroPython_Firmware.md
- Set
aidriver.DEBUG_AIDRIVER = Trueinmain.pyfor richer runtime logs. - The firmware creates a run-scoped
event_log.txtnext tomain.py. - In recovery mode (GPIO2 held low at boot), both
main.pyandevent_log.txtare reset to defaults.
Students complete challenge stages in order, carrying code forward each time.
Stage 1: PID wall following
- Challenge_1.md - P control
- Challenge_2.md - PD control
- Challenge_3.md - Full PID
Stage 2: State-machine maze solving
- Challenge_4.md - Corner detection and first state machine
- Challenge_5.md - Outside corners (nib state)
- Challenge_6.md - Dead ends and nibs in one machine
- Challenge_7.md - Full maze capstone
Stage 3: Rescue sensors and competition behavior
- Challenge_8.md - Ground color detection
- Challenge_9.md - No-go zones and recovery
- Challenge_10.md - Competition run, victims, score, OLED
Use the web simulator to test before uploading to hardware: https://tempehs.github.io/AIDriver_MicroPython_Challanges/
- Rescue_Maze_Rules_Summary.md: plain-language guide to the RoboCup Junior Australia Rescue Maze rules.
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).


