Skip to content

Repository files navigation

EnglishРусский

🤖 ESP32 Self-Balancing Robot

Anton Petnitsky

Автономный робот-балансир на двух колёсах с линией, препятствиями и управлением через веб-интерфейс.

📁 Файлы проекта

Основные скетчи:

  • esp32_robot_monolith/esp32_robot_monolith.ino - основная программа робота
  • web_interface.html - веб-интерфейс с джойстиком

Тестовые скетчи:

  • test_line_sensor.ino - тест датчика линии (5 датчиков)
  • test_distance_sensor.ino - тест датчика расстояния (VL53L0X)
  • test_motors.ino - тест моторов (скорость и синхронизация)
  • test_servo_gripper.ino - тест сервомоторов захвата (две серво)
  • test_gyro.ino - тест гироскопа/акселерометра (MPU6050)

Код:

  • Вся логика робота собрана в монолите esp32_robot_monolith/esp32_robot_monolith.ino (WiFi, веб-интерфейс, сенсоры, моторы, манипулятор)
  • Веб-интерфейс: main/web_interface.html

⚡ Быстрый старт

1. Редактировать WiFi

В esp32_robot_monolith.ino:

String sta_ssid = "YourWiFiSSID";
String sta_password = "YourWiFiPassword";

2. Загрузить в Arduino IDE

Библиотеки нужны:

  • AsyncTCP
  • ESPAsyncWebServer
  • VL53L0X

3. Открыть веб-интерфейс

http://192.168.X.X

🎮 Управление (веб-интерфейс)

Джойстик

  • Вверх-вниз = Throttle (скорость)
  • Влево-вправо = Steering (поворот)

Кнопки

  • ▶ Прямо - ехать 2 сек, потом линия
  • 〰 Линия - следить за линией
  • ⏹ Стоп - остановка

Датчики в реальном времени

  • Расстояние до препятствия (мм)
  • 5 датчиков линии (график)
  • Угол наклона
  • Статус уклона

🤖 Как работает робот

1. IDLE (ждёт команду)
   ├─ Кнопка "Прямо" → STRAIGHT
   ├─ Кнопка "Линия" → LINE_FOLLOW
   └─ Кнопка Захвата → Открыть/Закрыть (независимо)
   
2. STRAIGHT (2 сек движение вперёд)
   └─ Автоматический переход → LINE_FOLLOW
   
3. LINE_FOLLOW (следит за линией)
   ├─ Если видит препятствие → STOPPED
   ├─ Если уклон → замедление (×0.5)
   └─ Захват управляется отдельно
   
4. STOPPED (препятствие обнаружено)
   ├─ Моторы остановлены
   └─ Кнопка "Стоп" → IDLE

Захват (независимый):
- Открыть: 180° (можно в любой момент)
- Закрыть: 90° (можно в любой момент)

🧪 Тестирование

1. Тест датчика линии

// Загрузить: test_line_sensor.ino
// Serial Monitor: 115200 baud
// Выводит: Raw values, Calibrated, ASCII график

2. Тест датчика расстояния

// Загрузить: test_distance_sensor.ino
// Serial Monitor: 115200 baud
// Выводит: Расстояние в мм, статус, ASCII график
// Проверяет: 0-200mm (очень близко) до >1000mm (далеко)

3. Тест моторов

// Загрузить: test_motors.ino
// Serial Monitor: 115200 baud
// Тесты:
//   1. Оба медленно вперёд
//   2. Оба быстро вперёд
//   3. Оба назад
//   4. Разные скорости (синхронизация)
// Выводит: Количество шагов, соотношение скоростей

4. Тест сервомоторов захвата

// Загрузить: test_servo_gripper.ino
// Serial Monitor: 115200 baud
// Тесты:
//   1. Левая серво: 0° → 180° → 0°
//   2. Правая серво: 0° → 180° → 0°
//   3. Обе вместе (Открыть 180° → Закрыть 90° → Сброс 0°)
// Пины: GPIO 13 (левая), GPIO 33 (правая)
// Выводит: ASCII график углов поворота

5. Тест гироскопа (MPU6050)

// Загрузить: test_gyro.ino
// Serial Monitor: 115200 baud
// Проверяет: WHO_AM_I (0x68), затем читает данные
// Выводит:
//   - Гироскоп X/Y/Z (°/сек)
//   - Акселерометр X/Y/Z (g)
//   - Углы Pitch / Roll
//   - Температуру (°C)
// Пины I2C: SDA=GPIO 21, SCL=GPIO 22

🔧 Параметры в коде

#define DISTANCE_THRESHOLD 300      // Стоп < 300мм
#define STRAIGHT_TIME 2000          // 2 сек прямо
#define SLOPE_ACCEL_THRESHOLD 2000  // Порог уклона
#define MAX_THROTTLE 550            // Макс скорость
#define MAX_STEERING 140            // Макс поворот

📊 GPIO подключение (ESP32)

I2C (для датчиков):
  GPIO 21 (SDA) ← MPU6050, VL53L0X
  GPIO 22 (SCL) ← MPU6050, VL53L0X

Моторы (движение):
  GPIO 27 ← Motor1 DIR (направление)
  GPIO 14 ← Motor1 STEP (шаги)
  GPIO 25 ← Motor2 DIR (направление)
  GPIO 26 ← Motor2 STEP (шаги)
  GPIO 12 ← Enable (включение)

Захват (две серво):
  GPIO 13 ← Servo Left (левая рука)
  GPIO 33 ← Servo Right (правая рука)

Датчик линии:
  GPIO 34 ← S1 (левый край)
  GPIO 35 ← S2 (левая четверть)
  GPIO 36 ← S3 (центр)
  GPIO 39 ← S4 (правая четверть)
  GPIO 32 ← S5 (правый край)

🐛 Помощь

Робот не подключается:

  • Проверить SSID/пароль WiFi
  • Смотреть Serial Monitor (115200)

Не балансирует:

  • Проверить I2C (MPU6050)
  • Проверить моторы (test_motors.ino)

Не следит за линией:

  • Калибровать датчик (test_line_sensor.ino)
  • Проверить контрастность линии

Не видит препятствие:

  • Тест датчика (test_distance_sensor.ino)
  • Отрегулировать DISTANCE_THRESHOLD

⚠️ Известная проблема: драйверы моторов иногда «отпадают» (не работает пин DIR)

Аппаратный баг, замеченный на соревнованиях: периодически один из драйверов шаговых моторов теряет реакцию на пин DIR — мотор крутится только в одну сторону или полностью замирает. Робота начинает уводить в сторону, баланс ломается, заезд провален.

Симптомы:

  • Мотор едет только вперёд или только назад, направление не меняется
  • После перезапуска может снова заработать (потом опять отвалится)
  • Один мотор крутится, второй стоит — хотя test_motors.ino раньше проходил

Причины (по частоте):

  1. Плохой контакт Dupont-провода на DIR/STEP (GPIO 27/25 → DIR, GPIO 14/26 → STEP) — вибрации от моторов расшатывают разъёмы
  2. Перегрев драйвера — срабатывает тепловая защита, драйвер отключается до остывания
  3. Просадка питания 12В при старте обоих моторов одновременно
  4. Наводки от сервоприводов захвата на сигнальные линии (если сервопитание не отдельное)

Что делать (по порядку):

  1. Переподключить и лучше припаять провода DIR/STEP — дребезг контакта это причина №1
  2. Проверить общую землю: ESP32 ↔ драйвер ↔ блок питания моторов
  3. Потрогать драйвер: горячий = тепловая защита. Ставить радиатор, снизить ток через Vref
  4. Серво захват питать строго от отдельного источника 5V, иначе наводки будут валить драйверы
  5. Быстрый сброс драйвера без перезагрузки робота: дёрнуть ENABLE (GPIO 12) в HIGH и обратно в LOW
  6. Перед каждым заездом гонять test_motors.ino (тест №4 — разные скорости/направления): он ловит отвалившийся DIR сразу

💡 На соревновании: если робота начало уводить в сторону — первым делом подозревай DIR-пин драйвера, а не настройку PID.


✅ Проверка перед использованием

  • ESP32 подключена
  • Все датчики подключены
  • WiFi SSID/пароль введены
  • test_motors.ino проходит (обе стороны вращения!)
  • DIR-пины обоих драйверов живые — моторы меняют направление (частая поломка!)
  • Драйверы не перегреты (радиатор на месте)
  • test_line_sensor.ino работает
  • test_distance_sensor.ino работает
  • Веб-интерфейс открывается

Версия: 3.4.0 (с веб-интерфейсом)
Статус: ✅ Production Ready


🔌 ПОЛНАЯ СХЕМА ПОДКЛЮЧЕНИЯ

ESP32 Pinout (30 pin version)

         ┌─────────────────────┐
         │      ESP32-30       │
    GND  │  ⬤ ⬤ ⬤ ⬤ ⬤ ⬤ ⬤ ⬤  │  3.3V
    GND  │  ⬤                 ⬤ │  VUSB
    3.3V │  ⬤                 ⬤ │  GND
    RST  │  ⬤                 ⬤ │  EN
    12   │  ⬤ ENABLE MOTORS   ⬤ │  27 (MOTOR1_DIR)
    13   │  ⬤ SERVO           ⬤ │  25 (MOTOR2_DIR)
    14   │  ⬤ MOTOR1_STEP     ⬤ │  32 (LINE_S5)
    26   │  ⬀                 ⬀ │  33 (BUZZER)
    35   │  ⬀ LINE_S2         ⬀ │  34 (LINE_S1)
    39   │  ⬀ LINE_S4         ⬀ │  36 (LINE_S3)
    GND  │  ⬀                 ⬀ │  GND
    GND  │  ⬀                 ⬀ │  15
    23   │  ⬀ VSPI_MOSI       ⬀ │  2 (WIFI_LED)
    22   │  ⬀ SCL (I2C)       ⬀ │  4
    21   │  ⬀ SDA (I2C)       ⬀ │  5
    19   │  ⬀ VSPI_MISO       ⬀ │  18 (VSPI_CLK)
    GND  │  ⬀                 ⬀ │  GND
    GND  │  ⬀                 ⬀ │  17
    16   │  ⬀ RX2             ⬀ │  GND
         └─────────────────────┘

📋 ДЕТАЛЬНОЕ ПОДКЛЮЧЕНИЕ КОМПОНЕНТОВ

1. МОТОРЫ (Stepper NEMA17 с драйвером)

Motor 1:
┌──────────────────┐
│  NEMA17 Motor   │
├──────────────────┤
│ DIR ─────→ GPIO 27
│ STEP ────→ GPIO 14
│ GND ─────→ GND
│ +12V ────→ 12V (через драйвер)
└──────────────────┘

Motor 2:
┌──────────────────┐
│  NEMA17 Motor   │
├──────────────────┤
│ DIR ─────→ GPIO 25
│ STEP ────→ GPIO 26
│ GND ─────→ GND
│ +12V ────→ 12V (через драйвер)
└──────────────────┘

Motor Enable:
GPIO 12 → Motor Driver Enable
GND ────→ GND

2. MPU6050 (Гироскоп + Акселерометр)

┌──────────────────┐
│     MPU6050      │
├──────────────────┤
│ SDA ─────→ GPIO 21 (I2C)
│ SCL ─────→ GPIO 22 (I2C)
│ GND ─────→ GND
│ VCC ─────→ 3.3V
│ INT ─────→ не подключать (опционально)
└──────────────────┘

I2C адрес: 0x68

3. VL53L0X (Датчик расстояния)

┌──────────────────┐
│    VL53L0X       │
├──────────────────┤
│ SDA ─────→ GPIO 21 (I2C)
│ SCL ─────→ GPIO 22 (I2C)
│ GND ─────→ GND
│ VCC ─────→ 3.3V
│ XSHUT ───→ не подключать (опционально)
└──────────────────┘

I2C адрес: 0x29

4. ДАТЧИК ЛИНИИ (Ldabrye 5-sensor)

┌─────────────────────────────┐
│  Ldabrye Line Sensor Array  │
├─────────────────────────────┤
│ S1 (Левый)   ─→ GPIO 34 (ADC)
│ S2          ─→ GPIO 35 (ADC)
│ S3 (Центр)  ─→ GPIO 36 (ADC)
│ S4          ─→ GPIO 39 (ADC)
│ S5 (Правый) ─→ GPIO 32 (ADC)
│ GND         ─→ GND
│ VCC         ─→ 5V
└─────────────────────────────┘

5. ЗАХВАТ (две серво)

┌──────────────────────────┐
│  Servo Left (MG996R)     │
├──────────────────────────┤
│ Signal ────→ GPIO 13 (PWM)
│ GND ───────→ GND
│ VCC ───────→ 5V
└──────────────────────────┘

┌──────────────────────────┐
│  Servo Right (MG996R)    │
├──────────────────────────┤
│ Signal ────→ GPIO 33 (PWM)
│ GND ───────→ GND
│ VCC ───────→ 5V
└──────────────────────────┘

Углы:
- OPEN (180°) - захват открыт
- CLOSE (90°) - захват закрыт

6. СВЕТОДИОДЫ (опционально)

WiFi LED:
GPIO 2 → LED+ → ⎕ → 220Ω → GND

7. ПИТАНИЕ (Очень важно!)

┌──────────────────────────────┐
│   Power Distribution         │
├──────────────────────────────┤
│ Battery/PSU                  │
│ ├─→ 5V ────→ 5V шина         │
│ │  ├─→ Line Sensor VCC       │
│ │  ├─→ VL53L0X VCC           │
│ │  └─→ Servo Left + Right    │
│ │
│ ├─→ 12V ───→ Motor Driver    │
│ │  └─→ Stepper Motors        │
│ │
│ ├─→ 3.3V ──→ ESP32 (Zener)   │
│ │  └─→ MPU6050 VCC           │
│ │
│ └─→ GND ───→ GND шина (ОБЩАЯ)│
│    ├─→ ESP32 GND            │
│    ├─→ Драйвер GND          │
│    ├─→ Датчики GND          │
│    └─→ Серво GND            │
└──────────────────────────────┘

⚠️ КРИТИЧНО: 
- Все GND должны быть соединены вместе!
- Серво требуют отдельный источник питания (5V мощный!)
- Защищать сигналы серво от помех моторов

🎯 ПЛАТА ПОДКЛЮЧЕНИЯ (breadboard раскладка)

I2C (GPIO 21, 22):
┌─ 3.3V ─ Pull-up 4.7K ─ GPIO 22 (SCL) ─ MPU6050 SCL
├─ 3.3V ─ Pull-up 4.7K ─ GPIO 21 (SDA) ─ MPU6050 SDA
│                                      └─ VL53L0X SDA/SCL
└─ GND ─────────────────────────────── Оба датчика GND

АДЦ (Line Sensors):
GPIO 34 ← Sensor1 (ADC1_CH6)
GPIO 35 ← Sensor2 (ADC1_CH7)
GPIO 36 ← Sensor3 (ADC1_CH0)
GPIO 39 ← Sensor4 (ADC1_CH3)
GPIO 32 ← Sensor5 (ADC1_CH4)

Motor Control:
GPIO 27 → Драйвер DIR1 → Motor1 DIR
GPIO 14 → Драйвер STEP1 → Motor1 STEP
GPIO 25 → Драйвер DIR2 → Motor2 DIR
GPIO 26 → Драйвер STEP2 → Motor2 STEP
GPIO 12 → Драйвер ENABLE

Аудио/Визуально:
GPIO 33 → Buzzer
GPIO 2 → WiFi LED

📐 ПРИНЦИПИАЛЬНАЯ СХЕМА

                     ┌──────────────────┐
                     │       ESP32      │
                     └──────────────────┘
                              │
         ┌────────────────────┼─────────────────────┐
         │                    │                     │
    ┌────────┐         ┌───────────┐        ┌──────────┐
    │ Motors │         │ Sensors   │        │ WiFi/Web │
    │ ────── │         │ ──────── │        │ ──────── │
    │ M1/M2  │         │ MPU6050   │        │ Interface│
    │ Driver │         │ VL53L0X   │        │ Browser  │
    │ 12V    │         │ LineSensor│        │ Joystick │
    └────────┘         └───────────┘        └──────────┘
         │                    │                     │
         └────────────────────┼─────────────────────┘
                              │
                         [Battery]

✅ ПРОВЕРКА ПОДКЛЮЧЕНИЯ

На столе:
1. GPIO 21/22 (I2C) → датчики
   - SDA → GPIO 21 (MPU6050, VL53L0X)
   - SCL → GPIO 22 (MPU6050, VL53L0X)
   - 3.3V, GND

2. GPIO 34/35/36/39/32 (ADC) → датчик линии
   - S1-S5 → GPIO 34/35/36/39/32
   - 5V, GND

3. GPIO 27/14/25/26/12 (Motor) → драйвер
   - DIR/STEP → GPIO 27/14/25/26
   - Enable → GPIO 12
   - GND, 12V

4. GPIO 13/33 (PWM) → сервомоторы захвата
   - Servo Left  → GPIO 13
   - Servo Right → GPIO 33
   - GND, 5V (отдельный источник!)

5. Проверить:
   [ ] Все 3.3V соединены
   [ ] Все GND соединены (ОБЩАЯ земля!)
   [ ] MPU6050 + VL53L0X на I2C (GPIO 21/22)
   [ ] I2C Pull-up резисторы (4.7K)
   [ ] Датчик линии на GPIO 34/35/36/39/32
   [ ] Моторы на GPIO 27/14/25/26/12
   [ ] Сервомоторы на GPIO 13 и GPIO 33
   [ ] Питание серв отдельное и мощное!
   [ ] Питание моторов 12V отдельное

🔍 I2C PULL-UP РЕЗИСТОРЫ (ВАЖНО!)

Если датчики не отвечают, добавить:

GPIO 22 (SCL):
3.3V ──[4.7K]──┬── GPIO 22
               │
            MPU6050 SCL
            VL53L0X SCL

GPIO 21 (SDA):
3.3V ──[4.7K]──┬── GPIO 21
               │
            MPU6050 SDA
            VL53L0X SDA

Версия схемы: 1.0
Последнее обновление: 2026-06-07

About

Self-balancing robot on ESP32 with line tracking, obstacle avoidance, and web joystick control. Real-time PID control, WiFi enabled, fully documented with web interface.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages