A complete odometry system for ESP32 with N20 motors and encoders, featuring real-time position tracking, motor control, and a web-based dashboard for your phone.
- Real-time Odometry: 100Hz position and velocity tracking
- Motor Control: PID-controlled N20 motors with encoder feedback
- Web Dashboard: Beautiful mobile-friendly interface accessible from your phone
- WiFi Communication: ESP32 creates its own WiFi network
- Encoder Calibration: Built-in calibration tools for accurate measurements
- Multi-threaded: Separate tasks for odometry and communication
- ESP32 Development Board
- 2x N20 Motors with Encoders (typically 6V, 12 CPR)
- Motor Driver (L298N, TB6612FNG, or DRV8833)
- Wheels (65mm diameter recommended)
- Chassis with ~200mm wheelbase
- Battery (6-12V depending on motors)
Left Motor:
- IN1: GPIO 25
- IN2: GPIO 26
- PWM: GPIO 27
Right Motor:
- IN1: GPIO 32
- IN2: GPIO 33
- PWM: GPIO 14
Left Encoder:
- A: GPIO 18
- B: GPIO 19
Right Encoder:
- A: GPIO 16
- B: GPIO 17
# Using PlatformIO (recommended)
pio run
# Or using Arduino IDE
# Install these libraries:
# - WiFiManager
# - ArduinoJson
# - ESPAsyncWebServer
# - AsyncTCP
# - ESP32TimerInterrupt
# - PID_v1Edit src/Config.h to match your hardware:
#define WHEELBASE_MM 200 // Distance between wheels
#define WHEEL_DIAMETER_MM 65 // Wheel diameter
#define ENCODER_CPR 12 // Encoder counts per revolutionpio run --target upload- Power on the ESP32
- Look for WiFi network:
ESP32_Odometry - Connect with password:
12345678 - Open browser and go to:
192.168.4.1
The system provides a beautiful web interface accessible from any device:
- Real-time Position Display: Live X, Y coordinates and heading
- Velocity Monitoring: Linear and angular velocity in real-time
- Position Visualization: Canvas showing robot movement path
- Control Panel: Manual movement commands and system controls
- Mobile Optimized: Works perfectly on phones and tablets
- Open Serial Monitor (115200 baud)
- Send command:
CALIBRATE - Rotate wheel exactly 1 revolution
- Press any key when complete
- System calculates
distance_per_count
// In Config.h, update these values after calibration:
#define LEFT_DISTANCE_PER_COUNT 0.017 // mm per encoder count
#define RIGHT_DISTANCE_PER_COUNT 0.017 // mm per encoder countThe system uses differential drive odometry:
Linear Velocity = (left_distance + right_distance) / (2 ร dt)
Angular Velocity = (right_distance - left_distance) / (wheelbase ร dt)
Position Update:
X += linear_velocity ร cos(heading) ร dt
Y += linear_velocity ร sin(heading) ร dt
Heading += angular_velocity ร dt
- Reset: Reset odometry to origin
- Calibrate: Start encoder calibration
- Move Forward 100mm: Move robot forward 100mm
- Turn 90ยฐ: Rotate robot 90 degrees
RESET - Reset odometry
CALIBRATE - Start calibration
MOVE:FORWARD:100 - Move forward 100mm
MOVE:TURN:90 - Turn 90 degrees
Default PID values are conservative. Tune for your specific robot:
// In Config.h
#define MOTOR_KP 2.0 // Proportional gain
#define MOTOR_KI 0.1 // Integral gain
#define MOTOR_KD 0.05 // Derivative gainTuning Process:
- Start with P only, increase until oscillation
- Add D to reduce oscillation
- Add I to eliminate steady-state error
- Fine-tune for smooth operation
Motors not moving:
- Check motor driver connections
- Verify PWM pins are correct
- Check battery voltage
Encoders not reading:
- Verify encoder pin connections
- Check for loose connections
- Ensure proper pull-up resistors
WiFi not connecting:
- Check SSID and password in code
- Ensure ESP32 has enough power
- Try resetting ESP32
Inaccurate odometry:
- Recalibrate encoders
- Check wheel diameter and wheelbase
- Verify encoder CPR value
Enable debug output in Config.h:
#define DEBUG_ENCODER true
#define DEBUG_MOTOR true
#define DEBUG_ODOMETRY true
#define DEBUG_COMMUNICATION true- Odometry Update Rate: 100Hz (10ms intervals)
- Communication Rate: 20Hz (50ms intervals)
- Position Accuracy: ยฑ2-5mm (depends on calibration)
- WiFi Range: ~10-20m (indoor)
// Add to main.cpp
void customMovement() {
// Move in a square pattern
odometry.moveForward(100);
odometry.turn(PI/2);
odometry.moveForward(100);
odometry.turn(PI/2);
// ... continue pattern
}// Log odometry data to SD card or cloud
void logData() {
String data = String(odometry.getX()) + "," +
String(odometry.getY()) + "," +
String(odometry.getHeading());
// Save to storage
}Feel free to contribute improvements:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
This project is open source. Feel free to use and modify for your projects.
If you encounter issues:
- Check the troubleshooting section
- Review Serial Monitor output
- Verify hardware connections
- Check configuration values
Happy Building! ๐คโจ
Your ESP32 odometry system is now ready to track position and provide real-time feedback to your phone!