ArduinoVN
Đăng nhập Tham gia

Danh sách linh kiện

CSV
Linh kiện SL Đơn giá Thành tiền Đã có Mua
Tổng chi phí còn lại:

Các bước thực hiện

6 bước

Bước 1: Linh kiện và thiết kế

Xe 4 bánh có 4 motor DC giảm tốc → tank-drive (mỗi bên 2 motor cùng chiều). ESP32-CAM trên đỉnh xe, servo SG90 xoay pan ±90°.

  • ESP32-CAM (Ai-Thinker).
  • FTDI programmer (lúc flash code).
  • Khung xe 4 bánh kit (~300k) với 4 motor + 4 bánh cao su.
  • 2× L298N (hoặc 1 cái dùng cả 4 motor 2 cặp).
  • Servo SG90.
  • Pin 2× 18650 + đế kẹp.
  • Buck converter 5V/3A.

Bước 2: Đấu nối ESP32-CAM (chú ý chân hạn chế)

ESP32-CAM ít GPIO available vì camera + flash chiếm nhiều. Chỉ còn:

  • GPIO 12, 13, 14, 15 (boot strapping — chú ý)
  • GPIO 2 (boot mode khi LOW)
  • GPIO 16
  • GPIO 4 (flash LED — nếu không dùng flash thì OK)

Đấu nối:

  • Motor trái IN1/IN2 → GPIO 12, 13.
  • Motor phải IN3/IN4 → GPIO 14, 15.
  • Enable A/B (nếu cần PWM tốc độ) → GPIO 2, 16.
  • Servo signal → GPIO 4 (nếu không dùng flash) hoặc bỏ servo.
  • 5V → ESP32-CAM 5V (qua buck).

Lưu ý: GPIO 12 = boot mode — khi flash code thì pull-down. Nếu đấu motor tới đó, có thể block flash. Cần ngắt motor connector khi reprogram.

Bước 3: Code chính — camera + motor + web UI

Build trên example CameraWebServer ESP32, thêm endpoint /cmd?dir=F:

cmd_handler.cpp — C++ / Arduino
// Trong app_httpd.cpp hoặc file mới cmd_handler.cpp

#include "esp_http_server.h"
#include <Arduino.h>

const int IN1 = 12, IN2 = 13;
const int IN3 = 14, IN4 = 15;

void stopAll() {
  digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW); digitalWrite(IN4, LOW);
}

esp_err_t cmd_handler(httpd_req_t *req) {
  char buf[100];
  if (httpd_req_get_url_query_str(req, buf, sizeof(buf)) == ESP_OK) {
    char dir[8];
    if (httpd_query_key_value(buf, "dir", dir, sizeof(dir)) == ESP_OK) {
      char d = dir[0];
      switch (d) {
        case 'F': digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW);
                  digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW); break;
        case 'B': digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH);
                  digitalWrite(IN3,LOW); digitalWrite(IN4,HIGH); break;
        case 'L': digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH);
                  digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW); break;
        case 'R': digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW);
                  digitalWrite(IN3,LOW); digitalWrite(IN4,HIGH); break;
        case 'S': stopAll(); break;
      }
    }
  }
  httpd_resp_set_type(req, "text/plain");
  return httpd_resp_send(req, "OK", 2);
}

static httpd_uri_t cmd_uri = {
  .uri = "/cmd",
  .method = HTTP_GET,
  .handler = cmd_handler,
  .user_ctx = NULL
};

void startCmdServer() {
  pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
  stopAll();
  // Register cmd_uri vào server chính khi startCameraServer()
}

Bước 4: Web UI joystick

Trang HTML serve từ ESP32 với 5 button + thẻ <img> stream MJPEG:

control.html — JavaScript
<!DOCTYPE html>
<html><head><meta charset='utf-8'>
<style>
  body{font-family:sans-serif;text-align:center;background:#222;color:#fff;margin:0}
  img{width:100%;max-width:640px}
  .pad{display:grid;grid-template-columns:repeat(3,80px);gap:10px;justify-content:center;margin-top:20px}
  button{padding:25px;font-size:30px;background:#444;color:#fff;border:none;border-radius:8px}
  button:active{background:#0a0}
</style></head>
<body>
<h2>Robot Cam</h2>
<img src="/stream" />
<div class='pad'>
  <span></span><button onclick="send('F')">↑</button><span></span>
  <button onclick="send('L')">←</button>
  <button onclick="send('S')">■</button>
  <button onclick="send('R')">→</button>
  <span></span><button onclick="send('B')">↓</button><span></span>
</div>
<script>
function send(d) {
  fetch('/cmd?dir=' + d);
}
// Hold-to-drive: gửi S khi nhả nút
document.querySelectorAll('button').forEach(b =&gt; {
  b.addEventListener('mouseup', () =&gt; send('S'));
  b.addEventListener('touchend', () =&gt; send('S'));
});
</script>
</body></html>

Bước 5: Test và tinh chỉnh

  1. Cấp nguồn xe.
  2. Mở browser PC/điện thoại trong cùng WiFi.
  3. Truy cập http://<esp-cam-ip>/control.html.
  4. Thấy video stream + 5 nút điều khiển.
  5. Bấm nút → xe di chuyển. Nhả nút → dừng.

Latency: ~200–400ms từ bấm đến motion. Đủ cho indoor drive nhưng không phải FPV racing.

Lỗi thường gặp

  • Brownout reset: nguồn yếu. ESP32-CAM peak 800mA khi stream + flash + motor 1A+ → cần adapter 5V/3A.
  • Stream lag: WiFi yếu, giảm frame_size xuống QVGA.
  • Xe quay không đều: 4 motor không đồng tốc — chỉnh PWM riêng từng cặp.
  • Stream dừng khi bấm nút: handler block — tách thành task FreeRTOS riêng.

Bước 6: Mở rộng

  • Servo pan/tilt camera: 2 servo, control thêm slider trong UI.
  • Flash LED: bật/tắt qua API.
  • Speed slider: PWM enable A/B chỉnh tốc độ.
  • Battery monitor: voltage divider, hiển thị % pin trong UI.
  • HC-SR04 phía trước: auto-stop khi vật cản < 15cm.
  • Joystick gamepad: dùng Gamepad API trong browser thay nút bấm.
  • Record video: lưu MJPEG vào SD card trong xe.
  • WebRTC thay MJPEG: latency < 100ms — chuyên hơn nhiều, nhưng phức tạp setup.

Thảo luận (0)

Đăng nhập để tham gia thảo luận.
Chưa có bình luận nào. Hãy là người đầu tiên!