ESP32-CAM Kullanımı: Kurulum, Programlama ve Canlı Kamera Yayını
ESP32-CAM nasıl programlanır? AI-Thinker pinleri, MB ve USB-TTL ile yükleme, CameraWebServer, PSRAM, 0x105 ve brownout hataları, flaş LED, SD karta fotoğraf.
ESP32-CAM, yalnızca 27 × 40 mm boyutunda olmasına rağmen üzerinde ESP32 işlemcisi, 2 megapiksellik OV2640 kamera, microSD kart yuvası ve beyaz bir flaş LED'i taşıyan, uygun fiyatlı bir Wi-Fi kamera kartıdır. Tek başına ev ağına bağlanır, görüntüyü tarayıcıda canlı yayınlar, fotoğraf çekip SD karta kaydeder ya da internete gönderir. Güvenlik kamerası, kapı zili kamerası, bitki büyüme kaydı ve görüntülü robot araba gibi projelerin en popüler kartıdır; ancak üzerinde USB soketi olmadığı için ilk kurulumu, alışık olduğun ESP32 kartlarından biraz farklıdır.
Bu rehberde AI-Thinker ESP32-CAM kartının pinlerini, kartın ESP32-CAM-MB adaptörüyle ya da bir USB-TTL dönüştürücüyle nasıl programlandığını (IO0-GND bağlantısı dahil), hazır CameraWebServer örneğiyle tarayıcıda canlı görüntü almayı ve doğru PSRAM ile bölüm (partition) ayarlarını öğreneceksin. Ardından en sık görülen Camera init failed with error 0x105 ve brownout hatalarının sebeplerini, flaş LED'ini kontrol etmeyi ve butona basınca fotoğrafı microSD karta kaydeden kodu adım adım göreceksin.

ESP32-CAM nedir, nasıl çalışır?
Kartın kalbi, Wi-Fi ve Bluetooth'lu çift çekirdekli ESP32 yongasını taşıyan ESP32-S modülüdür. Kamera, ince bir şerit kabloyla (FPC) karttaki 24 pinli konnektöre takılır. ESP32, GPIO 0 üzerinden kameraya 20 MHz'lik bir saat sinyali (XCLK) gönderir ve kamerayı GPIO 26 ile 27'deki I2C benzeri SCCB hattından ayarlar. OV2640 sensörü görüntüyü kendi içinde JPEG olarak sıkıştırabildiği için ESP32'ye ham pikseller yerine küçük JPEG kareleri gelir. Bu kareler 8 bitlik paralel bir veri yoluyla karttaki 4 MB'lık PSRAM belleğe aktarılır, Wi-Fi da onları tarayıcıya ya da bir sunucuya taşır.
| Özellik | Değer |
|---|---|
| İşlemci | ESP32 (ESP32-S modülü), çift çekirdek, 240 MHz'e kadar |
| Kablosuz | Wi-Fi 802.11 b/g/n (yalnız 2,4 GHz), Bluetooth 4.2 ve BLE |
| Bellek | 520 KB dahili SRAM + 4 MB PSRAM, 4 MB flaş |
| Kamera | OV2640, 2 MP, en fazla 1600×1200 (UXGA), JPEG çıkışı |
| Depolama | microSD yuvası (resmi belgede 4 GB'a kadar) |
| Işık | Beyaz flaş LED'i (GPIO 4), arkada kırmızı durum LED'i (GPIO 33) |
| Besleme | 5V pininden 5 V (önerilen) ya da 3V3 pininden 3,3 V |
| Akım (5 V'ta) | Flaş kapalı yaklaşık 180 mA, flaş tam parlak yaklaşık 310 mA; Wi-Fi anlık tepeleri daha yüksek |
| Boyut | 27 × 40,5 × 4,5 mm |
AI-Thinker ESP32-CAM pinleri: hangileri boş?
Kartın iki kenarında 16 pin vardır ama bunların yalnızca birkaçı gerçekten serbesttir: kamera tek başına 15 GPIO kullanır, microSD yuvası da altı pini paylaşır. Aşağıdaki tablo kenardaki pinleri ve ne zaman kullanılabileceklerini özetler. ESP32'nin genel pin özelliklerini Pinout aracında da inceleyebilirsin.
| Pin | Görevi | Serbest kullanım |
|---|---|---|
| 5V | Besleme girişi (önerilen) | - |
| 3V3 | 3,3 V besleme girişi | - |
| GND (3 adet) | Toprak | - |
| VCC | Besleme çıkışı (varsayılan 3,3 V) | Karta besleme vermek için kullanma |
| U0R (GPIO 3) | Seri RX: programlama ve Serial Monitor | Yalnız seri port gerekmiyorsa |
| U0T (GPIO 1) | Seri TX: programlama ve Serial Monitor | Yalnız seri port gerekmiyorsa |
| GPIO 0 | Kamera saati (XCLK) ve açılış modu | Hayır; yalnız yüklemede GND'ye bağlanır |
| GPIO 16 | Birçok kartta PSRAM'e bağlı | Hayır |
| GPIO 2 | SD DATA0 | SD kullanılmıyorsa; açılış (strapping) pini |
| GPIO 4 | SD DATA1 ve flaş LED'i | SD 1-bit modda ya da SD yoksa |
| GPIO 12 | SD DATA2 | SD 1-bit modda ya da SD yoksa; açılışta LOW kalmalı |
| GPIO 13 | SD DATA3 | SD 1-bit modda ya da SD yoksa; en güvenli boş pin |
| GPIO 14 | SD CLK | SD kullanılmıyorsa |
| GPIO 15 | SD CMD | SD kullanılmıyorsa; açılış (strapping) pini |
| GPIO 33 | Kırmızı LED (kenarda değil) | Yalnız LED; LOW yazınca yanar |
ESP32-CAM nasıl programlanır? İki yol
Normal ESP32 kartlarında bilgisayarla konuşmayı sağlayan USB-seri yonga ESP32-CAM'de yoktur. Kod yüklemek için iki seçeneğin var: kartın altına takılan ESP32-CAM-MB adaptörü (CH340 yongalı, micro USB soketli küçük bir taban kartı) ya da elindeki bir USB-TTL dönüştürücü (FTDI, CH340, CP2102). Hangisini seçersen seç mantık aynıdır: ESP32, açılış anında GPIO 0 LOW ise kod bekleyen indirme moduna (download mode) girer, HIGH ise flaştaki programı çalıştırır. MB adaptöründeki IO0 düğmesi ve USB-TTL ile kurulan IO0-GND kablosu tam olarak bu işi yapar.

| USB-TTL dönüştürücü | ESP32-CAM | Açıklama |
|---|---|---|
| GND | GND | Ortak toprak |
| 5V | 5V | Kartı besler; dönüştürücünün 3,3 V çıkışı yetersiz kalır |
| TX | U0R (GPIO 3) | Çapraz bağlanır: verici alıcıya |
| RX | U0T (GPIO 1) | Çapraz bağlanır: alıcı vericiye |
| - | IO0 ile GND arası | Yalnız yükleme sırasında; yan yana duran iki pin arasına kısa bir kablo |
Dönüştürücünün üzerinde 3,3 V / 5 V seçme jumper'ı varsa onu 3,3 V konumuna al; böylece TX hattı ESP32'nin pinlerine uygun seviyede kalır. Kartın beslemesini ise dönüştürücünün 5V pininden ver. Çoğu dönüştürücünün 3,3 V çıkışı yalnızca 50–100 mA civarında akım verebilir; ESP32-CAM Wi-Fi'yi açtığı anda bu besleme çöker ve kart yeniden başlar.
Arduino IDE ayarları: kart, bölüm şeması ve PSRAM
- Arduino IDE'de Kart Yöneticisi'ni aç ve esp32 by Espressif Systems paketini kur; ayrıntılı anlatım Arduino IDE kurulumu yazısında.
- Araçlar > Kart > esp32 listesinden AI Thinker ESP32-CAM kartını seç.
- Partition Scheme ayarının Huge APP (3MB No OTA/1MB SPIFFS) olduğundan emin ol; kamera örneği en az 3 MB uygulama alanı ister.
- Kartı adaptöre ya da dönüştürücüye bağla ve Araçlar > Port menüsünden yeni beliren portu seç (Windows'ta COMx, macOS'ta /dev/cu.usbserial... ya da /dev/cu.wchusbserial...).
- Port hiç görünmüyorsa CH340 ya da CP2102 sürücüsünü kur ve veri taşıyan bir USB kablosu kullan.
| Ayar | Önerilen değer | Neden? |
|---|---|---|
| Kart | AI Thinker ESP32-CAM | PSRAM tanımı, 4 MB flaş ve doğru bölüm şeması hazır gelir |
| Partition Scheme | Huge APP (3MB No OTA/1MB SPIFFS) | CameraWebServer'ın istediği 3 MB'lık uygulama alanı |
| PSRAM | Bu kart tanımında hep açık | ESP32 Dev Module seçersen PSRAM: Enabled yap; ESP32 Wrover Module'de zaten açıktır |
| CPU Frequency | 240MHz (WiFi/BT) | Görüntü aktarımı ve Wi-Fi için en yüksek hız |
| Flash Mode / Flash Frequency | QIO / 80MHz | Yükleme ya da açılış sorununda DIO / 40MHz dene |
| Core Debug Level | None (sorun ararken Info) | Info seviyesinde kamera ve FPS bilgileri Serial Monitor'e yazılır |
| Upload Speed | 460800 (bu kartta sabit) | Yükleme sık kopuyorsa ESP32 Wrover Module seçip 115200 dene |
Adım adım ilk yükleme
- Kablolamayı yap: kartı MB adaptörüne pinleri hizalayarak tak ya da USB-TTL dönüştürücüyü yukarıdaki tabloya göre bağla. USB-TTL kullanıyorsan IO0 ile GND arasındaki kısa kabloyu da tak.
- Kartı indirme moduna al: MB adaptöründe IO0 düğmesini basılı tutarken RST düğmesine bas ve bırak, ardından IO0'ı bırak. USB-TTL'de IO0-GND kablosu takılıyken RST'ye basman yeterlidir. Otomatik reset devreli bazı MB adaptörleri düğmeye basmadan da yükler.
- Arduino IDE'de Yükle'ye tıkla. Çıktıda önce Connecting..., ardından yüzde olarak yazma ilerlemesi görünür.
- Hard resetting via RTS pin... satırı göründüğünde yükleme bitmiştir. USB-TTL kullanıyorsan IO0-GND kablosunu şimdi çıkar.
- Serial Monitor'ü 115200 baud hızında aç ve RST düğmesine bas; yeni program çalışmaya başlar.
1// ESP32-CAM ilk yükleme testi / ESP32-CAM first upload test
2const int KIRMIZI_LED = 33; // arkadaki kırmızı LED, ters mantık / red LED on the back, inverted logic
3
4void setup() {
5 Serial.begin(115200);
6 pinMode(KIRMIZI_LED, OUTPUT);
7 delay(500);
8
9 // PSRAM kontrolü / PSRAM check
10 if (psramFound()) {
11 Serial.print("PSRAM bulundu / PSRAM found: ");
12 Serial.print(ESP.getPsramSize());
13 Serial.println(" bayt / bytes");
14 } else {
15 Serial.println("PSRAM yok / No PSRAM");
16 }
17}
18
19void loop() {
20 digitalWrite(KIRMIZI_LED, LOW); // LOW = yanar / LOW = on
21 delay(500);
22 digitalWrite(KIRMIZI_LED, HIGH); // HIGH = söner / HIGH = off
23 delay(500);
24}Kod yüklendiyse kartın arkasındaki küçük kırmızı LED yarım saniye aralıkla yanıp söner. Bu LED ters mantıkla çalışır: LOW yazınca yanar, HIGH yazınca söner. Serial Monitor'de yaklaşık 4 milyon baytlık PSRAM görmelisin; PSRAM yok yazıyorsa kart seçimini kontrol et, düzelmiyorsa kartında PSRAM yongası olmayabilir. Kamera örneğine geçmeden önce bu kısa testi yapmak, sorunun yüklemede mi yoksa kamerada mı olduğunu baştan ayırır.
CameraWebServer örneği: tarayıcıda canlı görüntü
- Dosya > Örnekler > ESP32 > Camera > CameraWebServer örneğini aç.
- Kamera modelini seç: yeni sürümlerde board_config.h sekmesindeki, eski sürümlerde ana dosyanın başındaki listede CAMERA_MODEL_ESP_EYE satırının başına // ekle, CAMERA_MODEL_AI_THINKER satırının başındaki // işaretini sil.
- ssid ve password satırlarına 2,4 GHz Wi-Fi ağının adını ve şifresini yaz.
- Kartı indirme moduna al ve kodu yükle; ardından IO0 bağlantısını kaldırıp RST'ye bas.
- Serial Monitor'de Camera Ready! Use 'http://192.168.1.45' to connect benzeri bir satır göreceksin; bu adresi aynı ağa bağlı bir telefonun ya da bilgisayarın tarayıcısında aç.
- Sayfadaki Start Stream düğmesiyle canlı görüntüyü başlat, Get Still ile tek bir fotoğraf çek.
1// board_config.h (eski sürümlerde CameraWebServer.ino) / (CameraWebServer.ino in older versions)
2//#define CAMERA_MODEL_ESP_EYE // Has PSRAM <- kapat / comment out
3#define CAMERA_MODEL_AI_THINKER // Has PSRAM <- aç / enable
4
5// CameraWebServer.ino
6const char *ssid = "AgAdi"; // Wi-Fi adı / Wi-Fi name
7const char *password = "Sifre123"; // Wi-Fi şifresi / Wi-Fi passwordArayüz iki ayrı sunucuyla çalışır: ayar sayfası ve tek fotoğraf veren /capture adresi 80 numaralı porttadır, canlı yayın ise 81 numaralı portta /stream adresindedir (ör. http://192.168.1.45:81/stream). Bu yayın adresini kendi web sayfana ya da ev otomasyonu yazılımına ekleyebilirsin. Sol menüden çözünürlüğü, JPEG kalitesini, parlaklığı, kontrastı ve beyaz dengesini değiştirebilir, görüntü ters geliyorsa V-Flip ve H-Mirror anahtarlarını kullanabilirsin; yeni sürümlerde flaş için bir LED Intensity kaydırıcısı da vardır. Kart aynı anda genellikle tek bir canlı yayın izleyicisine hizmet verir, ikinci sekmede açtığın yayın donabilir. Sayfa hiç açılmıyorsa telefonun ve kartın aynı ağda olduğundan emin ol; bağlantı sorunları için ESP32 Wi-Fi'ye bağlanmıyor yazısına bakabilirsin.
ESP32-CAM çözünürlük ve FPS tablosu
OV2640 sensörü kâğıt üzerinde 1600×1200'de saniyede 15, 800×600'de 30, CIF boyutunda 60 kare üretebilir. Gerçekte ise kare hızını çoğunlukla Wi-Fi bağlantısı ve JPEG kare boyutu belirler: çözünürlük ve kalite arttıkça her kare büyür ve ağdan daha yavaş geçer. Aşağıdaki değerler, iyi bir Wi-Fi sinyalinde ve 10–12 JPEG kalitesinde CameraWebServer ile görülen yaklaşık aralıklardır. Kendi kartında ölçmek için Core Debug Level ayarını Info yap; yayın sırasında Serial Monitor her kare için MJPG: ... (x fps) biçiminde bir satır yazar.
| Çözünürlük | Piksel | Yaklaşık FPS (Wi-Fi yayını) | Ne için uygun? |
|---|---|---|---|
| QQVGA | 160×120 | 25–30 | Hareket algılama, çok zayıf ağ |
| QVGA | 320×240 | 20–30 | Robot araba, akıcı canlı görüntü |
| CIF | 400×296 | 15–25 | Küçük ekranda akıcı izleme |
| VGA | 640×480 | 10–20 | Genel amaçlı canlı izleme |
| SVGA | 800×600 | 8–15 | Daha net izleme; PSRAM'siz kullanılabilen en büyük boyut |
| XGA | 1024×768 | 5–10 | Ayrıntılı görüntü |
| HD | 1280×720 | 4–8 | Geniş (16:9) kadraj |
| SXGA | 1280×1024 | 3–6 | Fotoğraf |
| UXGA | 1600×1200 | 2–5 | En yüksek çözünürlükte fotoğraf |
Kendi kodunda çözünürlüğü, kaliteyi ve görüntünün yönünü, kamera başarıyla başlatıldıktan sonra sensör nesnesi üzerinden değiştirebilirsin. JPEG kalitesi 0–63 arasında bir sayıdır ve küçük sayı daha yüksek kalite demektir; 10'un altına inmek kareleri büyütür ve yarım görüntülere yol açabilir.
1// esp_camera_init() başarılı olduktan sonra / after esp_camera_init() succeeds
2sensor_t *s = esp_camera_sensor_get();
3s->set_framesize(s, FRAMESIZE_VGA); // 640x480 çözünürlük / resolution
4s->set_quality(s, 12); // 0-63: küçük = daha kaliteli, 10 altı önerilmez / lower = better, below 10 not advised
5s->set_vflip(s, 1); // görüntüyü dikey çevir / flip vertically
6s->set_hmirror(s, 1); // yatay ayna / mirror horizontally
7s->set_brightness(s, 1); // parlaklık -2..2 / brightness -2..2ESP32-CAM PSRAM ayarı neden bu kadar önemli?
ESP32'nin dahili belleği 520 KB'tır ve bunun önemli bir kısmını Wi-Fi yığını kullanır. 1600×1200'lük tek bir JPEG karesi ise sahneye ve kaliteye göre 100–250 KB tutabilir. Bu yüzden kamera sürücüsü kare tamponlarını (frame buffer) PSRAM'e yerleştirir. CameraWebServer, psramFound() fonksiyonuyla PSRAM olup olmadığına bakar: varsa en yüksek çözünürlükle ve iki kare tamponuyla başlar, yoksa çözünürlüğü SVGA (800×600) ile sınırlar ve tek tamponu dahili belleğe alır.
PSRAM etkin değilken yüksek çözünürlük istersen Serial Monitor'de frame buffer malloc failed ve ardından Camera init failed with error 0xffffffff mesajlarını görürsün. Çözüm, kart olarak AI Thinker ESP32-CAM'i seçmek (ESP32 Dev Module kullanıyorsan Araçlar > PSRAM: Enabled yapmak) ya da çözünürlüğü düşürüp kare tampon sayısını 1'e indirmektir. Bazı ucuz kopyalarda PSRAM yongası hiç bulunmayabilir; ilk test kodundaki PSRAM satırı bunu hemen gösterir.
Camera init failed with error 0x105 ve diğer kamera hataları
Kamera hatalarının büyük çoğunluğu üç sebepten birine dayanır: kodda yanlış kamera modeli, konnektöre iyi oturmamış şerit kablo ya da yetersiz besleme. Serial Monitor'deki hata kodunu okumak sebebi hızla daraltmanı sağlar:
| Serial Monitor mesajı | Anlamı | Çözüm |
|---|---|---|
| Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND) | ESP32, SCCB hattında hiçbir kamera bulamadı | CAMERA_MODEL_AI_THINKER seçili mi bak, şerit kabloyu çıkarıp yeniden tak, beslemeyi 5 V / 2 A yap |
| Detected camera not supported ve 0x106 | Yeni sürücü sürümlerinde aynı durum: kamera bulunamadı ya da tanınmadı | 0x105 ile aynı adımlar; sorun sürerse kamera modülünü değiştir |
| frame buffer malloc failed ve 0xffffffff | Kare tamponu için bellek ayrılamadı | PSRAM'i etkinleştir, çözünürlüğü düşür, fb_count değerini 1 yap |
| cam_hal: EV-VSYNC-OVF ya da FB-OVF | Yeni kare geldiğinde eskisi henüz işlenmemişti, kare atlandı | Ara sıra görünmesi zararsızdır; sık görünüyorsa çözünürlüğü düşür, Wi-Fi sinyalini iyileştir |
| NO-SOI (JPEG start marker missing) | Bozuk ya da eksik JPEG karesi | Beslemeyi ve şerit kabloyu kontrol et, xclk_freq_hz değerini 10000000 yap |
| Görüntü yarım, yeşil ya da çizgili | Kare tampona sığmadı ya da besleme gürültülü | JPEG kalitesini 12 ve üstüne çek, beslemeyi iyileştir |
Brownout hatası ve doğru besleme (5 V / 2 A)
Serial Monitor'de Brownout detector was triggered yazıp kart sürekli yeniden başlıyorsa ESP32'nin besleme gerilimi bir anlığına güvenli seviyenin altına inmiş demektir. ESP32-CAM, Wi-Fi vericisini açtığı ve kamera kare çekmeye başladığı anda kısa ama yüksek akım tepeleri çeker. Zayıf bir USB portu, ince ve uzun jumper kablolar ya da dönüştürücünün 3,3 V çıkışı bu tepeleri karşılayamaz. Kalıcı çözümler şunlardır:
- 5 V ve en az 2 A veren bir adaptör kullan ve beslemeyi kartın 5V pinine ver; kart üzerindeki regülatör bunu 3,3 V'a düşürür.
- Besleme kablolarını kısa ve kalın tut; breadboard ve uzun jumper kablolar gerilim düşümünü artırır.
- Kartın 5V ve GND pinleri arasına, karta olabildiğince yakın bir 470–1000 µF'lık elektrolitik kondansatör ekle (artı ucu 5V'a).
- Bilgisayardan besliyorsan USB çoklayıcı yerine kasanın arkasındaki bir porta doğrudan tak.
- Pille çalışacaksan bir 18650 pil ve 5 V yükseltici (boost) modül kullan; bu çözüm dizi hâlindeki AA pillerden çok daha kararlıdır.

İnternette brownout algılayıcısını kodla kapatan WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0) satırına sıkça rastlarsın. Bu satır yeniden başlamayı durdurur ama sorunu çözmez: gerilim düşmeye devam eder ve kart bu kez donabilir, bozuk kare üretebilir ya da flaşa yazarken veri kaybedebilir. Onu yalnızca geçici bir deneme için kullan; yeniden başlama mesajlarının tamamı ESP32 brownout ve Guru Meditation yazısında. Pil süresini hesaplarken kartın sürekli yayında ortalama 180 mA çektiğini düşün: 2600 mAh'lik bir 18650, %85 verimli bir yükselticiyle 5 V tarafında yaklaşık 1600 mAh eder, bu da 9 saat civarında yayın demektir. Kendi değerlerini Pil Ömrü Hesaplama aracıyla bulabilirsin; derin uykuda bile kartın regülatör ve PSRAM yüzünden yaklaşık 6 mA çektiğini unutma.
Flaş LED'ini (GPIO 4) kontrol etmek
Kartın ön yüzündeki parlak beyaz LED, GPIO 4'e bağlı bir transistör üzerinden sürülür; yani pin yalnızca transistörü açıp kapatır, LED'in yüksek akımı besleme hattından gelir. digitalWrite(4, HIGH) ile yanar, LOW ile söner. LED çok parlaktır ve uzun süre açık kalırsa hem kendisi hem kart ısınır; flaşı yalnızca fotoğraf çekerken birkaç yüz milisaniye yakmak en iyisidir. GPIO 4 aynı zamanda microSD kartın DATA1 hattı olduğundan, kart 4 bitlik modda kullanılırken flaş her okuma ve yazmada kendiliğinden yanıp söner. Bunu önlemek için SD kartı 1-bit modda başlat (SD_MMC.begin("/sdcard", true)); bazı kartlarda LED yine de çok hafif parlayabilir.
ESP32-CAM ile microSD karta fotoğraf kaydetmek
Aşağıdaki kod, GPIO 13'e bağlı butona her bastığında flaşı yakar, 1600×1200 çözünürlükte bir fotoğraf çeker ve microSD karta foto1.jpg, foto2.jpg... adlarıyla kaydeder. microSD kartı bilgisayarında FAT32 olarak biçimlendir; resmi belgeler 4 GB'a kadar kartlardan söz etse de uygulamada 16–32 GB'lık FAT32 kartlar da genellikle sorunsuz çalışır. Butonun bir bacağını GPIO 13'e, diğerini GND'ye bağla; kod dahili pull-up direncini açtığı için ek direnç gerekmez. Buton bağlantısının mantığı için Arduino'ya buton nasıl bağlanır? yazısına bakabilirsin.
1#include "esp_camera.h"
2#include "FS.h"
3#include "SD_MMC.h"
4
5// AI-Thinker ESP32-CAM kamera pinleri / AI-Thinker ESP32-CAM camera pins
6#define PWDN_GPIO_NUM 32
7#define RESET_GPIO_NUM -1
8#define XCLK_GPIO_NUM 0
9#define SIOD_GPIO_NUM 26
10#define SIOC_GPIO_NUM 27
11#define Y9_GPIO_NUM 35
12#define Y8_GPIO_NUM 34
13#define Y7_GPIO_NUM 39
14#define Y6_GPIO_NUM 36
15#define Y5_GPIO_NUM 21
16#define Y4_GPIO_NUM 19
17#define Y3_GPIO_NUM 18
18#define Y2_GPIO_NUM 5
19#define VSYNC_GPIO_NUM 25
20#define HREF_GPIO_NUM 23
21#define PCLK_GPIO_NUM 22
22
23#define FLAS_LED 4 // beyaz flaş LED'i / white flash LED
24#define BUTON 13 // butonun diğer ucu GND'de / other button leg to GND
25
26int fotoNo = 1; // sıradaki dosya numarası / next file number
27bool hazir = false; // kamera ve SD hazır mı? / are camera and SD ready?
28
29bool kameraBaslat() {
30 camera_config_t config = {};
31 config.ledc_channel = LEDC_CHANNEL_0;
32 config.ledc_timer = LEDC_TIMER_0;
33 config.pin_d0 = Y2_GPIO_NUM;
34 config.pin_d1 = Y3_GPIO_NUM;
35 config.pin_d2 = Y4_GPIO_NUM;
36 config.pin_d3 = Y5_GPIO_NUM;
37 config.pin_d4 = Y6_GPIO_NUM;
38 config.pin_d5 = Y7_GPIO_NUM;
39 config.pin_d6 = Y8_GPIO_NUM;
40 config.pin_d7 = Y9_GPIO_NUM;
41 config.pin_xclk = XCLK_GPIO_NUM;
42 config.pin_pclk = PCLK_GPIO_NUM;
43 config.pin_vsync = VSYNC_GPIO_NUM;
44 config.pin_href = HREF_GPIO_NUM;
45 config.pin_sccb_sda = SIOD_GPIO_NUM;
46 config.pin_sccb_scl = SIOC_GPIO_NUM;
47 config.pin_pwdn = PWDN_GPIO_NUM;
48 config.pin_reset = RESET_GPIO_NUM;
49 config.xclk_freq_hz = 20000000; // 20 MHz kamera saati / 20 MHz camera clock
50 config.pixel_format = PIXFORMAT_JPEG;
51
52 if (psramFound()) {
53 config.frame_size = FRAMESIZE_UXGA; // 1600x1200
54 config.jpeg_quality = 10; // küçük = daha kaliteli / lower = better quality
55 config.fb_count = 2;
56 config.fb_location = CAMERA_FB_IN_PSRAM;
57 config.grab_mode = CAMERA_GRAB_LATEST;
58 } else {
59 config.frame_size = FRAMESIZE_SVGA; // PSRAM yoksa 800x600 / 800x600 without PSRAM
60 config.jpeg_quality = 12;
61 config.fb_count = 1;
62 config.fb_location = CAMERA_FB_IN_DRAM;
63 config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
64 }
65
66 esp_err_t err = esp_camera_init(&config);
67 if (err != ESP_OK) {
68 Serial.printf("Camera init failed 0x%x (%s)\n", err, esp_err_to_name(err));
69 return false;
70 }
71 return true;
72}
73
74void fotoCek() {
75 digitalWrite(FLAS_LED, HIGH); // flaşı yak / flash on
76 delay(150); // pozlama otursun / let exposure settle
77
78 camera_fb_t *fb = esp_camera_fb_get(); // eski kareyi at / discard the stale frame
79 if (fb) esp_camera_fb_return(fb);
80 fb = esp_camera_fb_get(); // asıl fotoğraf / the real photo
81 digitalWrite(FLAS_LED, LOW); // flaşı söndür / flash off
82
83 if (!fb) {
84 Serial.println("Kare alinamadi / Capture failed");
85 return;
86 }
87
88 String yol = "/foto" + String(fotoNo) + ".jpg";
89 File dosya = SD_MMC.open(yol, FILE_WRITE);
90 if (dosya) {
91 dosya.write(fb->buf, fb->len); // JPEG verisini yaz / write the JPEG data
92 dosya.close();
93 Serial.printf("Kaydedildi / Saved: %s (%u bayt / bytes)\n", yol.c_str(), (unsigned)fb->len);
94 fotoNo++;
95 } else {
96 Serial.println("Dosya acilamadi / Could not open file");
97 }
98 esp_camera_fb_return(fb); // tamponu geri ver / return the buffer
99}
100
101void setup() {
102 Serial.begin(115200);
103 pinMode(BUTON, INPUT_PULLUP);
104
105 if (!kameraBaslat()) return; // kamera yoksa dur / stop without a camera
106
107 // 1-bit mod: GPIO 4, 12 ve 13 boşta kalır / 1-bit mode keeps GPIO 4, 12 and 13 free
108 if (!SD_MMC.begin("/sdcard", true)) {
109 Serial.println("SD kart takilamadi / SD card mount failed");
110 return;
111 }
112 if (SD_MMC.cardType() == CARD_NONE) {
113 Serial.println("SD kart yok / No SD card");
114 return;
115 }
116
117 pinMode(FLAS_LED, OUTPUT);
118 digitalWrite(FLAS_LED, LOW);
119
120 // Var olan fotoğrafların üzerine yazma / don't overwrite existing photos
121 while (SD_MMC.exists("/foto" + String(fotoNo) + ".jpg")) fotoNo++;
122
123 hazir = true;
124 Serial.println("Hazir, butona bas / Ready, press the button");
125}
126
127void loop() {
128 if (!hazir) { // hata varsa bekle / wait if setup failed
129 delay(1000);
130 return;
131 }
132 if (digitalRead(BUTON) == LOW) {
133 delay(30); // buton sıçramasını (bounce) önle / debounce
134 if (digitalRead(BUTON) == LOW) {
135 fotoCek();
136 while (digitalRead(BUTON) == LOW) delay(10); // bırakılmasını bekle / wait for release
137 }
138 }
139}Kod SD kartı 1-bit modda başlattığı için yalnızca GPIO 2, 14 ve 15'i kullanır; GPIO 4 flaşa, GPIO 13 de butona kalır. Fotoğraf çekmeden önce bir kare alınıp hemen geri verilir: kamera sürekli kare ürettiği için tampondaki ilk kare flaş yanmadan önce çekilmiş olabilir, otomatik pozlamanın yeni ışığa uyması için de kısa bir bekleme gerekir. Dosya numarası karttaki mevcut dosyalara bakılarak bulunur; böylece kart yeniden başlasa bile eski fotoğrafların üzerine yazılmaz. SD kartla veri kaydının genel kuralları için SD kart modülü yazısına göz atabilirsin.
MicroPython ve yeni nesil kamera kartları
ESP32-CAM'i MicroPython ile programlamak da mümkündür, ancak resmi MicroPython sürümünde kamera sürücüsü bulunmaz; kamera desteği eklenmiş topluluk firmware'lerini yüklemen gerekir. Bu yüzden başlangıç için Arduino IDE yolu çok daha sorunsuzdur. USB soketi olmayan bir kartla uğraşmak istemiyorsan, USB'si ve daha fazla belleği olan ESP32-S3 tabanlı kamera kartlarına (ör. Seeed XIAO ESP32S3 Sense ya da ESP32-S3-EYE) da bakabilirsin; CameraWebServer örneğinin model listesinde bu kartlar da yer alır.
ESP32-CAM ile proje fikirleri
- Hareket algılayınca fotoğraf: Bir PIR sensörü birini gördüğünde fotoğraf çek ve telefonuna gönder; adım adım anlatım ESP32-CAM ile Telegram'a fotoğraf yazısında.
- Zaman atlamalı (time-lapse) kayıt: Kart her 10 dakikada bir uyanıp fotoğraf çeksin, SD karta kaydetsin ve derin uykuya dönsün; bir bitkinin büyümesini ya da hava değişimini izle.
- Kapı zili kamerası: Zil butonuna basıldığında kapının önünü çek ve bir Telegram botu ile bildirim gönder.
- Görüntülü robot araba: QVGA çözünürlükte akıcı canlı yayınla aracı telefondan izleyerek sür.
- Evcil hayvan kamerası: Canlı yayını ev ağında izle, gerektiğinde flaşı web sayfasından yak.
- Kendi kontrol panelin: Canlı yayını kendi web sayfana göm, yanına röle ve sensör göstergeleri ekle; ESP32 WebSocket yazısı bu konuda yol gösterir.
Sık yapılan hatalar ve çözümleri
| Belirti | Olası sebep | Çözüm |
|---|---|---|
| Failed to connect to ESP32: No serial data received (eski sürümlerde Timed out waiting for packet header) | Kart indirme modunda değil ya da TX ve RX yanlış | IO0'ı GND'ye bağla ya da IO0 düğmesini kullan, RST'ye bas; TX'in U0R'ye, RX'in U0T'ye gittiğini kontrol et |
| Wrong boot mode detected (0x13) | Açılış anında GPIO 0 LOW değildi | IO0-GND bağlantısını yaptıktan sonra mutlaka RST'ye bas |
| Serial Monitor'de waiting for download | IO0 hâlâ GND'ye bağlı | IO0 kablosunu çıkar ve RST'ye bas |
| Serial Monitor'de anlamsız karakterler | Baud hızı yanlış | Serial Monitor'ü 115200 baud yap |
| Port listesinde kart yok | Sürücü eksik ya da kablo yalnız şarj kablosu | CH340 ya da CP2102 sürücüsünü kur, veri kablosu kullan |
| SD kart takılıyken yükleme başarısız | GPIO 2 hem SD hattı hem açılış pini | Yükleme sırasında microSD kartı çıkar |
| Görüntü çok yavaş ya da sık donuyor | Zayıf Wi-Fi sinyali ya da yüksek çözünürlük | VGA ya da QVGA'ya düş, kartı modeme yaklaştır, gerekirse harici anten kullan |
| Flaş sürekli hafif yanıyor | SD kart 4-bit modda ya da GPIO 4 boşta kalmış | SD'yi 1-bit modda başlat, GPIO 4'ü OUTPUT yapıp LOW yaz |
ESP32-CAM, uygun fiyatlı bir kartla Wi-Fi kamera yapmanın en kolay yoludur ve karşılaşılan zorlukların neredeyse tamamı programlama bağlantısından ya da beslemeden kaynaklanır. Bu iki konuyu doğru kurduğunda kart kendi web sunucusuyla canlı yayın yapar, fotoğraf çeker ve SD karta kaydeder. BlueGrays uygulamasında ESP32 ile Wi-Fi bağlantısı, web sunucu, mDNS, microSD'ye veri kaydı ve Telegram bildirimli hareket alarmı gibi projeleri devre şemaları ve hazır kodlarıyla adım adım bulabilirsin.
Sıkça sorulan sorular
ESP32-CAM nasıl programlanır?
ESP32-CAM'de USB soketi olmadığı için ESP32-CAM-MB adaptörü ya da bir USB-TTL dönüştürücü gerekir. Arduino IDE'de AI Thinker ESP32-CAM kartını seçer, kartı indirme moduna alırsın: GPIO 0 GND'ye bağlıyken (ya da MB'deki IO0 düğmesi basılıyken) RST'ye basarsın. Yükleme bitince IO0 bağlantısını kaldırıp yeniden RST'ye basman yeterlidir.
ESP32-CAM Arduino Uno ile programlanabilir mi?
Evet; Uno'nun RESET pinini GND'ye bağlarsan kartın USB yongası bir USB-seri köprü gibi çalışır. Bu durumda bağlantı çapraz değil düz yapılır: Uno'nun D0 (RX) pini U0R'ye, D1 (TX) pini U0T'ye gider ve IO0 yine GND'ye bağlanır. Uno'nun sinyalleri 5 V olduğu için bu yöntem ESP32'yi sınırda zorlar; kalıcı kullanım için MB adaptörü ya da 3,3 V seviyeli bir USB-TTL dönüştürücü daha güvenlidir.
ESP32-CAM kaç volt ile çalışır?
Kartı 5V pininden 5 V ile beslemek önerilir; kart üzerindeki regülatör bunu 3,3 V'a düşürür. 3V3 pininden 3,3 V vermek de mümkündür, ama kaynak Wi-Fi akım tepelerini karşılayamazsa kart sık sık yeniden başlar. En az 2 A verebilen bir adaptör brownout hatalarını büyük ölçüde önler.
ESP32-CAM Camera init failed hatası nasıl çözülür?
0x105 ya da 0x106 kodu kameranın hiç bulunamadığını gösterir: önce kodda CAMERA_MODEL_AI_THINKER'ın seçili olduğunu, sonra şerit kablonun konnektöre tam oturduğunu kontrol et ve beslemeyi 5 V / 2 A'e çıkar. Sorun sürerse kamera modülü bozuk olabilir. frame buffer malloc failed ile birlikte 0xffffffff görüyorsan PSRAM'i etkinleştir ya da çözünürlüğü düşür.
ESP32-CAM internet olmadan çalışır mı?
Evet. Görüntüyü izlemek için internete değil, yalnızca yerel bir ağa ihtiyaç vardır; ESP32-CAM WiFi.softAP() ile kendi Wi-Fi ağını da kurabilir ve tarayıcıda 192.168.4.1 adresinden açılır. Hiç ağ kullanmadan, fotoğrafları yalnızca microSD karta kaydeden bir kamera olarak da çalıştırabilirsin.
ESP32-CAM video kaydedebilir mi?
Hazır örnekler canlı görüntüyü MJPEG olarak yayınlar ve tek tek fotoğraf çeker; doğrudan bir video dosyası kaydetmez. Ardışık JPEG karelerini microSD karta yazarak AVI dosyası oluşturan topluluk projeleri vardır, ancak kare hızı düşük çözünürlükte bile sınırlıdır. Kartta mikrofon olmadığı için ses de kaydedilemez.
Bu yazıdan sonra yapabileceğin projeler
Tüm projeleri gör
ESP32 ile LED Yakma
ESP32 ile temel GPIO çıkışı kullanımını öğretir. Bir LED'i dijital pinden açıp kapatarak yanıp sönme efekti elde ederiz. Arduino UNO'daki klasik blink projesinin ESP32 versiyonu; Arduino ortamındaki temel blink komutları aynıdır, ancak ESP32'nin pin yerleşimi ve 3,3 V GPIO seviyeleri Arduino UNO'dan farklıdır.

ESP32 Dahili LED Yakma
ESP32 DevKit V1'in üzerindeki dahili (built-in) mavi LED'i yanıp söndürmek. Hiçbir harici bileşen gerekmez! ESP32 satın aldığında ilk denemen gereken proje. GPIO 2 dahili LED'e bağlıdır.

ESP32 Wi-Fi STA Bağlantısı (LCD Ekranlı)
Bu projede ESP32'yi Station (STA) modunda evdeki Wi-Fi ağına güvenli ve hata toleranslı şekilde bağlıyoruz. SSID/şifreyi `secrets.h` dosyasına ayırarak Git'e sızmasını önlüyor, otomatik yeniden bağlanma mekanizması kuruyor, RSSI sinyal seviyesini ve IP adresini I2C LCD ekranda gösteriyoruz. Dahili LED durum göstergesi olarak çalışır. Üretim seviyesi bir bağlantı yöneticisidir.

ESP32 Async Web Server (LCD'de IP Göstergeli)
Bu projede ESP32'yi aynı Wi-Fi ağındaki telefonunuzdan veya bilgisayarınızdan kontrol edebileceğiniz **asenkron bir web sunucusuna** dönüştürüyoruz. ESPAsyncWebServer kütüphanesi sayesinde sunucu birden fazla isteği aynı anda işleyebiliyor (klasik `WebServer.h` gibi tek istekte bloklamıyor). Tarayıcıdan ESP32'nin IP adresine bağlanıp ON/OFF butonlarına basarak (`/on` ve `/off` adresleri) GPIO 5'e bağlı LED'i açıp kapatabileceksiniz.

ESP32 mDNS: bluegrays-esp.local ile Cihaza Erişim (LCD Ekranlı)
Bu projede ESP32'ye mDNS (Multicast DNS) servisi ekleyerek IP adresi yerine `bluegrays-esp.local` gibi okunabilir bir host adıyla erişim sağlıyoruz. DHCP'nin verdiği IP değişse bile cihaza her zaman aynı isimle ulaşabilirsiniz. Üzerinde küçük bir web server da çalıştırarak tarayıcıdan `http://bluegrays-esp.local/` adresiyle LED kontrolü gönderiyoruz. I2C LCD ekranda hostname, IP ve LED durumu hem Türkçe hem İngilizce gösterilir. iOS, macOS ve Linux mDNS'i doğal olarak destekler; Windows'ta Bonjo

ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)
ESP32 ile zamanlı sıcaklık ve nem kayıt sistemi kur! Bu projede DHT22 sensörü ile dakikada bir sıcaklık/nem okuyup DS1307 RTC modülünden aldığın gerçek zaman etiketiyle microSD karta CSV formatında kaydediyoruz. OLED ekranda büyük font ile son sıcaklık değeri, nem yüzdesi, timestamp ve toplam kayıt sayısı canlı gösterilir. SD kart üzerindeki `/temp_log.csv` dosyası Excel/Google Sheets/Python pandas ile açılıp analiz edilebilir — sera monitörü, ev/oda sıcaklık takibi, laboratuvar veri toplama,

ESP32 Hareket Alarm Sistemi (PIR + Buzzer + LED + Telegram)
PIR sensörü hareket algıladığında buzzer ve LED'i aktif eden, aynı anda Telegram üzerinden sahibine anlık bildirim gönderen akıllı bir güvenlik alarm sistemidir. Tekrarlayan alarmların sıklığını sınırlamak için 30 saniyelik cooldown (bekleme süresi) mekanizması vardır; bu mekanizma PIR sensörünün yanlış algılamalarını doğrulamaz veya ortadan kaldırmaz. Ev güvenliği, garaj izleme, depo veya çalışma odası gibi alanlarda kullanılabilir. Telegram entegrasyonu sayesinde nerede olursanız olun anında h

ESP32 Hareket Algılama Alarmı
ESP32 ve PIR sensörü kullanılarak hazırlanan bu projede hareket algılandığında buzzer devreye girerek sesli alarm verir. Basit ve düşük maliyetli bir güvenlik sistemi uygulamasıdır. (Görseller temsilidir yazılara göre bağlayınız)
Diğer yazılar
BlueGrays uygulaması
Bu devreyi telefonunda adım adım kur
Devre şeması, kod ve parça listesi tek ekranda. 160'tan fazla Arduino, ESP32 ve Pico projesi seni bekliyor.
Telefonunla tara
Kamerayı koda tut; telefonunun uygulama mağazası açılır.
ya da mağazada aç

