Back to Expert Projects

🐁 Micromouse Maze Solver

The ultimate robotics challenge: autonomously map and solve a maze.

📋 Overview

Micromouse is an international robotics competition. The robot must explore an unknown 16x16 maze, map the walls, find the center, and then speedrun back using the optimal path.

What you'll learn: The Flood-Fill pathfinding algorithm, custom PCB design, high-speed encoder odometry, and IR wall detection.

Estimated time: 20+ hours. Difficulty: ⭐⭐⭐⭐⭐ Expert.

🧩 Components Needed

ComponentSpecificationQtyNotes
Custom PCB1Essential for compact size
Micro Metal GearmotorsWith Encoders2High speed (e.g. 1000 RPM)
STM32 / TeensyFast MCU1Arduino Uno lacks memory for 16x16 maze
IR Emitter/Receiver pairsSide & Front6For wall detection
IMUMPU60501For perfectly straight 90-degree turns

📖 Step-by-Step Tutorial

1

Odometry

You must know exactly where the mouse is. Use the motor encoders to measure distance, and the IMU gyro to track heading. If you tell it to move exactly 18cm (one cell), it must not drift.
2

Wall Sensors

Use IR LEDs and phototransistors pointing diagonally and forward. Calibrate them so the mouse can perfectly center itself between two walls.
3

Flood-Fill Algorithm

Represent the maze as a 2D array. The algorithm assigns a "distance to center" value to every cell. As the mouse discovers walls, it updates the values and moves to the cell with the lowest number.
4

Speed Run

Once the center is found and the path is mapped, calculate the optimal trajectory (cutting corners diagonally if possible) and increase motor PID limits for the speed run.
💡
Do not use an Arduino Uno for a full Micromouse. The 16x16 maze array, flood-fill recursion, and fast float math for PID will quickly exceed the 2KB SRAM and processing power of the ATmega328P.

💻 Code / Configuration

micromouse.ino
INO
// Micromouse Flood Fill (Conceptual Logic)
const int MAZE_SIZE = 16;
int distances[MAZE_SIZE][MAZE_SIZE];
bool vertWalls[MAZE_SIZE][MAZE_SIZE+1];
bool horizWalls[MAZE_SIZE+1][MAZE_SIZE];

void floodFill(int targetX, int targetY) {
  // 1. Initialize all distances to 255
  // 2. Set target cell distance to 0
  // 3. Push target to queue
  // 4. While queue is not empty:
  //    a. Pop cell
  //    b. For each neighbor (N, S, E, W):
  //       If there is NO wall between cell and neighbor,
  //       and neighbor.distance > cell.distance + 1:
  //         neighbor.distance = cell.distance + 1
  //         push neighbor to queue
}

void loop() {
  // 1. Read IR sensors to update wall arrays
  updateWalls(currentX, currentY, currentHeading);
  
  // 2. Recalculate distances to the center
  floodFill(8, 8);

Reviews & Ratings

0 reviews
5★
0
4★
0
3★
0
2★
0
1★
0
...

Loading reviews...