IoT & Gömülü Sistemler

ESP32-CAM ile Uzaktan İzleme Sistemi Kurulumu

Fatih Algül
12.03.2026 352 görüntülenme

ESP32-CAM Nedir ve Neden Tercih Edilmeli?

ESP32-CAM, Espressif Systems tarafından üretilen ESP32-S çipini temel alan, üzerinde entegre kamera modülü (OV2640) bulunan kompakt bir geliştirme kartıdır. Wi-Fi ve Bluetooth desteği sayesinde IoT projelerinde sıklıkla tercih edilen bu kart, düşük maliyeti ve yüksek esnekliğiyle ev güvenliği, tarımsal izleme, endüstriyel denetim gibi pek çok alanda kullanılabilir.

Geleneksel IP kamera sistemlerine kıyasla ESP32-CAM'in öne çıkan avantajları şunlardır:

  • Düşük maliyet: Ortalama 5-10 dolar arasında temin edilebilir
  • Kompakt boyut: 27mm x 40.5mm gibi küçük bir form faktörü
  • Wi-Fi desteği: 802.11 b/g/n ile kablosuz bağlantı
  • MicroSD kart desteği: Yerel kayıt imkânı
  • Dahili LED flaş: Düşük ışık koşullarında aydınlatma
  • Esnek programlama: Arduino IDE veya PlatformIO ile kolayca programlanabilir

Gerekli Malzemeler

Uzaktan izleme sisteminizi kurmak için aşağıdaki malzemelere ihtiyacınız olacak:

  1. ESP32-CAM modülü (AI-Thinker modeli en yaygın olanıdır)
  2. FTDI USB-TTL dönüştürücü (programlama için, 3.3V destekli)
  3. Jumper kablolar (dişi-dişi, en az 5 adet)
  4. Mikro USB kablosu (FTDI için)
  5. 5V güç kaynağı (en az 500mA, tercihen 1A)
  6. MicroSD kart (isteğe bağlı, yerel kayıt için)
  7. 3D baskılı veya hazır muhafaza kutusu (isteğe bağlı)

Donanım Bağlantıları

ESP32-CAM modülünde dahili bir USB port bulunmadığından, programlama için bir FTDI dönüştürücü kullanmanız gerekir. Bağlantıları aşağıdaki şekilde yapın:

  • FTDI GNDESP32-CAM GND
  • FTDI VCC (5V)ESP32-CAM 5V
  • FTDI TXESP32-CAM U0R (RX)
  • FTDI RXESP32-CAM U0T (TX)
  • ESP32-CAM IO0ESP32-CAM GND (sadece programlama sırasında)

Önemli: IO0 pinini GND'ye bağlamak, kartı programlama (flash) moduna geçirir. Programlama tamamlandıktan sonra bu bağlantıyı mutlaka çıkarın ve kartı yeniden başlatın. Aksi takdirde kart normal çalışma moduna geçemez.

Arduino IDE Kurulumu

ESP32-CAM'i programlamak için Arduino IDE'yi hazırlamamız gerekir. Aşağıdaki adımları izleyin:

  1. Arduino IDE'yi indirin ve kurun (1.8.x veya 2.x sürümü)
  2. Dosya → Tercihler menüsüne gidin
  3. Ek Kart Yöneticisi URL'leri alanına şu adresi ekleyin:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  1. Araçlar → Kart → Kart Yöneticisi'ni açın ve esp32 paketini arayıp kurun
  2. Kart olarak AI Thinker ESP32-CAM'i seçin
  3. Upload Speed'i 115200 olarak ayarlayın

Web Sunuculu Kamera Yazılımı

Aşağıdaki kod, ESP32-CAM üzerinde bir web sunucu oluşturarak tarayıcı üzerinden canlı görüntü akışı sağlar. Bu temel kod üzerine hareket algılama, anlık görüntü yakalama ve bildirim gibi özellikler eklenebilir.

#include "esp_camera.h"
#include <WiFi.h>
#include "esp_http_server.h"

// Wi-Fi bilgilerinizi buraya girin
const char* ssid = "WIFI_ADINIZ";
const char* password = "WIFI_SIFRENIZ";

// AI-Thinker ESP32-CAM pin tanımlamaları
#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

// LED flaş pini
#define FLASH_GPIO_NUM     4

httpd_handle_t stream_httpd = NULL;

// MJPEG akış boundary tanımı
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";

// Akış handler fonksiyonu
static esp_err_t stream_handler(httpd_req_t *req) {
  camera_fb_t *fb = NULL;
  esp_err_t res = ESP_OK;
  char part_buf[64];

  res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
  if (res != ESP_OK) return res;

  while (true) {
    fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Kamera goruntusu alinamadi");
      res = ESP_FAIL;
    } else {
      size_t hlen = snprintf(part_buf, 64, _STREAM_PART, fb->len);
      res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY,
            strlen(_STREAM_BOUNDARY));
      if (res == ESP_OK) {
        res = httpd_resp_send_chunk(req, part_buf, hlen);
      }
      if (res == ESP_OK) {
        res = httpd_resp_send_chunk(req, (const char *)fb->buf,
              fb->len);
      }
      esp_camera_fb_return(fb);
    }
    if (res != ESP_OK) break;
  }
  return res;
}

// Ana sayfa handler fonksiyonu
static esp_err_t index_handler(httpd_req_t *req) {
  const char html[] = R"rawliteral(
    <!DOCTYPE html>
    <html>
    <head>
      <title>ESP32-CAM Izleme</title>
      <style>
        body { font-family: Arial; text-align: center;
               background: #1a1a2e; color: #eee; }
        img { max-width: 100%; border: 2px solid #0f3460; }
        h1 { color: #e94560; }
        .container { max-width: 800px; margin: 0 auto;
                     padding: 20px; }
        .btn { background: #0f3460; color: white; border: none;
               padding: 10px 20px; margin: 5px; cursor: pointer;
               border-radius: 5px; font-size: 16px; }
        .btn:hover { background: #e94560; }
      </style>
    </head>
    <body>
      <div class="container">
        <h1>ESP32-CAM Uzaktan Izleme</h1>
        <img src="/stream" id="stream">
        <br><br>
        <button class="btn"
          onclick="fetch('/flash?state=toggle')">
          Flash LED
        </button>
      </div>
    </body>
    </html>
  )rawliteral";

  httpd_resp_set_type(req, "text/html");
  return httpd_resp_send(req, html, strlen(html));
}

// Flash LED kontrolü
static esp_err_t flash_handler(httpd_req_t *req) {
  static bool flashState = false;
  flashState = !flashState;
  digitalWrite(FLASH_GPIO_NUM, flashState ? HIGH : LOW);
  httpd_resp_set_type(req, "text/plain");
  return httpd_resp_send(req, flashState ? "ON" : "OFF", -1);
}

void startServer() {
  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.server_port = 80;

  httpd_uri_t index_uri = {
    .uri       = "/",
    .method    = HTTP_GET,
    .handler   = index_handler,
    .user_ctx  = NULL
  };

  httpd_uri_t stream_uri = {
    .uri       = "/stream",
    .method    = HTTP_GET,
    .handler   = stream_handler,
    .user_ctx  = NULL
  };

  httpd_uri_t flash_uri = {
    .uri       = "/flash",
    .method    = HTTP_GET,
    .handler   = flash_handler,
    .user_ctx  = NULL
  };

  if (httpd_start(&stream_httpd, &config) == ESP_OK) {
    httpd_register_uri_handler(stream_httpd, &index_uri);
    httpd_register_uri_handler(stream_httpd, &stream_uri);
    httpd_register_uri_handler(stream_httpd, &flash_uri);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();

  // Flash LED pin ayarı
  pinMode(FLASH_GPIO_NUM, OUTPUT);
  digitalWrite(FLASH_GPIO_NUM, LOW);

  // Kamera yapılandırması
  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;

  // PSRAM varsa yüksek çözünürlük kullan
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
    Serial.println("PSRAM bulundu, yuksek cozunurluk aktif");
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
    Serial.println("PSRAM bulunamadi, dusuk cozunurluk aktif");
  }

  // Kamerayı başlat
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Kamera baslatilamadi, hata: 0x%x\n", err);
    return;
  }

  // Kamera sensör ayarları
  sensor_t *s = esp_camera_sensor_get();
  s->set_brightness(s, 1);
  s->set_contrast(s, 1);
  s->set_saturation(s, 0);
  s->set_whitebal(s, 1);
  s->set_awb_gain(s, 1);
  s->set_wb_mode(s, 0);

  // Wi-Fi bağlantısı
  WiFi.begin(ssid, password);
  WiFi.setSleep(false);

  Serial.print("WiFi'ye baglaniliyor");
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 30) {
    delay(500);
    Serial.print(".");
    attempts++;
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println();
    Serial.println("WiFi baglantisi basarili!");
    Serial.print("Kamera adresi: http://");
    Serial.println(WiFi.localIP());
    startServer();
  } else {
    Serial.println();
    Serial.println("WiFi baglantisi basarisiz!");
    ESP.restart();
  }
}

void loop() {
  // Bağlantı kopması durumunda yeniden bağlan
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi baglantisi koptu, yeniden deneniyor...");
    WiFi.reconnect();
    delay(5000);
    if (WiFi.status() != WL_CONNECTED) {
      ESP.restart();
    }
  }
  delay(10000);
}

Kodu Yükleme Adımları

  1. FTDI bağlantılarını yapın ve IO0 pinini GND'ye bağlayın
  2. Arduino IDE'de doğru port ve kart seçili olduğundan emin olun
  3. Koddaki WIFI_ADINIZ ve WIFI_SIFRENIZ değerlerini kendi ağ bilgilerinizle değiştirin
  4. Yükle butonuna basın
  5. Konsolda "Connecting..." mesajı görünürken ESP32-CAM üzerindeki RST butonuna basın
  6. Yükleme tamamlandıktan sonra IO0-GND bağlantısını çıkarın
  7. RST butonuna tekrar basarak kartı yeniden başlatın
  8. Seri monitörü 115200 baud hızında açın ve IP adresini not edin
  9. Tarayıcınızda gösterilen IP adresine gidin (örn: http://192.168.1.105)

Uzaktan Erişim Yapılandırması

ESP32-CAM varsayılan olarak yalnızca yerel ağınızda erişilebilir durumdadır. Dışarıdan erişim sağlamak için birkaç yöntem kullanabilirsiniz:

1. Port Yönlendirme (Port Forwarding)

Router ayarlarınızdan 80 numaralı portu ESP32-CAM'in yerel IP adresine yönlendirin. Ancak bu yöntem güvenlik riskleri taşır ve statik IP veya DDNS hizmeti gerektirir.

2. Reverse Tunnel Servisleri

Cloudflare Tunnel, ngrok veya PageKite gibi servisler NAT arkasındaki cihazlarınıza güvenli bir şekilde dışarıdan erişim sağlar. Bu yöntem port yönlendirmeye göre çok daha güvenlidir. Ancak bu servisleri ESP32-CAM üzerinde doğrudan çalıştıramazsınız; yerel ağınızda bir aracı cihaz (Raspberry Pi, bilgisayar vb.) gerekir.

3. MQTT ile Bildirim Sistemi

Sürekli akış yerine olay tabanlı bir mimari tercih ediyorsanız, ESP32-CAM'den bir MQTT broker'a (örneğin Mosquitto) anlık görüntüler veya hareket algılama bildirimleri gönderebilirsiniz. Bu yöntem bant genişliği tüketimini önemli ölçüde azaltır.

Performans İyileştirmeleri

ESP32-CAM'den en iyi performansı almak için aşağıdaki önerilere dikkat edin:

  • Çözünürlüğü ihtiyaca göre ayarlayın: Sürekli akış için FRAMESIZE_VGA veya FRAMESIZE_SVGA yeterlidir. Yüksek çözünürlük FPS değerini düşürür.
  • JPEG kalitesini dengeleyin: jpeg_quality değeri 10-15 arası çoğu senaryo için idealdir. Düşük değer daha iyi kalite ancak daha büyük dosya boyutu demektir.
  • Wi-Fi sinyalini güçlü tutun: ESP32-CAM'in dahili anteni zayıftır. Harici anten bağlantısı destekleyen modellerde harici anten kullanmayı tercih edin. Bunun için kart üzerindeki 0 ohm direnci harici anten padına lehimlemeniz gerekir.
  • Güç kaynağına dikkat edin: Yetersiz güç kaynağı kararsız çalışmaya, ani yeniden başlamalara ve kamera hatalarına neden olur. USB'den besleme yerine düzenli bir 5V/1A adaptör kullanın.
  • Isınmayı göz önünde bulundurun: Sürekli akış sırasında ESP32-CAM ısınabilir. Kapalı muhafazalarda havalandırma delikleri bırakın.

Sık Karşılaşılan Sorunlar ve Çözümleri

Kamera başlatılamadı hatası (0x20001)

Bu genellikle kamera modülünün düzgün oturmadığını gösterir. Kamera ribbon kablosunu çıkarıp tekrar takın, altın kontakların konnektöre doğru baktığından emin olun. Ayrıca güç kaynağınızın yeterli akım sağladığını kontrol edin.

Wi-Fi bağlantısı kurulamıyor

SSID ve şifrenin doğru olduğunu kontrol edin. ESP32-CAM yalnızca 2.4 GHz ağları destekler; 5 GHz ağlara bağlanamaz. Router'ınızda MAC filtreleme aktifse ESP32-CAM'in MAC adresini beyaz listeye ekleyin.

Görüntü bulanık veya karanlık

Kamera lensinin üzerindeki koruyucu plastiği çıkardığınızdan emin olun. Lens odağını, lensi yavaşça saat yönünde veya tersine çevirerek manuel olarak ayarlayabilirsiniz. Düşük ışık ortamlarında set_brightness ve set_gainceiling değerlerini artırmayı deneyin.

Akış donuyor veya çok yavaş

Çözünürlüğü düşürün, fb_count değerini 2 yapın (PSRAM gerektirir) ve Wi-Fi sinyal gücünü kontrol edin. Aynı anda birden fazla istemcinin bağlanması performansı önemli ölçüde düşürür.

Güvenlik Önerileri

Bir izleme sistemi kurarken güvenliği göz ardı etmemelisiniz:

  • HTTP yerine HTTPS: ESP32-CAM'in sınırlı kaynakları nedeniyle doğrudan TLS zordur, ancak bir reverse proxy (nginx) arkasına alarak HTTPS sağlayabilirsiniz.
  • Temel kimlik doğrulama: Web sunucusuna en azından basit bir kullanıcı adı ve şifre doğrulaması ekleyin. HTTP header'larında Authorization kontrolü yaparak yetkisiz erişimi engelleyebilirsiniz.
  • Ağ izolasyonu: IoT cihazlarınızı ana ağınızdan ayrı bir VLAN veya misafir ağında tutun.
  • Firmware güncellemeleri: OTA (Over-The-Air) güncelleme desteği ekleyerek güvenlik yamalarını kolayca uygulayabilirsiniz.

Sonuç ve İleri Adımlar

ESP32-CAM ile temel bir uzaktan izleme sistemi kurmak oldukça basit ve ekonomiktir. Bu temel yapı üzerine ekleyebileceğiniz özelliklerden bazıları:

  • PIR sensörü ile hareket algılama: GPIO 13 veya 15 pinlerine bir PIR sensör bağlayarak yalnızca hareket olduğunda kayıt veya bildirim gönderebilirsiniz
  • MicroSD karta kayıt: Zamanlı veya olay tabanlı görüntü kaydetme
  • Telegram bot entegrasyonu: Hareket algılandığında Telegram üzerinden anlık görüntü gönderme
  • Çoklu kamera desteği: Birden fazla ESP32-CAM'i merkezi bir panelde birleştirme
  • Güneş paneli ile besleme: Dış mekân kullanımı için enerji bağımsız sistem kurulumu
  • Deep sleep modu: Pil ömrünü uzatmak için belirli aralıklarla uyandırma ve görüntü gönderme

ESP32-CAM, profesyonel güvenlik kameralarının yerini alacak bir çözüm olmasa da, hobi projeleri, prototipleme ve özelleştirilmiş izleme senaryoları için son derece güçlü ve esnek bir platformdur. Açık kaynak ekosistemi ve geniş topluluk desteği sayesinde hayal gücünüzün sınırlarına kadar genişletebileceğiniz projeler oluşturabilirsiniz.

Yazar Hakkında
Fatih Algül
TechSoft Solutions
Proje mi var?

Yazılım, IoT veya otomasyon konularında destek almak ister misiniz?

İletişime Geç