Autonomous wall-following robot — register-level ESP32 firmware
An ESP32-based autonomous robot that follows walls inside a corridor track, detects and classifies 90° turns, and reports results over WiFi TCP — all using register-level C with zero high-level Arduino APIs.
- 11-state FSM for wall following, approach, turn execution, gyro correction, and dead-end detection
- PID steering with configurable wall-lock modes (left, right, dual)
- Encoder + gyro turn verification — optical encoders trigger the stop, MPU-6050 gyroscope verifies the angle
- WiFi telemetry — ESP32 runs as an access point with a TCP server; a Python client receives live turn data
- Register-level GPIO — direct
REG_WRITE/REG_READfor minimal latency, nodigitalWrite/digitalRead
├── wallcar_autonomous/ # Arduino sketch (ESP32)
│ ├── wallcar_autonomous.ino # Entry point — setup() + loop()
│ ├── config.h # Pins, tuning constants, FSM states
│ ├── drivers.h / .cpp # GPIO, PWM, I2C, ultrasonics, MPU-6050, encoders, motors
│ ├── comms.h / .cpp # WiFi AP + TCP server
│ └── controller.h / .cpp # PID controller + FSM dispatch
├── client/
│ └── wallcar_client.py # Python TCP client for live monitoring
├── docs/
│ ├── WIRING.md # Full ESP32 pin map
│ └── TUNING.md # PID and turn calibration guide
└── assets/
└── hero_banner.png
stateDiagram-v2
[*] --> IDLE
IDLE --> WALL_FOLLOW : TCP connected + startup delay
IDLE --> TURN_STOP : front wall at start
WALL_FOLLOW --> APPROACH : front < 45cm
APPROACH --> TURN_STOP : front < 25cm
TURN_STOP --> WALL_FOLLOW : front cleared (false alarm)
TURN_STOP --> VERIFY_DEAD_END : both side walls present
TURN_STOP --> TURN_SPIN : side open → spin toward it
TURN_SPIN --> TURN_STABILIZE : encoder target hit or timeout
TURN_STABILIZE --> TURN_CORRECT : wheels stopped
TURN_CORRECT --> TURN_CORRECT_WAIT : gyro error > 5°
TURN_CORRECT --> POST_TURN : gyro OK
TURN_CORRECT_WAIT --> POST_TURN : correction burst done
POST_TURN --> WALL_FOLLOW : both walls found
POST_TURN --> APPROACH : front wall close
VERIFY_DEAD_END --> TURN_STOP : side wall disappeared
VERIFY_DEAD_END --> TRACK_COMPLETE : front < 10cm or timeout
TRACK_COMPLETE --> [*]
| Component | Part | Qty |
|---|---|---|
| Microcontroller | ESP32 DevKit V1 | 1 |
| Ultrasonic sensors | HC-SR04 | 3 |
| Motor driver | L298N | 1 |
| DC motors | With optical encoders | 2 |
| IMU | MPU-6050 | 1 |
Full wiring table → docs/WIRING.md
Open wallcar_autonomous/ in Arduino IDE (or PlatformIO). Select board ESP32 Dev Module. Upload.
WiFi SSID: WallCar_AP
Password: wallcar123
python3 client/wallcar_client.pyThe robot starts autonomously when a TCP client connects. Turn data streams in real time:
[14:32:01] CONNECTED — Starting!
[14:32:03] TURNING RIGHT...
[14:32:03] TURN #1: R
[14:32:05] TURNING LEFT...
[14:32:05] TURN #2: L
[14:32:08] ======================
[14:32:08] Turns: 2
[14:32:08] Sequence: R, L
[14:32:08] ======================
Send r to reset the robot. Send q to quit.
All tuning constants live in config.h. See docs/TUNING.md for a step-by-step calibration guide covering PID gains, turn encoder targets, speed constants, and distance thresholds.
graph LR
subgraph Sensors
US_F[HC-SR04 Front]
US_L[HC-SR04 Left]
US_R[HC-SR04 Right]
ENC[Optical Encoders]
IMU[MPU-6050]
end
subgraph ESP32
DRV[drivers.cpp]
CTRL[controller.cpp]
COM[comms.cpp]
end
subgraph Output
MOT[L298N Motors]
PC[PC Client]
end
US_F --> DRV
US_L --> DRV
US_R --> DRV
ENC --> DRV
IMU --> DRV
DRV --> CTRL
CTRL --> MOT
CTRL --> COM
COM --> PC
MIT