Program Arduino IDE untuk robot Differential Drive Mobile Robot (DDMR) menggunakan ESP32 dengan sistem operasi real-time FreeRTOS. Program ini mengimplementasikan sistem odometri yang akurat dan navigasi dasar untuk robot beroda dua.
- Gambaran Umum
- Spesifikasi Hardware
- Arsitektur Sistem
- Instalasi dan Setup
- Konfigurasi Pin
- Algoritma Odometri
- Sistem Navigasi
- Perintah yang Tersedia
- Kalibrasi
- Troubleshooting
Program ini dirancang untuk robot DDMR (Differential Drive Mobile Robot) dengan fitur:
- Dual Core Processing: Core 0 untuk odometri dan navigasi, Core 1 untuk LED indicator
- Real-Time Odometry: Tracking posisi dan orientasi robot dengan presisi tinggi
- Navigation Functions: Fungsi maju dan belok dengan kontrol jarak dan sudut
- Thread-Safe: Menggunakan mutex untuk proteksi data yang dibagi antar task
- Motor: JGA25-370 dengan encoder 2 fase (quadrature)
- Gear Ratio: 298:1 (dapat disesuaikan sesuai varian motor)
- Encoder Raw PPR: 11 pulses per revolution (sebelum gearbox)
- Effective PPR: 3,278 pulses per revolution roda (11 Γ 298)
- Diameter: 65mm
- Circumference: 204.2mm (Ο Γ 65mm)
- Resolusi Odometri: ~62 mikrometer per pulse
- IC: TB6612FNG Dual Motor Driver
- Voltage: 2.5V - 13.5V (motor supply)
- Current: Hingga 1.2A per channel (3.2A peak)
- Logic Voltage: 3.3V (kompatibel dengan ESP32)
- Board: ESP32 (dual-core Xtensa LX6)
- Core 0: Sistem odometri dan navigasi
- Core 1: LED blink dan task sekunder
- Prioritas: 2 (tinggi)
- Frekuensi: 50Hz (update setiap 20ms)
- Fungsi:
- Membaca encoder counts
- Menghitung odometri menggunakan kinematika differential drive
- Update posisi robot (X, Y, ΞΈ)
- Menampilkan pose robot setiap detik
- Prioritas: 1 (rendah)
- Frekuensi: 1Hz (blink setiap 500ms)
- Fungsi:
- Blink LED D2 sebagai indikator sistem aktif
- Left Encoder ISR: Menghitung pulses encoder kiri
- Right Encoder ISR: Menghitung pulses encoder kanan
- Quadrature Decoding: Menentukan arah rotasi berdasarkan fase A dan B
Pin ESP32 | TB6612FNG | Fungsi
-----------|-----------|------------------
25 | PWMA | PWM Motor Kiri
26 | AIN1 | Direction 1 Motor Kiri
27 | AIN2 | Direction 2 Motor Kiri
32 | PWMB | PWM Motor Kanan
33 | BIN1 | Direction 1 Motor Kanan
14 | BIN2 | Direction 2 Motor Kanan
12 | STBY | Standby (Enable Driver)
Pin ESP32 | Encoder | Fungsi
-----------|-----------|------------------
18 | Left A | Fase A Encoder Kiri
19 | Left B | Fase B Encoder Kiri
21 | Right A | Fase A Encoder Kanan
22 | Right B | Fase B Encoder Kanan
Pin ESP32 | Fungsi
-----------|------------------
2 | LED Built-in (D2)
Program menggunakan kinematika differential drive untuk menghitung posisi dan orientasi robot berdasarkan rotasi kedua roda.
left_distance = (ΞLeft_pulses Γ wheel_circumference) / effective_PPR
right_distance = (ΞRight_pulses Γ wheel_circumference) / effective_PPR
Ξdistance = (left_distance + right_distance) / 2
ΞΞΈ = (right_distance - left_distance) / wheelbase
ΞΈ_new = ΞΈ_old + ΞΞΈ
ΞΈ_avg = (ΞΈ_old + ΞΈ_new) / 2
X_new = X_old + Ξdistance Γ cos(ΞΈ_avg)
Y_new = Y_old + Ξdistance Γ sin(ΞΈ_avg)
- Average Heading: Menggunakan rata-rata sudut untuk update posisi yang lebih akurat
- Angle Normalization: Sudut selalu dinormalisasi ke range [-Ο, Ο]
- High Resolution: Resolusi ~62 mikrometer dengan gear ratio 298:1
- Thread-Safe: Mutex protection untuk akses data pose yang aman
maju(1.5); // Maju 1.5 meterAlgoritma:
- Hitung jarak euclidean dari posisi start
- Proportional control: kecepatan berkurang saat mendekati target
- Stop otomatis saat mencapai jarak target
belok(90); // Belok kiri 90Β°
belok(-45); // Belok kanan 45Β°Algoritma:
- Konversi derajat ke radian
- Handle angle wrap-around untuk rotasi yang efisien
- Proportional control: kecepatan putar berkurang mendekati target
- Toleransi Β±3Β° untuk presisi yang baik
- Arduino IDE 1.8.19 atau lebih baru
- ESP32 Board Package
- Library yang diperlukan sudah built-in (FreeRTOS, Math)
-
Install ESP32 Board Package:
- Buka Arduino IDE
- File β Preferences
- Tambahkan URL:
https://dl.espressif.com/dl/package_esp32_index.json - Tools β Board β Boards Manager
- Cari "ESP32" dan install
-
Upload Program:
- Buka file
esp32_ddmr_odometry.ino - Pilih Board: "ESP32 Dev Module"
- Pilih Port yang sesuai
- Upload program
- Buka file
-
Setup Hardware:
- Hubungkan motor driver TB6612FNG sesuai skema pin
- Hubungkan encoder ke pin interrupt ESP32
- Pastikan power supply memadai (5V untuk motor, 3.3V untuk logic)
ESP32 TB6612FNG Motor/Encoder
------ ---------- -------------
3.3V βββββββ VCC
GND βββββββ GND
25 βββββββ PWMA
26 βββββββ AIN1
27 βββββββ AIN2 βββββββ Motor Kiri (+/-)
32 βββββββ PWMB
33 βββββββ BIN1
14 βββββββ BIN2 βββββββ Motor Kanan (+/-)
12 βββββββ STBY
18 βββββββββββββββββββββββ Encoder Kiri A
19 βββββββββββββββββββββββ Encoder Kiri B
21 βββββββββββββββββββββββ Encoder Kanan A
22 βββββββββββββββββββββββ Encoder Kanan B
VM (Motor Power) βββββ 6V-12V Supply
Buka Serial Monitor (115200 baud) dan gunakan perintah berikut:
maju 2.5 # Maju 2.5 meter
belok 90 # Belok kiri 90Β°
belok -180 # Belok kanan 180Β°
stop # Stop motor segera
reset # Reset posisi ke (0,0,0Β°)
info # Tampilkan konfigurasi dan status robot
ESP32 DDMR Robot with FreeRTOS Starting...
Odometry task started on Core 0
LED task started on Core 1
Setup completed. Robot ready!
Motor Configuration:
- Wheel diameter: 65mm
- Gear ratio: 298:1
- Effective PPR: 3278
Available commands:
- 'maju <jarak_meter>' : Move forward
- 'belok <derajat>' : Turn (positive = left, negative = right)
- 'stop' : Stop motors
- 'reset' : Reset pose to origin
- 'info' : Show robot configuration
Pose - X: 0.000m, Y: 0.000m, Theta: 0.0Β°
Jika hasil gerakan tidak akurat:
#define GEAR_RATIO 298 // Sesuaikan dengan motor AndaCara test:
- Reset pose:
reset - Maju 1 meter:
maju 1.0 - Ukur jarak aktual dengan penggaris
- Adjust gear ratio jika perlu
Untuk akurasi belokan:
#define WHEELBASE 0.15 // Jarak antar roda dalam meterCara test:
- Reset pose:
reset - Belok 360Β°:
belok 360 - Robot harus kembali ke orientasi awal
- Adjust wheelbase jika ada drift
Jika robot bergerak mundur saat perintah maju:
- Tukar kabel motor atau
- Inverse logika di ISR encoder
Gear Ratio: 298:1
Raw Encoder PPR: 11
Effective PPR: 3,278
Wheel Circumference: 204.2mm
Distance per Pulse: 62.3 ΞΌm
Angular Resolution: 0.11Β° (untuk wheelbase 150mm)
Odometry Update Rate: 50Hz (20ms interval)
Position Accuracy: Β±0.1mm (ideal conditions)
Angular Accuracy: Β±0.1Β° (ideal conditions)
Response Time: <20ms
Memory Usage: ~6KB RAM
Program menggunakan mutex (poseMutex) untuk melindungi data pose robot yang diakses oleh multiple tasks:
if (xSemaphoreTake(poseMutex, portMAX_DELAY) == pdTRUE) {
// Akses aman ke robotPose
robotPose.x += deltaX;
robotPose.y += deltaY;
robotPose.theta += deltaTheta;
xSemaphoreGive(poseMutex);
}Encoder menggunakan hardware interrupt untuk capture setiap pulse:
void IRAM_ATTR leftEncoderISR() {
if (digitalRead(ENCODER_LEFT_A) == digitalRead(ENCODER_LEFT_B)) {
leftEncoderCount++; // Forward rotation
} else {
leftEncoderCount--; // Backward rotation
}
}Update posisi menggunakan average heading method untuk akurasi tinggi:
double avgTheta = (robotPose.theta + newTheta) / 2.0;
robotPose.x += deltaDistance * cos(avgTheta);
robotPose.y += deltaDistance * sin(avgTheta);Sistem navigasi menggunakan proportional controller sederhana:
// Untuk gerakan maju
if (remainingDistance < 0.1) {
speed = (int)(speed * (remainingDistance / 0.1));
speed = max(speed, 50); // Minimum speed
}
// Untuk gerakan belok
if (abs(remainingAngle) < 0.2) {
turnSpeed = (int)(turnSpeed * (abs(remainingAngle) / 0.2));
turnSpeed = max(turnSpeed, 30); // Minimum turn speed
}struct RobotPose {
double x; // Posisi X dalam meter
double y; // Posisi Y dalam meter
double theta; // Orientasi dalam radian
};volatile bool navigationActive = false; // Flag navigasi aktif
volatile double targetDistance = 0.0; // Target jarak (meter)
volatile double targetAngle = 0.0; // Target sudut (radian)
volatile bool moveForward = false; // Flag gerakan maju
volatile bool turnRobot = false; // Flag gerakan belok- Odometry Task: Priority 2, 50Hz update rate
- LED Task: Priority 1, 1Hz blink rate
- Main Loop: Handle serial commands, 10Hz polling
- Encoder ISR: <1ΞΌs execution time (IRAM)
- Odometry Update: <1ms per cycle
- Navigation Control: 10ms update interval
- Serial Processing: 100ms polling interval
-
Linear Movement Test:
reset maju 1.0 info # Check if X β 1.0m, Y β 0.0m -
Rotation Test:
reset belok 90 info # Check if ΞΈ β 90Β° -
Square Pattern Test:
reset maju 1.0 belok 90 maju 1.0 belok 90 maju 1.0 belok 90 maju 1.0 belok 90 info # Should return close to origin
- Linear accuracy: Β±1cm untuk jarak 1-5 meter
- Angular accuracy: Β±2Β° untuk rotasi 90-360Β°
- Repeatability: Β±0.5cm untuk gerakan yang sama
Untuk motor JGA25 varian lain:
// Varian umum JGA25-370:
#define GEAR_RATIO 120 // Untuk JGA25-370 (120:1)
#define GEAR_RATIO 298 // Untuk JGA25-370 (298:1) - default
#define GEAR_RATIO 495 // Untuk JGA25-370 (495:1)
#define GEAR_RATIO 1000 // Untuk JGA25-370 (1000:1)Sesuaikan dengan jarak fisik antar roda:
#define WHEELBASE 0.20 // 20cm wheelbase
#define WHEELBASE 0.15 // 15cm wheelbase - defaultAdjust kecepatan di fungsi navigasi:
int speed = 150; // Base speed (0-255)
int turnSpeed = 100; // Turn speed (0-255)Penyebab: Arah motor atau encoder terbalik Solusi:
- Tukar kabel motor (+/-), atau
- Inverse logika di ISR encoder, atau
- Tukar pin AIN1-AIN2 atau BIN1-BIN2
Penyebab: Parameter fisik tidak sesuai Solusi:
- Verifikasi gear ratio motor
- Ukur diameter roda yang sebenarnya
- Ukur wheelbase dengan presisi
- Cek koneksi encoder
Penyebab: Driver tidak enable atau koneksi salah Solusi:
- Cek pin STBY terhubung ke pin 12
- Pastikan power supply motor memadai (6-12V)
- Cek koneksi PWM dan direction pins
Penyebab: Interrupt tidak bekerja atau koneksi encoder Solusi:
- Cek koneksi encoder A dan B
- Pastikan menggunakan pin interrupt-capable
- Periksa power supply encoder (biasanya 3.3V atau 5V)
Penyebab: Stack overflow atau priority conflict
Solusi:
- Increase stack size di
xTaskCreatePinnedToCore - Adjust task priority
- Monitor free heap memory
- Tuning PID: Implement PID controller untuk kontrol motor yang lebih smooth
- Kalman Filter: Tambahkan sensor IMU dan gunakan Kalman filter untuk sensor fusion
- Path Planning: Implement algoritma path planning untuk navigasi yang lebih complex
info # Tampilkan semua parameter dan status
Output akan menampilkan:
- Konfigurasi motor dan gearbox
- Resolusi sistem
- Posisi dan orientasi saat ini
- Nilai encoder real-time
- Selalu
resetpose sebelum test navigasi - Test gerakan kecil dahulu sebelum jarak jauh
- Monitor serial output untuk debug
- Pastikan surface yang rata untuk akurasi maksimal
- Slip roda: Dapat menyebabkan error akumulatif
- Backlash gearbox: Error kecil saat perubahan arah
- Quantization error: Terbatas oleh resolusi encoder
- Timing jitter: Variasi timing ISR dapat mempengaruhi akurasi
- Gunakan roda dengan grip baik
- Kalibrasi parameter secara berkala
- Implement sensor fusion dengan IMU
- Use higher resolution encoders jika diperlukan
Program ini dibuat untuk tujuan edukatif dan penelitian. Silakan gunakan dan modifikasi sesuai kebutuhan.
Untuk improvement atau bug report, silakan buat issue atau pull request di repository ini.
Dibuat dengan β€οΈ untuk komunitas robotika Indonesia @mochshultan at trkb unair