Componenti · 14 min di lettura

ESP32-CAM: guida per programmarla, streaming video e foto su SD

Come programmare l'ESP32-CAM: pinout AI-Thinker, caricamento con ESP32-CAM-MB o USB-TTL, CameraWebServer, PSRAM, errori 0x105 e brownout, flash e foto su SD.

L'ESP32-CAM è una scheda telecamera Wi-Fi economica che, pur misurando solo 27 × 40 mm, integra un processore ESP32, una fotocamera OV2640 da 2 megapixel, uno slot per scheda microSD e un LED flash bianco. Da sola si collega alla rete di casa, trasmette il video in diretta al browser, scatta foto e le salva sulla scheda SD o le invia su internet. È la scheda più usata per telecamere di sorveglianza, videocitofoni, time-lapse della crescita delle piante e robot car con telecamera, ma poiché non ha una presa USB, la messa in funzione è un po' diversa da quella delle schede ESP32 a cui forse sei abituato.

In questa guida scoprirai il pinout dell'ESP32-CAM di AI-Thinker, come programmarla con l'adattatore ESP32-CAM-MB o con un convertitore USB-TTL (compreso il collegamento IO0-GND), come vedere l'immagine in diretta nel browser con l'esempio CameraWebServer e quali impostazioni di PSRAM e di partizione usare. Poi vedrai le cause degli errori più comuni, Camera init failed with error 0x105 e brownout, controllerai il LED flash e scriverai uno sketch che salva una foto sulla microSD quando premi un pulsante.

Modulo telecamera ESP32-CAM di AI-Thinker
ESP32-CAM: modulo ESP32-S, fotocamera OV2640, slot microSD e LED flash su un'unica scheda. Non c'è la presa USB, quindi per programmarla serve un adattatore.

Cos'è l'ESP32-CAM e come funziona?

Il cuore della scheda è il modulo ESP32-S, che contiene il chip ESP32 dual core con Wi-Fi e Bluetooth. La fotocamera si inserisce in un connettore a 24 pin della scheda tramite un sottile cavo flat (FPC). L'ESP32 invia alla fotocamera un segnale di clock a 20 MHz (XCLK) sul GPIO 0 e la configura attraverso il bus SCCB, simile all'I2C, sui GPIO 26 e 27. Poiché il sensore OV2640 sa comprimere da solo l'immagine in JPEG, all'ESP32 arrivano piccoli fotogrammi JPEG invece di pixel grezzi. Questi fotogrammi passano su un bus dati parallelo a 8 bit fino ai 4 MB di PSRAM della scheda, e il Wi-Fi li porta al browser o a un server.

CaratteristicaValore
ProcessoreESP32 (modulo ESP32-S), dual core, fino a 240 MHz
WirelessWi-Fi 802.11 b/g/n (solo 2,4 GHz), Bluetooth 4.2 e BLE
Memoria520 KB di SRAM interna + 4 MB di PSRAM, 4 MB di flash
FotocameraOV2640, 2 MP, fino a 1600×1200 (UXGA), uscita JPEG
ArchiviazioneSlot microSD (fino a 4 GB secondo la documentazione ufficiale)
LuceLED flash bianco (GPIO 4), LED di stato rosso sul retro (GPIO 33)
Alimentazione5 V sul pin 5V (consigliato) oppure 3,3 V sul pin 3V3
Corrente (a 5 V)Circa 180 mA con flash spento, circa 310 mA con flash alla massima luminosità; i picchi del Wi-Fi sono più alti
Dimensioni27 × 40,5 × 4,5 mm

Pinout dell'ESP32-CAM AI-Thinker: quali pin sono liberi?

Sui due lati della scheda ci sono 16 pin, ma solo pochi sono davvero liberi: la fotocamera da sola usa 15 GPIO e lo slot microSD ne condivide altri sei. La tabella riassume i pin sui lati e quando puoi usarli. Puoi consultare anche le caratteristiche generali dei pin dell'ESP32 nello strumento Pinout.

PinFunzioneUso libero?
5VIngresso di alimentazione (consigliato)-
3V3Ingresso di alimentazione a 3,3 V-
GND (3 pin)Massa-
VCCUscita di alimentazione (3,3 V di default)Non usarlo per alimentare la scheda
U0R (GPIO 3)RX seriale: programmazione e Monitor serialeSolo se non serve la porta seriale
U0T (GPIO 1)TX seriale: programmazione e Monitor serialeSolo se non serve la porta seriale
GPIO 0Clock della fotocamera (XCLK) e modalità di avvioNo; va a GND solo durante il caricamento
GPIO 16Collegato alla PSRAM su molte schedeNo
GPIO 2SD DATA0Se la SD non è usata; pin di strapping
GPIO 4SD DATA1 e LED flashCon la SD in modalità 1 bit o senza SD
GPIO 12SD DATA2Con la SD in modalità 1 bit o senza SD; deve essere LOW all'avvio
GPIO 13SD DATA3Con la SD in modalità 1 bit o senza SD; il pin libero più sicuro
GPIO 14SD CLKSe la SD non è usata
GPIO 15SD CMDSe la SD non è usata; pin di strapping
GPIO 33LED rosso (non sui lati)Solo LED; si accende con LOW
Il pin VCC non è un ingresso ma l'uscita del regolatore della scheda e di default fornisce 3,3 V. Collegarci 5 V porta la linea a 3,3 V direttamente a 5 V e può bruciare l'ESP32: alimenta sempre la scheda dal pin 5V. Inoltre, se il GPIO 12 è HIGH all'avvio, l'ESP32 prova a far funzionare la flash a 1,8 V e la scheda non parte; non collegare a questo pin una resistenza di pull-up né un modulo che lo porti a HIGH.

Come si programma l'ESP32-CAM? Due modi

Il chip USB-seriale che permette alle normali schede ESP32 di comunicare con il computer sull'ESP32-CAM non c'è. Per caricare il codice hai due possibilità: l'adattatore ESP32-CAM-MB, che si innesta sotto la scheda (una piccola base con chip CH340 e presa micro USB), oppure un convertitore USB-TTL che hai già (FTDI, CH340, CP2102). Qualunque strada tu scelga, il principio è lo stesso: se all'avvio il GPIO 0 è LOW, l'ESP32 entra in modalità download e aspetta il codice; se è HIGH, esegue il programma nella flash. Il pulsante IO0 dell'adattatore MB e il filo IO0-GND aggiunto con il convertitore USB-TTL fanno esattamente questo.

Convertitore USB-TTL CP2102
Convertitore USB-TTL CP2102: per programmare l'ESP32-CAM bastano i pin GND, 5V, TX e RX.
Convertitore USB-TTLESP32-CAMNota
GNDGNDMassa comune
5V5VAlimenta la scheda; l'uscita a 3,3 V del convertitore non basta
TXU0R (GPIO 3)Incrociato: trasmettitore verso ricevitore
RXU0T (GPIO 1)Incrociato: ricevitore verso trasmettitore
-Tra IO0 e GNDSolo durante il caricamento; un filo corto tra i due pin vicini

Se il convertitore ha un jumper per scegliere tra 3,3 V e 5 V, mettilo su 3,3 V, così la linea TX resta a un livello adatto ai pin dell'ESP32. Alimenta però la scheda dal pin 5V del convertitore. L'uscita a 3,3 V della maggior parte dei convertitori fornisce solo circa 50–100 mA; appena l'ESP32-CAM accende il Wi-Fi, questa alimentazione crolla e la scheda si riavvia.

Impostazioni dell'Arduino IDE: scheda, schema di partizione e PSRAM

  1. Apri il Gestore schede dell'Arduino IDE e installa il pacchetto esp32 by Espressif Systems; i dettagli sono nella guida installare l'Arduino IDE.
  2. Scegli la scheda AI Thinker ESP32-CAM da Strumenti > Scheda > esp32.
  3. Verifica che Partition Scheme sia impostato su Huge APP (3MB No OTA/1MB SPIFFS); l'esempio della fotocamera richiede almeno 3 MB per l'applicazione.
  4. Collega la scheda all'adattatore o al convertitore e scegli la nuova porta da Strumenti > Porta (COMx su Windows, /dev/cu.usbserial... o /dev/cu.wchusbserial... su macOS).
  5. Se non compare nessuna porta, installa il driver CH340 o CP2102 e usa un cavo USB che trasmetta dati.
ImpostazioneValore consigliatoPerché?
SchedaAI Thinker ESP32-CAMPSRAM, 4 MB di flash e schema di partizione corretto già impostati
Partition SchemeHuge APP (3MB No OTA/1MB SPIFFS)I 3 MB di applicazione richiesti da CameraWebServer
PSRAMSempre attiva su questa schedaCon ESP32 Dev Module scegli PSRAM: Enabled; con ESP32 Wrover Module è già attiva
CPU Frequency240MHz (WiFi/BT)Massima velocità per immagini e Wi-Fi
Flash Mode / Flash FrequencyQIO / 80MHzSe il caricamento o l'avvio falliscono, prova DIO / 40MHz
Core Debug LevelNone (Info per la diagnosi)Con Info il Monitor seriale mostra i dati della fotocamera e gli FPS
Upload Speed460800 (fissa su questa scheda)Se il caricamento si interrompe spesso, scegli ESP32 Wrover Module e prova 115200
Apri sempre il Monitor seriale a 115200 baud. I messaggi di avvio arrivano solo al momento del reset, quindi se la finestra è vuota premi il pulsante RST della scheda. Se compare waiting for download, IO0 è ancora collegato a GND; togli il filo, premi di nuovo RST e il tuo programma parte.

Il primo caricamento passo dopo passo

  1. Fai i collegamenti: inserisci la scheda sull'adattatore MB con i pin allineati oppure collega il convertitore USB-TTL come nella tabella sopra. Se usi il convertitore USB-TTL, aggiungi anche il filo corto tra IO0 e GND.
  2. Metti la scheda in modalità download: sull'adattatore MB tieni premuto il pulsante IO0, premi e rilascia RST, poi rilascia IO0. Con il convertitore USB-TTL basta premere RST mentre il filo IO0-GND è inserito. Alcuni adattatori MB con circuito di reset automatico caricano anche senza premere nulla.
  3. Clicca su Carica nell'Arduino IDE. Nell'output compare prima Connecting... e poi l'avanzamento della scrittura in percentuale.
  4. Quando appare la riga Hard resetting via RTS pin..., il caricamento è finito. Se usi il convertitore USB-TTL, togli adesso il filo IO0-GND.
  5. Apri il Monitor seriale a 115200 baud e premi RST: il nuovo programma parte.
Arduino (C++)
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}

Se il caricamento è andato a buon fine, il piccolo LED rosso sul retro lampeggia ogni mezzo secondo. Questo LED funziona a logica invertita: si accende con LOW e si spegne con HIGH. Nel Monitor seriale dovresti vedere circa 4 milioni di byte di PSRAM; se compare No PSRAM, controlla la scheda selezionata e, se non cambia nulla, la tua scheda potrebbe non avere il chip PSRAM. Fare questo breve test prima dell'esempio della fotocamera ti dice subito se il problema è nel caricamento o nella fotocamera.

L'esempio CameraWebServer: immagine in diretta nel browser

  1. Apri File > Esempi > ESP32 > Camera > CameraWebServer.
  2. Scegli il modello di fotocamera: nell'elenco della scheda board_config.h (versioni recenti) o all'inizio del file principale (versioni vecchie), aggiungi // davanti alla riga CAMERA_MODEL_ESP_EYE e togli le // davanti a CAMERA_MODEL_AI_THINKER.
  3. Scrivi nelle righe ssid e password il nome e la password della tua rete Wi-Fi a 2,4 GHz.
  4. Metti la scheda in modalità download e carica lo sketch; poi togli il collegamento IO0 e premi RST.
  5. Nel Monitor seriale vedrai una riga come Camera Ready! Use 'http://192.168.1.45' to connect; apri questo indirizzo nel browser di uno smartphone o di un computer collegato alla stessa rete.
  6. Avvia l'immagine in diretta con il pulsante Start Stream oppure scatta una singola foto con Get Still.
Arduino (C++)
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 password

L'interfaccia usa due server separati: la pagina delle impostazioni e l'indirizzo /capture, che restituisce una singola foto, sono sulla porta 80, mentre lo streaming è su /stream alla porta 81 (es. http://192.168.1.45:81/stream). Puoi inserire questo indirizzo nella tua pagina web o in un software di domotica. Nel menu a sinistra puoi cambiare risoluzione, qualità JPEG, luminosità, contrasto e bilanciamento del bianco; se l'immagine è capovolta, usa gli interruttori V-Flip e H-Mirror, e le versioni recenti hanno anche un cursore LED Intensity per il flash. Di solito la scheda serve un solo spettatore dello streaming alla volta, e uno streaming aperto in una seconda scheda del browser può bloccarsi. Se la pagina non si apre, verifica che smartphone e scheda siano sulla stessa rete; per i problemi di connessione leggi l'ESP32 non si connette al Wi-Fi.

Tabella di risoluzione e FPS dell'ESP32-CAM

Sulla carta il sensore OV2640 produce 15 fotogrammi al secondo a 1600×1200, 30 a 800×600 e 60 in formato CIF. In pratica la frequenza dipende soprattutto dalla connessione Wi-Fi e dalle dimensioni dei fotogrammi JPEG: aumentando risoluzione e qualità, ogni fotogramma diventa più pesante e attraversa la rete più lentamente. I valori qui sotto sono intervalli indicativi ottenuti con CameraWebServer, un buon segnale Wi-Fi e qualità JPEG 10–12. Per misurare la tua scheda, imposta Core Debug Level su Info: durante lo streaming il Monitor seriale scrive per ogni fotogramma una riga come MJPG: ... (x fps).

RisoluzionePixelFPS indicativi (streaming Wi-Fi)Ideale per
QQVGA160×12025–30Rilevamento di movimento, reti molto deboli
QVGA320×24020–30Robot car, video in diretta fluido
CIF400×29615–25Visione fluida su schermi piccoli
VGA640×48010–20Video in diretta per uso generale
SVGA800×6008–15Immagine più nitida; dimensione massima senza PSRAM
XGA1024×7685–10Immagini dettagliate
HD1280×7204–8Inquadratura ampia (16:9)
SXGA1280×10243–6Foto
UXGA1600×12002–5Foto alla massima risoluzione

Nel tuo codice puoi cambiare risoluzione, qualità e orientamento dell'immagine tramite l'oggetto sensore, dopo che la fotocamera è stata avviata correttamente. La qualità JPEG è un numero da 0 a 63 e un numero più basso significa qualità più alta; scendere sotto 10 rende i fotogrammi più pesanti e può produrre immagini a metà.

Arduino (C++)
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..2

Perché l'impostazione PSRAM dell'ESP32-CAM è così importante?

La memoria interna dell'ESP32 è di 520 KB e buona parte la usa lo stack Wi-Fi. Un singolo fotogramma JPEG a 1600×1200, invece, può occupare da 100 a 250 KB a seconda della scena e della qualità. Per questo il driver della fotocamera mette i buffer dei fotogrammi (frame buffer) nella PSRAM. CameraWebServer controlla con la funzione psramFound() se la PSRAM c'è: se c'è, parte alla risoluzione massima con due buffer; altrimenti limita la risoluzione a SVGA (800×600) e tiene un solo buffer nella memoria interna.

Se chiedi una risoluzione alta senza PSRAM attiva, il Monitor seriale mostra frame buffer malloc failed e poi Camera init failed with error 0xffffffff. La soluzione è scegliere AI Thinker ESP32-CAM come scheda (con ESP32 Dev Module imposta Strumenti > PSRAM: Enabled) oppure abbassare la risoluzione e ridurre i buffer a 1. Alcuni cloni economici potrebbero non avere affatto il chip PSRAM; la riga PSRAM del primo sketch di prova lo rivela subito.

Camera init failed with error 0x105 e gli altri errori della fotocamera

La maggior parte degli errori della fotocamera ha una di tre cause: modello di fotocamera sbagliato nel codice, cavo flat non ben inserito nel connettore o alimentazione insufficiente. Leggere il codice di errore nel Monitor seriale restringe subito il campo:

Messaggio nel Monitor serialeSignificatoSoluzione
Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND)L'ESP32 non ha trovato nessuna fotocamera sul bus SCCBVerifica che sia selezionato CAMERA_MODEL_AI_THINKER, reinserisci il cavo flat, alimenta con 5 V / 2 A
Detected camera not supported e 0x106La stessa situazione nelle versioni recenti del driver: fotocamera non trovata o non riconosciutaStessi passi di 0x105; se persiste, sostituisci il modulo fotocamera
frame buffer malloc failed e 0xffffffffImpossibile allocare la memoria per il buffer del fotogrammaAttiva la PSRAM, abbassa la risoluzione, imposta fb_count a 1
cam_hal: EV-VSYNC-OVF o FB-OVFÈ arrivato un nuovo fotogramma prima che il precedente fosse elaborato, uno è stato saltatoInnocuo se capita ogni tanto; se è frequente, abbassa la risoluzione e migliora il segnale Wi-Fi
NO-SOI (JPEG start marker missing)Fotogramma JPEG danneggiato o incompletoControlla alimentazione e cavo flat, imposta xclk_freq_hz a 10000000
Immagine a metà, verde o a righeIl fotogramma non è entrato nel buffer o l'alimentazione è disturbataPorta il valore di qualità JPEG a 12 o più, migliora l'alimentazione
Per inserire il cavo flat, solleva la levetta nera di blocco del connettore, spingi il cavo dritto fino in fondo e richiudi la levetta. Non collegare né scollegare mai la fotocamera con la scheda alimentata: potresti danneggiare sia la fotocamera sia l'ESP32. Ricordati anche di togliere la pellicola protettiva dall'obiettivo di un modulo nuovo, altrimenti l'immagine risulterà sfocata.

Errore di brownout e alimentazione corretta (5 V / 2 A)

Se il Monitor seriale mostra Brownout detector was triggered e la scheda continua a riavviarsi, la tensione di alimentazione dell'ESP32 è scesa per un attimo sotto un livello sicuro. L'ESP32-CAM assorbe picchi di corrente brevi ma elevati appena accende il trasmettitore Wi-Fi e la fotocamera inizia a catturare. Una porta USB debole, cavetti jumper sottili e lunghi o l'uscita a 3,3 V del convertitore non reggono questi picchi. Ecco le soluzioni definitive:

  • Usa un alimentatore da 5 V e almeno 2 A collegato al pin 5V della scheda; il regolatore integrato lo abbassa a 3,3 V.
  • Tieni i cavi di alimentazione corti e spessi; breadboard e cavetti lunghi aumentano la caduta di tensione.
  • Aggiungi un condensatore elettrolitico da 470–1000 µF tra i pin 5V e GND, il più vicino possibile alla scheda (terminale positivo su 5V).
  • Se la alimenti dal computer, collegala direttamente a una porta sul retro invece che a un hub USB.
  • Per il funzionamento a batteria usa una cella 18650 con un modulo step-up (boost) a 5 V; è molto più stabile di più pile AA in serie.
Batteria agli ioni di litio 18650
Batteria 18650 agli ioni di litio: insieme a uno step-up a 5 V garantisce un'alimentazione stabile ai progetti ESP32-CAM a batteria.

In rete troverai spesso la riga WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0), che disattiva da codice il rilevatore di brownout. Ferma i riavvii ma non risolve il problema: la tensione continua a calare e ora la scheda può bloccarsi, produrre fotogrammi danneggiati o perdere dati mentre scrive nella flash. Usala solo per una prova temporanea; tutti i messaggi di riavvio sono spiegati in ESP32 brownout e Guru Meditation. Per stimare l'autonomia considera che la scheda assorbe in media 180 mA in streaming continuo: una 18650 da 2600 mAh con uno step-up con rendimento dell'85 % dà circa 1600 mAh sul lato a 5 V, cioè circa 9 ore di streaming. Puoi calcolare i tuoi valori con il calcolatore di durata della batteria, ricordando che anche in deep sleep la scheda assorbe circa 6 mA a causa del regolatore e della PSRAM.

Controllare il LED flash (GPIO 4)

Il LED bianco molto luminoso sul davanti della scheda è pilotato da un transistor collegato al GPIO 4: il pin comanda solo il transistor e l'alta corrente del LED arriva dall'alimentazione. Si accende con digitalWrite(4, HIGH) e si spegne con LOW. Il LED è molto potente e, se resta acceso a lungo, si scaldano sia il LED sia la scheda; è meglio accendere il flash solo per qualche centinaio di millisecondi mentre scatti la foto. Il GPIO 4 è anche la linea DATA1 della microSD, quindi con la scheda in modalità 4 bit il flash lampeggia da solo a ogni lettura e scrittura. Per evitarlo, avvia la SD in modalità 1 bit (SD_MMC.begin("/sdcard", true)); su alcune schede il LED può comunque restare acceso molto debolmente.

Salvare foto sulla microSD con l'ESP32-CAM

Lo sketch seguente, ogni volta che premi un pulsante collegato al GPIO 13, accende il flash, scatta una foto a 1600×1200 e la salva sulla microSD con i nomi foto1.jpg, foto2.jpg.... Formatta la scheda sul computer in FAT32; anche se la documentazione ufficiale parla di schede fino a 4 GB, in pratica le schede FAT32 da 16–32 GB di solito funzionano senza problemi. Collega un terminale del pulsante al GPIO 13 e l'altro a GND; lo sketch attiva la resistenza di pull-up interna, quindi non serve una resistenza aggiuntiva. Per capire come si collega un pulsante, leggi come collegare un pulsante ad Arduino.

Arduino (C++)
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}

Poiché lo sketch avvia la SD in modalità 1 bit, usa solo i GPIO 2, 14 e 15, lasciando il GPIO 4 al flash e il GPIO 13 al pulsante. Prima dello scatto viene preso un fotogramma e restituito subito: la fotocamera produce fotogrammi di continuo, quindi il primo nel buffer potrebbe essere stato catturato prima dell'accensione del flash, e l'esposizione automatica ha bisogno di una breve pausa per adattarsi alla nuova luce. Il numero del file si ricava dai file già presenti sulla scheda, così le foto vecchie non vengono sovrascritte nemmeno dopo un riavvio. Per le regole generali sulla registrazione di dati su SD, dai un'occhiata alla guida modulo scheda SD.

MicroPython e schede fotocamera più recenti

Puoi programmare l'ESP32-CAM anche in MicroPython, ma la versione ufficiale di MicroPython non include il driver della fotocamera; devi installare un firmware della community che lo aggiunga. Per iniziare, quindi, la strada dell'Arduino IDE è molto più semplice. Se preferisci evitare una scheda senza presa USB, valuta anche le schede fotocamera basate su ESP32-S3, con USB e più memoria (ad es. Seeed XIAO ESP32S3 Sense o ESP32-S3-EYE); compaiono anche loro nell'elenco dei modelli di CameraWebServer.

Idee di progetti con l'ESP32-CAM

  • Foto al rilevamento di movimento: scatta una foto quando un sensore PIR rileva qualcuno e inviala allo smartphone; la guida passo dopo passo è in foto dell'ESP32-CAM su Telegram.
  • Time-lapse: fai svegliare la scheda ogni 10 minuti, scattare una foto, salvarla sulla SD e tornare in deep sleep; osserva la crescita di una pianta o il cambiare del tempo.
  • Telecamera per il campanello: fotografa l'ingresso quando qualcuno suona e invia una notifica con un bot Telegram.
  • Robot car con telecamera: guida l'auto guardando sullo smartphone uno streaming fluido in QVGA.
  • Telecamera per animali: guarda lo streaming sulla rete di casa e accendi il flash dalla pagina web quando serve.
  • Il tuo pannello di controllo: inserisci lo streaming nella tua pagina web e aggiungi accanto comandi per relè e letture dei sensori; la guida ESP32 WebSocket ti mostra come fare.

Errori comuni e soluzioni

SintomoCausa probabileSoluzione
Failed to connect to ESP32: No serial data received (nelle versioni vecchie Timed out waiting for packet header)La scheda non è in modalità download, oppure TX e RX sono sbagliatiCollega IO0 a GND o usa il pulsante IO0, premi RST; verifica che TX vada a U0R e RX a U0T
Wrong boot mode detected (0x13)All'avvio il GPIO 0 non era LOWDopo aver collegato IO0 a GND premi sempre RST
waiting for download nel Monitor serialeIO0 è ancora collegato a GNDTogli il filo di IO0 e premi RST
Caratteri incomprensibili nel Monitor serialeVelocità in baud sbagliataImposta il Monitor seriale a 115200 baud
La scheda non compare nell'elenco delle porteDriver mancante o cavo di sola ricaricaInstalla il driver CH340 o CP2102, usa un cavo dati
Il caricamento fallisce con la SD inseritaIl GPIO 2 è sia linea SD sia pin di strappingTogli la microSD durante il caricamento
Immagine molto lenta o che si blocca spessoSegnale Wi-Fi debole o risoluzione altaScendi a VGA o QVGA, avvicina la scheda al router, usa un'antenna esterna se serve
Il flash resta sempre leggermente accesoSD in modalità 4 bit o GPIO 4 lasciato flottanteAvvia la SD in modalità 1 bit, imposta il GPIO 4 come OUTPUT a LOW
Se vuoi usare un'antenna esterna (IPEX), quale antenna usa la scheda lo decide la posizione di una minuscola resistenza da 0 Ω accanto all'antenna; collegare l'antenna non basta, devi anche spostare la resistenza. Se la scheda non si avvia o la SD non si inizializza, scollega i moduli sui GPIO 2, 12 e 13 e riprova: i GPIO 2 e 12 sono pin di strapping, e il GPIO 13 è la linea DATA3 della SD, che non deve essere LOW durante l'inizializzazione.

L'ESP32-CAM è il modo più semplice per costruire una telecamera Wi-Fi con una scheda economica, e quasi tutte le difficoltà nascono dal collegamento di programmazione o dall'alimentazione. Una volta sistemati questi due punti, la scheda trasmette in diretta dal proprio web server, scatta foto e le salva sulla SD. Nell'app BlueGrays trovi progetti con ESP32 come la connessione Wi-Fi, un web server, mDNS, la registrazione di dati su microSD e un allarme di movimento con notifiche Telegram, ognuno con schema del circuito passo dopo passo e codice pronto all'uso.

Domande frequenti

Come si programma l'ESP32-CAM?

Poiché l'ESP32-CAM non ha una presa USB, serve un adattatore ESP32-CAM-MB o un convertitore USB-TTL. Nell'Arduino IDE scegli la scheda AI Thinker ESP32-CAM e metti la scheda in modalità download premendo RST mentre il GPIO 0 è collegato a GND (o mentre tieni premuto il pulsante IO0 dell'MB). Finito il caricamento, togli il collegamento IO0 e premi di nuovo RST.

Si può programmare l'ESP32-CAM con un Arduino Uno?

Sì; se colleghi il pin RESET dell'Uno a GND, il suo chip USB funziona come un ponte USB-seriale. In questo caso il collegamento è diretto e non incrociato: il D0 (RX) dell'Uno va a U0R, il D1 (TX) a U0T e IO0 resta collegato a GND. Poiché i segnali dell'Uno sono a 5 V, questo mette l'ESP32 al limite; per un uso continuativo è più sicuro un adattatore MB o un convertitore USB-TTL a 3,3 V.

Con quanti volt funziona l'ESP32-CAM?

Si consiglia di alimentare la scheda con 5 V sul pin 5V; il regolatore integrato li abbassa a 3,3 V. Puoi anche fornire 3,3 V sul pin 3V3, ma se la sorgente non regge i picchi di corrente del Wi-Fi, la scheda si riavvia di continuo. Un alimentatore da almeno 2 A evita la maggior parte degli errori di brownout.

Come si risolve l'errore Camera init failed dell'ESP32-CAM?

I codici 0x105 o 0x106 indicano che non è stata trovata nessuna fotocamera: controlla prima che nel codice sia selezionato CAMERA_MODEL_AI_THINKER, poi che il cavo flat sia inserito fino in fondo, e alimenta la scheda con 5 V / 2 A. Se il problema persiste, il modulo fotocamera potrebbe essere guasto. Se vedi 0xffffffff insieme a frame buffer malloc failed, attiva la PSRAM o abbassa la risoluzione.

L'ESP32-CAM funziona senza internet?

Sì. Per vedere l'immagine serve solo una rete locale, non internet; l'ESP32-CAM può anche creare una propria rete Wi-Fi con WiFi.softAP() e allora si apre nel browser all'indirizzo 192.168.4.1. Puoi persino usarla senza alcuna rete, come una fotocamera che salva le foto solo sulla microSD.

L'ESP32-CAM può registrare video?

Gli esempi forniti trasmettono l'immagine in diretta in MJPEG e scattano singole foto; non registrano direttamente un file video. Esistono progetti della community che scrivono fotogrammi JPEG consecutivi sulla microSD per creare un file AVI, ma la frequenza resta limitata anche a bassa risoluzione. La scheda non ha un microfono, quindi non registra nemmeno l'audio.

Vedi tutti i progetti
LED Lampeggiante con ESP32
#103Principiante

LED Lampeggiante con ESP32

Insegna l'uso di base delle uscite GPIO con l'ESP32. Otteniamo un effetto lampeggiante accendendo e spegnendo un LED dal pin digitale. Versione ESP32 del classico progetto blink su Arduino UNO; i comandi di base di blink nell'ambiente Arduino sono gli stessi, ma la disposizione dei pin e i livelli GPIO a 3,3 V dell'ESP32 sono diversi da quelli di Arduino UNO.

4.7(36)
96
Lampeggio del LED interno dell'ESP32
#106Principiante

Lampeggio del LED interno dell'ESP32

Far lampeggiare il LED blu integrato nell'ESP32 DevKit V1. Non sono necessari componenti esterni! Il primo progetto da provare quando si acquista un ESP32. Il GPIO 2 è collegato al LED interno.

4.8(29)
53
Connessione Wi-Fi STA con ESP32 (con display LCD)
#127Avanzato
Premium

Connessione Wi-Fi STA con ESP32 (con display LCD)

In questo progetto colleghiamo l'ESP32 alla rete Wi-Fi domestica in modalità Station (STA) in modo sicuro e tollerante agli errori. Separiamo SSID e password in un file `secrets.h` per impedire fughe su Git, impostiamo un meccanismo di riconnessione automatica e visualizziamo il livello del segnale RSSI e l'indirizzo IP su un display LCD I2C. Il LED interno funge da indicatore di stato.

4.4(21)
33
Server web asincrono ESP32 (con indicazione dell'IP sul display LCD)
#129Avanzato
Premium

Server web asincrono ESP32 (con indicazione dell'IP sul display LCD)

In questo progetto trasformiamo l'ESP32 in un **server web asincrono** che potrete controllare dal vostro telefono o computer collegato alla stessa rete Wi-Fi. Grazie alla libreria ESPAsyncWebServer, il server è in grado di elaborare più richieste contemporaneamente (a differenza del classico `WebServer.h`, che si blocca su una singola richiesta).

4.8(16)
26
ESP32 mDNS: accesso al dispositivo tramite bluegrays-esp.local (con schermo LCD)
#131Avanzato
Premium

ESP32 mDNS: accesso al dispositivo tramite bluegrays-esp.local (con schermo LCD)

In questo progetto, aggiungendo il servizio mDNS (Multicast DNS) all'ESP32, consentiamo l'accesso tramite un nome host leggibile, come `bluegrays-esp.local`, anziché tramite l'indirizzo IP. Anche se l'IP assegnato dal DHCP dovesse cambiare, potrete sempre raggiungere il dispositivo con lo stesso nome. Eseguendo anche un piccolo server web, inviamo comandi di controllo dei LED dal browser all’indirizzo `http://bluegrays-esp.local/`. Sul display LCD I2C vengono visualizzati il nome host, l’IP e lo

4.8(14)
23
Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avanzato
Premium

Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Costruisci un data logger di temperatura con timestamp usando ESP32! Leggi temperatura/umidità dal DHT22 ogni minuto, ottieni l'ora reale dal DS1307 RTC e registra su scheda microSD in formato CSV. L'OLED mostra dal vivo temperatura (font grande), percentuale di umidità, timestamp e contatore di log. Il file `/temp_log.csv` sulla scheda SD si apre in Excel, Google Sheets o Python pandas per l'analisi — perfetto per il monitoraggio di serre, tracciamento della temperatura domestica, raccolta

4.7(7)
12
Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
#145Avanzato
Premium

Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)

Un sistema di allarme di sicurezza intelligente che attiva buzzer e LED quando il sensore PIR rileva movimento, inviando contemporaneamente una notifica istantanea al proprietario tramite Telegram. Dispone di un tempo di attesa di 30 secondi per limitare la frequenza degli allarmi ripetuti; questo meccanismo non verifica la validità dei rilevamenti del sensore PIR né elimina le false attivazioni. Adatto a sicurezza domestica, monitoraggio di garage, magazzini o studi. Con l'ESP32-CAM è possibile

0.0(0)
8
Allarme con sensore di movimento ESP32
#140Intermedio
Premium

Allarme con sensore di movimento ESP32

In questo progetto, realizzato utilizzando un ESP32 e un sensore PIR, quando viene rilevato un movimento, il cicalino si attiva emettendo un allarme acustico. Si tratta di un'applicazione semplice ed economica per un sistema di sicurezza. (Le immagini sono puramente illustrative; collegarle in base al testo)

4.4(10)
15