ESP32-CAM و FPV یعنی چه؟ (برای کسی که تا امروز ندیده)
ESP32-CAM یک برد الکترونیکی بسیار ارزان (زیر ۵۰۰ هزار تومان) است که در خودش یک میکروکنترلر ESP32، وایفای، بلوتوث، و یک دوربین ۲ مگاپیکسلی دارد. مدل محبوب آن از شرکت AI-Thinker است. این برد میتواند همزمان به عنوان یک دوربین IP، یک وبسرور، و یک کنترلکننده ربات عمل کند — همه در یک تراشه کوچک.
FPV مخفف First Person View یعنی دیدن دنیا از دید اولشخص. در پهپادها و ماشینهای RC، FPV یعنی شما تصویر دوربین نصبشده روی وسیله را روی نمایشگر یا عینک میبینید — انگار که خودتان آنجا نشستهاید. در این پروژه بهجای فرستنده FPV گرانقیمت، از وایفای ESP32 استفاده میکنیم تا تصویر به گوشی یا لپتاپ بیاید.
برای آپلود کد روی ESP32-CAM به یک FTDI Programmer نیاز دارید — یک مبدل USB-به-UART ارزان که دو پین TX/RX ندارد ولی بدون آن نمیتوانید به ESP32-CAM متصل شوید. این یک بار تهیه میشود و برای همه پروژههای آینده قابل استفاده است.
محصولی که میسازید
ماشین رباتیک FPV مبتنی بر وایفای — با گوشی یا لپتاپ به وایفای ESP32-CAM وصل میشوید، صفحه کنترل را در مرورگر باز میکنید، تصویر زنده میبینید و ماشین را به جلو/عقب/چپ/راست هدایت میکنید.
- زمان ساخت: ۳ تا ۵ ساعت
- سطح: مبتدی رو به متوسط
- برد وایفای: ۳۰ تا ۱۰۰ متر در فضای باز
- هزینه تقریبی: ۸۰۰ هزار تا ۱.۵ میلیون تومان
قطعات و ابزارهای لازم (BOM)
| قطعه | مدل | نقش |
|---|---|---|
| برد اصلی | ESP32-CAM AI-Thinker | مغز + دوربین + WiFi |
| پروگرامر | FTDI FT232RL | آپلود کد |
| درایور موتور | L298N | کنترل دو موتور DC |
| شاسی | Smart Car 2WD Kit | بدنه و موتور |
| باتری | 2S LiPo 1500mAh | تغذیه |
| رگولاتور | AMS1117-3.3 یا LM2596 | تبدیل ولتاژ برای ESP32-CAM |
نکته مهم: تغذیه ESP32-CAM
ESP32-CAM به ۳.۳ ولت با جریان حداقل ۵۰۰mA نیاز دارد. هرگز از پین 5V آردوینو مستقیم تغذیه نکنید. یک رگولاتور AMS1117-3.3 یا LM2596 بین باتری و ESP32-CAM قرار دهید. تغذیه ضعیف شایعترین دلیل ریست شدن ESP32-CAM است.
مراحل ساخت گام به گام
- نصب Arduino IDE و ESP32 Board Manager: در IDE بروید به File → Preferences، در Additional Board URLs این را اضافه کنید:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.jsonسپس از Boards Manager، «esp32 by Espressif» را نصب کنید. - وصل کردن FTDI به ESP32-CAM برای آپلود کد: پین GPIO0 را به GND وصل کنید (حالت Flash Mode). سپس: FTDI TX → ESP32 U0R، FTDI RX → ESP32 U0T، FTDI 3.3V → ESP32 3.3V، FTDI GND → ESP32 GND.
- انتخاب برد در IDE: Board: AI Thinker ESP32-CAM، Port: پورت FTDI شما.
- آپلود کد (در بخش بعد).
- بعد از آپلود: GPIO0 را از GND جدا کنید و دکمه Reset را بزنید.
- مونتاژ روی شاسی: ESP32-CAM و L298N را روی شاسی ببندید، موتورها را وصل کنید.
کد کامل
#include "esp_camera.h"
#include <WiFi.h>
#include "esp_http_server.h"
// پینهای دوربین (مدل AI-Thinker)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// پینهای موتور
#define IN1 12
#define IN2 13
#define IN3 15
#define IN4 14
const char* ssid = "ESP32-CAM-Car";
const char* password = "12345678";
void setupCamera() {
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 15;
config.fb_count = 1;
esp_camera_init(&config);
}
void forward() { digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW); }
void backward() { digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);digitalWrite(IN3,LOW);digitalWrite(IN4,HIGH); }
void left() { digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW); }
void right() { digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);digitalWrite(IN3,LOW);digitalWrite(IN4,HIGH); }
void stopAll() { digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);digitalWrite(IN3,LOW);digitalWrite(IN4,LOW); }
static esp_err_t cmd_handler(httpd_req_t *req) {
char buf[10]; int ret = httpd_req_recv(req, buf, sizeof(buf)-1);
if(ret <= 0) return ESP_FAIL;
buf[ret] = 0;
String cmd = String(buf);
if(cmd=="F") forward();
else if(cmd=="B") backward();
else if(cmd=="L") left();
else if(cmd=="R") right();
else stopAll();
httpd_resp_send(req, "OK", 2);
return ESP_OK;
}
static esp_err_t stream_handler(httpd_req_t *req) {
httpd_resp_set_type(req, "multipart/x-mixed-replace; boundary=frame");
while(true) {
camera_fb_t *fb = esp_camera_fb_get();
if(!fb) continue;
char part[64];
snprintf(part, sizeof(part), "--frame\r\nContent-Type: image/jpeg\r\nContent-Length: %d\r\n\r\n", fb->len);
httpd_resp_send_chunk(req, part, strlen(part));
httpd_resp_send_chunk(req, (const char*)fb->buf, fb->len);
httpd_resp_send_chunk(req, "\r\n", 2);
esp_camera_fb_return(fb);
delay(30);
}
return ESP_OK;
}
void setup() {
for(int p : {IN1,IN2,IN3,IN4}) pinMode(p, OUTPUT);
stopAll();
setupCamera();
WiFi.softAP(ssid, password);
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
httpd_handle_t server = NULL;
httpd_start(&server, &config);
httpd_uri_t cmd_uri = { .uri="/cmd", .method=HTTP_POST, .handler=cmd_handler };
httpd_uri_t stream_uri = { .uri="/stream", .method=HTTP_GET, .handler=stream_handler };
httpd_register_uri_handler(server, &cmd_uri);
httpd_register_uri_handler(server, &stream_uri);
}
void loop() { delay(1000); }
چکلیست تست
| تست | نتیجه | راهحل |
|---|---|---|
| WiFi «ESP32-CAM-Car» در گوشی دیده میشود؟ | بله | GPIO0 را از GND جدا کرده و Reset زدهاید؟ |
| آدرس 192.168.4.1/stream تصویر نشان میدهد؟ | بله | تغذیه ۳.۳V کافی است؟ (AMS1117) |
| دستور POST به /cmd موتورها را حرکت میدهد؟ | بله | پینهای IN1-IN4 را بررسی کنید |
| دمای ESP32-CAM معمولی است؟ | گرم ولی داغ نه | هیتسینک کوچک بچسبانید |