SAMET.DEV
İletişime Geç
← Bloga dön

·11 dk okuma

Kesis-Robot: ESP32-CAM ile Mecanum Sürüşlü, Otonom Renk Takipli Robot Projesi

Çift ESP32 mimarisi, ESP-NOW haberleşme, MJPEG canlı yayın, otonom renk takip algoritması, pan-tilt kamera ve Mecanum kinematik — Kesis-Robot'u sıfırdan nasıl inşa ettim.

Etiketler:esp32roboticsembeddedesp-nowcomputer-vision

Giriş: Bu Proje Nasıl Başladı?

Her şey basit bir fikirle başladı: telefonumdan kontrol edebileceğim, canlı kamera görüntüsü aktaran ve her yöne hareket edebilen bir robot yapmak istiyordum. Ama "basit" dediğim şey, zamanla kendi kendine top kovalayan, kamerasını uzaktan döndürebildiğim, korna çalabilen ciddi bir mühendislik projesine dönüştü. Bu yazıda Kesis-Robot projesini — kullandığım her ekipmandan, karşılaştığım her zorluğa kadar — baştan sona detaylıca anlatacağım.

Kaynak kod: GitHub — SmtGcl22/esp32cam-robot

📸 Proje Görselleri

Robotun Son Hali

Kesis-Robot — Güncel görünüm (Pan-Tilt mekanizması ve tüm bileşenler monte edilmiş hali)Kesis-Robot — Güncel görünüm (Pan-Tilt mekanizması ve tüm bileşenler monte edilmiş hali)

Kesis-Robot — Üstten görünümKesis-Robot — Üstten görünüm

Geliştirme Süreci

Prototip aşaması — Motor sürücüler ve kablolamaPrototip aşaması — Motor sürücüler ve kablolama

Mecanum tekerlekler ve şasi montajıMecanum tekerlekler ve şasi montajı

Devre testleri ve breadboard prototipiDevre testleri ve breadboard prototipi

İlk montaj — Projenin başlangıç haliİlk montaj — Projenin başlangıç hali

Demo Videoları

☝️ Robot sürüş demosu — Mecanum tekerleklerle omnidirectional hareket

☝️ Uzaktan kontrol ve canlı kamera yayını demosu

☝️ Otonom renk takip modu — Robot hedefi kendi başına buluyor

☝️ Pan-Tilt kamera kontrolü ve genel sistem testi

🎯 Projenin Amacı ve Vizyonu

Projenin temel amacı; mobil cihazlardan veya bilgisayarlardan tarayıcı üzerinden kontrol edilebilen, anlık kamera görüntüsü aktaran ve Mecanum tekerlekleri sayesinde her yöne (yanal, çapraz, yerinde dönüş dahil) hareket edebilen bir keşif robotu geliştirmekti.

Ama sadece uzaktan kumanda ile sınırlı kalmak istemedim. İkinci aşamada robota otonom renk takip yeteneği ekledim: robot, kameradan aldığı görüntüyü gerçek zamanlı işleyerek seçtiğim renkteki bir nesneyi (kırmızı, mavi veya sarı top gibi) kendi başına bulabiliyor ve takip edebiliyor.

Üçüncü aşamada ise Pan-Tilt servo mekanizması entegre ettim. Böylece kamerayı uzaktan sağa-sola ve yukarı-aşağı döndürebiliyorum — robotun gövdesini hareket ettirmeden etrafı tarayabiliyorum.

🛠️ Kullanılan Donanımlar ve Ekipmanlar

Bu projeyi hayata geçirmek için ciddi bir donanım listesi topladım. Her bir parçanın neden seçildiğini ve ne işe yaradığını anlatayım:

Mikrodenetleyiciler

  • ESP32-CAM (AI-Thinker): Projenin beyni. Üzerinde OV2640 kamera modülü, 4 MB PSRAM ve WiFi/Bluetooth var. Hem web sunucusunu barındırıyor, hem kamera yayını yapıyor, hem de ESP-NOW ile diğer ESP'ye komut gönderiyor. Flash LED'i de karanlık ortamlarda aydınlatma için kullanıyorum.

  • ESP32 DevKit v1 (Ana Alıcı): Motorları süren ikinci mikrodenetleyici. ESP-NOW ile gelen komutları alıp Mecanum kinematik hesaplamasını yaparak 4 motora ayrı ayrı PWM sinyali gönderiyor.

Motor Sürücüler ve Motorlar

  • 2x TB6612FNG Motor Sürücü: Neden L298N değil de TB6612? Çünkü TB6612 MOSFET tabanlı — L298N'e kıyasla çok daha verimli, çok daha az ısınıyor ve voltaj düşümü neredeyse yok. L298N'de motor başına yaklaşık 1.5-2V kayıp yaşanırken, TB6612'de bu 0.5V'un altında kalıyor. Pil ömrü ve motor performansı açısından fark muazzam.

  • 4x DC Motor + 4x Mecanum Tekerlek: Mecanum tekerleklerin üzerindeki 45° açılı rulolar sayesinde robot, yüzünü çevirmeden sağa-sola kayabiliyor (strafe hareketi). İleri, geri, sağa-sola kayma, çapraz hareket ve yerinde dönüş — hepsi mümkün.

Kamera ve Pan-Tilt Mekanizması

  • OV2640 Kamera Modülü: ESP32-CAM üzerinde entegre. PSRAM sayesinde VGA (640x480) çözünürlükte JPEG çekebiliyor. Otonom mod için QVGA'ya (320x240) düşürüp işleme hızını artırıyorum.

  • 2x SG90 Micro Servo (Pan-Tilt): Biri yatay eksende (Pan — sağ/sol), diğeri dikey eksende (Tilt — yukarı/aşağı) kamerayı döndürüyor. GPIO 14 ve GPIO 12 pinlerinden 50Hz PWM ile sürülüyor. Her ikisi de 0°-180° arasında hareket edebiliyor ve web arayüzünden slider ile kontrol ediliyor.

Güç Kaynağı

  • Li-Po Pil Paketi: Tüm sistemi besleyen güç kaynağı. Motorlar, servolar, ESP32'ler ve kamera hepsi buradan besleniyor. TB6612'nin düşük voltaj kaybı sayesinde pil ömrü oldukça uzun.

Diğer Ekipmanlar

  • Buzzer (Korna): GPIO 32 pinine bağlı. Web arayüzündeki korna butonuna bastığınızda "bip" sesi çıkarıyor. Eğlenceli bir detay ama aynı zamanda çevrenizdeki insanları uyarmak için de kullanışlı.

  • Multimetre: Projenin vazgeçilmez aracı. Her motor sürücüsünün voltaj düşümünü ölçtüm, servo PWM sinyallerini doğruladım, pil seviyelerini takip ettim. Özellikle TB6612 ve L298N karşılaştırmasını multimetreyle ölçerek karar verdim.

  • Breadboard ve Jumper Kablolar: Prototipleme aşamasında tüm devreyi breadboard üzerinde kurdum. Her bağlantıyı test edip çalıştığından emin olduktan sonra lehimlemeye geçtim.

  • Lehim İstasyonu: Kalıcı bağlantılar için kullandım. Özellikle motor kablolarının ve güç dağıtımının güvenilir olması kritik.

🏗️ Sistem Mimarisi — Neden Çift ESP32?

Bu projenin en kritik tasarım kararı buydu. İlk denememde her şeyi tek ESP32-CAM ile yapmaya çalıştım ve sonuç felaket oldu:

  • MJPEG video yayını WiFi ve CPU'yu aşırı meşgul ediyordu.
  • Motor komutlarında gözle görülür gecikme yaşanıyordu.
  • PWM sinyallerinde titreşim ve kopmalar oluyordu — robot sarsıntılı hareket ediyordu.
  • Kamera fps'i düşüyordu, görüntü donuyordu.

Hibrit Çözüm — İş Yükünü Bölmek

Sorunu çözmek için işi ikiye böldüm:

Modül 1 — ESP32-CAM (Kamera + Web Sunucu + Komut Verici)

  • WiFi Access Point açıyor (SSID: KesisRobot-CAM, Şifre: kesis2026)
  • Port 80'de web arayüzünü sunuyor (kontrol paneli)
  • Port 81'de MJPEG canlı video akışı yapıyor
  • Kullanıcıdan gelen joystick verisini ESP-NOW ile Modül 2'ye iletiyor
  • Otonom renk takip algoritmasını çalıştırıyor (FreeRTOS task olarak)
  • Pan-Tilt servolarını kontrol ediyor
  • Flash LED'i yönetiyor

Modül 2 — Ana ESP32 (Motor Kontrolcü)

  • ESP-NOW üzerinden kontrol paketlerini dinliyor
  • Mecanum kinematik hesaplamasını yapıyor
  • 4 motora ayrı ayrı PWM üretiyor (TB6612 üzerinden)
  • Korna buzzer'ını kontrol ediyor
  • 500ms sinyal gelmezse güvenlik durduruması yapıyor

ESP-NOW nedir? Espressif'in geliştirdiği, router'a ihtiyaç duymadan cihazlar arası doğrudan, milisaniye seviyesinde haberleşme sağlayan protokol. MAC adresine dayalı çalışıyor, çok düşük gecikmeli — bu projede motor komutlarının anlık iletilmesi tamamen buna bağlı.

💻 Yazılım Detayları ve Algoritmalar

1. ESP-NOW Kontrol Paketi

Joystick'ten gelen veriler şu yapıda paketlenip gönderiliyor:

typedef struct __attribute__((packed)) {
  int8_t x;      // -100..100 (Yanal kayma / strafe)
  int8_t y;      // -100..100 (İleri / geri)
  int8_t rot;    // -100..100 (Kendi ekseninde dönüş)
  uint8_t speed; // 0..255 (Maksimum hız limiti)
  uint8_t horn;  // 0=Kapalı, 1=Açık (Korna)
} ControlData;

Toplam sadece 5 byte — ESP-NOW'un düşük gecikmeli yapısıyla mükemmel uyumlu. Korna bilgisi de bu paketin içinde taşınıyor.

2. Mecanum Kinematiği

Mecanum tekerleklerin üzerindeki 45° açılı rulolar sayesinde, her tekerleğe farklı hız ve yön vererek robotu istediğimiz yöne hareket ettiriyoruz. Kinematik formül şöyle:

void mecanumDrive(int8_t x, int8_t y, int8_t rot, uint8_t maxSpeed) {
  int fl = y + x + rot;   // Sol Ön (Front Left)
  int bl = y - x + rot;   // Sol Arka (Back Left)
  int fr = y - x - rot;   // Sağ Ön (Front Right)
  int br = y + x - rot;   // Sağ Arka (Back Right)

  // Normalizasyon: herhangi bir değer 100'ü aşarsa oranla
  int maxVal = max(max(abs(fl), abs(bl)), max(abs(fr), abs(br)));
  if (maxVal > 100) {
    fl = (int)((long)fl * 100 / maxVal);
    bl = (int)((long)bl * 100 / maxVal);
    fr = (int)((long)fr * 100 / maxVal);
    br = (int)((long)br * 100 / maxVal);
  }
  // Motorları PWM ile sür...
}

Normalizasyon burada çok önemli. Joystick'ten X, Y ve rotasyon aynı anda geldiğinde toplam değerler 100'ü aşabiliyor. Bunu orantılı şekilde ölçeklendirmezsek motorlar doyuma girer ve sürüş kontrolden çıkar.

3. Otonom Renk Takip Sistemi

Bu özellik projenin en heyecan verici kısmı. Robot, kameradan aldığı görüntüyü gerçek zamanlı işleyerek belirli bir renkteki nesneyi kendi başına bulup takip edebiliyor.

Nasıl çalışıyor?

  1. FreeRTOS Task: Renk algılama, ESP32'nin Core 0'ında ayrı bir FreeRTOS task olarak çalışıyor. Core 1 ise WiFi ve HTTP sunucu işlerini hallediyor. Bu şekilde iki çekirdek paralel çalışıyor.

  2. Görüntü İşleme: Kameradan alınan JPEG kare, PSRAM'da RGB888 formatına dönüştürülüyor. Ardından her SCAN_STRIDE'ıncı piksel (her 4 piksel) taranarak hedef renk aranıyor. Bu atlama sayesinde işlem hızı 4 kat artıyor.

  3. Renk Eşleştirme: Her piksel için RGB değerleri kontrol ediliyor:

bool isTargetColor(uint8_t r, uint8_t g, uint8_t b, int color) {
  switch (color) {
    case COLOR_RED:
      return (r > 110 && g < 90 && b < 90 && r > (g + 40));
    case COLOR_BLUE:
      return (b > 80 && r < 100 && g < 120 && b > r && b > (g - 20));
    case COLOR_YELLOW:
      return (r > 100 && g > 80 && b < 100 && (r + g) > (b * 3 + 100));
    default: return false;
  }
}

OV2640 sensörünün mavi kanalı biraz zayıf olduğu için mavi renk eşiklerini biraz gevşek tutmak zorunda kaldım — yoksa mavi topları algılayamıyordu.

  1. Blob Tespiti: Hedef renkteki piksellerin ağırlık merkezi (centroid) hesaplanıyor. Minimum 25 piksel eşiğini aşarsa "hedef bulundu" sayılıyor.

  2. Motor Komut Üretimi: Hedefin ekrandaki konumuna göre robot hareket ediyor:

    • Hedef sağdaysa → sağa dön
    • Hedef solda → sola dön
    • Hedef küçük görünüyorsa (uzakta) → ileri git
    • Hedef çok büyükse (çok yakında) → geri gel
    • Hedef bulunamadıysa → yavaşça yerinde dönerek ara

4. Pan-Tilt Kamera Kontrolü

İki SG90 servo ile kamerayı uzaktan yönlendirebiliyorum:

#define SERVO_PAN_PIN   14   // Yatay (sağ-sol)
#define SERVO_TILT_PIN  12   // Dikey (yukarı-aşağı)

uint32_t angleToDuty(int angle) {
  uint32_t pulse = map(angle, 0, 180, 500, 2500);
  return (uint32_t)((uint64_t)pulse * 65535 / 20000);
}

16-bit PWM çözünürlüğü kullanıyorum (65535 seviye). Bu sayede servo pozisyonlaması çok hassas. Web arayüzündeki slider'lar ile 0°-180° arasında istediğim açıya getirebiliyorum. "Ortala" butonu ile tek tıkla kamerayı merkeze döndürüyorum.

5. Güvenlik Mekanizması (Fail-Safe)

En önemli yazılımsal detaylardan biri bu. İletişim koptuğunda robot kontrolsüz bir şekilde gitmemeli. Bunu şöyle çözdüm:

#define TIMEOUT_MS 500

// Loop içinde:
if (millis() - lastRecvTime > TIMEOUT_MS) {
  stopAllMotors();
  digitalWrite(BUZZER_PIN, LOW);
}

500 milisaniye boyunca ESP-NOW paketi gelmezse tüm motorlar sıfırlanıyor ve buzzer susturuluyor. Bu basit ama kritik bir güvenlik önlemi — WiFi sinyal kaybında robot duruyor, çevreye zarar vermiyor.

🎨 Web Arayüzü — Kokpit Hissiyatı

Arayüzü tasarlarken hedefim, gerçek bir drone kumanda ekranı hissiyatı vermekti. Tüm HTML, CSS ve JavaScript kodu web_page.h dosyasında tek blok halinde ESP32-CAM'in flash belleğinde saklanıyor — harici sunucu gerekmiyor.

Web arayüzü — Manuel kontrol modu (Joystick, hız ayarı ve canlı kamera görüntüsü)Web arayüzü — Manuel kontrol modu (Joystick, hız ayarı ve canlı kamera görüntüsü)

Web arayüzü — Otonom mod paneli ve Pan-Tilt kamera kontrolüWeb arayüzü — Otonom mod paneli ve Pan-Tilt kamera kontrolü

Arayüz Özellikleri

  • Canlı Video Paneli: MJPEG akış ile anlık kamera görüntüsü. Üzerinde REC göstergesi ve FPS bilgisi.
  • Canvas Joystick: Dokunmatik ekranlar için tasarlanmış, çoklu dokunma destekli analog joystick. Çekiş mesafesi hız ile orantılı.
  • Dönüş Butonları: Joystick'in iki yanında sol ve sağ dönüş butonları. Basılı tuttuğunuz sürece robot kendi etrafında dönüyor.
  • Hız Slider'ı: 80-255 arası motor hız limiti ayarı.
  • Korna Butonu: Basılı tutunca buzzer çalıyor, bırakınca susuyor.
  • Flash LED Kontrolü: Karanlık ortamlarda kamera LED'ini uzaktan açıp kapatma.
  • Otonom Mod Paneli: Manuel ve otonom mod geçişi. Otonom modda hedef renk seçimi (kırmızı, mavi, sarı), hedefin bulunup bulunmadığı, algılanan alan boyutu, FPS ve konum bilgisi canlı olarak gösteriliyor.
  • Hedef İndikatörü: Otonom modda kamera görüntüsünün üzerinde, tespit edilen nesnenin konumunda sarı crosshair göstergesi beliriyor.
  • Pan-Tilt Kontrol Paneli: İki slider ile kameranın yatay ve dikey açısını ayarlama, "Ortala" butonu ile tek tıkla merkeze getirme.
  • Karanlık Neon Tema: Koyu arkaplan üzerinde siyan-mor gradient tonları. Gece kullanımı için göz yormayan, oyun hissiyatlı bir tasarım.

Mod Sistemi

Arayüz iki modda çalışıyor:

  1. Manuel Mod: Joystick, dönüş butonları ve hız kontrolü aktif. Kullanıcı robotu tamamen kontrol ediyor.
  2. Otonom Mod: Joystick devre dışı kalıyor. Robot seçilen renkteki nesneyi kendi başına arıyor ve takip ediyor. Kullanıcı sadece hedef rengini seçiyor ve durumu izliyor.

🔌 Pin Haritası

ESP32-CAM

Pinİşlev
GPIO 0-39OV2640 Kamera veri yolu
GPIO 4Flash LED
GPIO 14Pan Servo (Yatay)
GPIO 12Tilt Servo (Dikey)

Ana ESP32 (Alıcı)

Pinİşlev
GPIO 33, 25Sol Ön Motor Yön (AIN1, AIN2)
GPIO 18Sol Ön Motor PWM
GPIO 26, 27Sol Arka Motor Yön (BIN1, BIN2)
GPIO 19Sol Arka Motor PWM
GPIO 14, 4Sağ Ön Motor Yön (AIN1, AIN2)
GPIO 21Sağ Ön Motor PWM
GPIO 13, 15Sağ Arka Motor Yön (BIN1, BIN2)
GPIO 22Sağ Arka Motor PWM
GPIO 23TB6612 Standby
GPIO 32Buzzer (Korna)

🚀 Karşılaştığım Zorluklar ve Çözümler

Zorluk 1: Kinematik Normalizasyon

Joystick'ten gelen X, Y ve rotasyon değerlerini motor PWM'ine aktarırken en çok burada zorlandım. Üç eksen aynı anda geldiğinde toplam değerler kolayca ±300'e çıkıyordu ama PWM aralığı 0-255. Değerleri basitçe kırpmak yerine orantılı normalizasyon uyguladım — en yüksek mutlak değeri bulup tüm kanalları aynı oranda ölçeklendirdim. Böylece hareket yönü korunurken doyuma girme problemi çözüldü.

Zorluk 2: OV2640 Renk Tutarsızlığı

Otonom renk takip geliştirirken en çok uğraştığım konu buydu. OV2640 sensörü, özellikle mavi kanal için oldukça zayıf bir renk ayrımı yapıyor. Aydınlatma koşullarına göre renk değerleri çok değişiyor. Çözüm olarak:

  • Parlaklığı artırdım (brightness: 1)
  • Kontrastı artırdım (contrast: 1)
  • Renk doygunluğunu yükselttim (saturation: 2)
  • Her renk için ayrı eşik değerleri belirledim

Zorluk 3: Çift Çekirdek Yönetimi

Otonom algılama task'ı sürekli kameradan kare alıp işlediğinde, aynı kamera donanımını MJPEG stream de kullanıyordu. Bu çakışmayı FreeRTOS ile çözdüm: algılama Core 0'da, HTTP sunucu Core 1'de çalışıyor. esp_camera_fb_get() ve esp_camera_fb_return() ile buffer yönetimini dikkatli bir şekilde yaptım.

Zorluk 4: Servo Titreşimi

İlk başta servoları standart 8-bit PWM ile sürdüğümde titreşim (jitter) çok fazlaydı. 16-bit çözünürlüğe geçince (65535 seviye) sorun büyük ölçüde çözüldü. Ayrıca 500-2500µs pulse aralığını kullanarak servonun tüm hareket aralığını doğru şekilde kapsadım.

Zorluk 5: WiFi ve ESP-NOW Aynı Kanalda

ESP-NOW, WiFi AP ile aynı kanalda çalışmak zorunda. Bunu sağlamak için her iki tarafta da kanal 1'e sabitledim. WIFI_IF_AP interface'ini kullanarak AP modunda ESP-NOW peer ekledim.

📐 Proje Akışı — Baştan Sona

  1. Tasarım: Mecanum şasiyi monte ettim, motor kablolarını lehimledim.
  2. Motor Testi: Multimetre ile her motor sürücüsünün voltaj çıkışını ölçtüm, TB6612'leri doğruladım.
  3. ESP32 Programlama: Önce alıcı ESP32'yi programladım, seri port üzerinden motor komutlarını test ettim.
  4. Kamera Entegrasyonu: ESP32-CAM'e web sunucu ve MJPEG stream kodunu yükledim.
  5. ESP-NOW Bağlantısı: İki ESP32'yi eşleştirdim, ilk kablosuz kontrol testini yaptım.
  6. Web Arayüzü: Joystick, hız kontrolü ve kamera panelini tasarladım.
  7. Otonom Mod: Renk algılama algoritmasını geliştirdim, FreeRTOS task yapısını kurdum.
  8. Pan-Tilt: Servo mekanizmasını monte ettim, PWM kodunu yazdım, web arayüzüne slider ekledim.
  9. Son Dokunuşlar: Korna, flash LED, güvenlik timeout'u ve UI cilalaması.

Sonuç

Kesis-Robot, başlangıçta basit bir uzaktan kumanda projesi olarak doğdu ama zamanla ciddi bir mühendislik çalışmasına dönüştü. Çift ESP32 mimarisi, ESP-NOW'un düşük gecikmeli haberleşmesi, Mecanum kinematik, otonom renk takip ve pan-tilt kamera — hepsi bir arada çalışan, tarayıcıdan kontrol edilebilen kompakt bir robot platformu ortaya çıktı.

Bu proje bana gömülü sistemlerde çoklu görev yönetimi (FreeRTOS), gerçek zamanlı görüntü işleme, kablosuz haberleşme protokolleri ve web tabanlı kontrol arayüzü tasarımı konularında muazzam bir deneyim kazandırdı.

Kod ve detaylı teknik döküman GitHub'daki esp32cam-robot deposunda mevcut. Bu altyapı, ileride daha gelişmiş otonomi (yapay zeka tabanlı nesne tespiti, yol planlama vb.) için sağlam bir temel oluşturuyor.