Componentes · 15 min de leitura

Tutorial do ESP32-CAM: configuração, programação, transmissão ao vivo e cartão SD

Como programar o ESP32-CAM: pinagem do AI-Thinker, carregamento com ESP32-CAM-MB e USB-TTL, CameraWebServer, PSRAM, soluções para 0x105 e brownout, LED de flash e fotos no SD.

O ESP32-CAM é uma placa de câmera Wi-Fi acessível que, mesmo medindo só 27 × 40 mm, traz um processador ESP32, uma câmera OV2640 de 2 megapixels, um slot para cartão microSD e um LED de flash branco. Sozinha, ela entra na rede da sua casa, transmite vídeo ao vivo para um navegador, tira fotos e as salva em um cartão SD ou envia pela internet. É a placa preferida para câmeras de segurança, câmeras de campainha, time-lapses do crescimento de plantas e carrinhos robô com vídeo, mas, como não tem conector USB, começar com ela é um pouco diferente das placas ESP32 com que você talvez esteja acostumado.

Neste guia você vai aprender a pinagem do ESP32-CAM AI-Thinker, como programá-lo com o adaptador ESP32-CAM-MB ou com um adaptador USB-TTL (incluindo a ligação IO0-GND), como obter uma imagem ao vivo no navegador com o exemplo pronto CameraWebServer e quais ajustes de PSRAM e de partição usar. Depois você vai ver as causas dos erros mais comuns, Camera init failed with error 0x105 e brownout, controlar o LED de flash e montar um sketch que salva uma foto em um cartão microSD quando você aperta um botão.

Módulo de câmera ESP32-CAM AI-Thinker
ESP32-CAM: um módulo ESP32-S, câmera OV2640, slot microSD e LED de flash em uma só placa. Não há conector USB, então você precisa de um adaptador para programá-la.

O que é o ESP32-CAM e como ele funciona?

O coração da placa é o módulo ESP32-S, que traz o chip ESP32 dual-core com Wi-Fi e Bluetooth. A câmera se encaixa em um conector de 24 pinos na placa por um cabo flat fino (FPC). O ESP32 envia à câmera um sinal de clock de 20 MHz (XCLK) pelo GPIO 0 e a configura pelo barramento SCCB, parecido com o I2C, nos GPIO 26 e 27. Como o sensor OV2640 consegue comprimir a imagem em JPEG sozinho, o ESP32 recebe pequenos quadros JPEG em vez de pixels brutos. Esses quadros passam por um barramento de dados paralelo de 8 bits até os 4 MB de PSRAM da placa, e o Wi-Fi os leva adiante até um navegador ou um servidor.

CaracterísticaValor
ProcessadorESP32 (módulo ESP32-S), dual-core, até 240 MHz
Sem fioWi-Fi 802.11 b/g/n (só 2,4 GHz), Bluetooth 4.2 e BLE
Memória520 KB de SRAM interna + 4 MB de PSRAM, 4 MB de flash
CâmeraOV2640, 2 MP, até 1600×1200 (UXGA), saída JPEG
ArmazenamentoSlot microSD (até 4 GB na documentação oficial)
LuzLED de flash branco (GPIO 4), LED de status vermelho no verso (GPIO 33)
Alimentação5 V no pino 5V (recomendado) ou 3,3 V no pino 3V3
Corrente (em 5 V)Cerca de 180 mA com o flash apagado, cerca de 310 mA com o flash no brilho máximo; os picos do Wi-Fi são maiores
Tamanho27 × 40,5 × 4,5 mm

Pinagem do ESP32-CAM AI-Thinker: quais pinos estão livres?

Há 16 pinos nas duas bordas da placa, mas só alguns estão realmente livres: a câmera sozinha usa 15 GPIOs, e o slot microSD compartilha mais seis. A tabela abaixo resume os pinos das bordas e quando você pode usá-los. Você também pode explorar as características gerais dos pinos do ESP32 na ferramenta de pinagem.

PinoFunçãoLivre para usar?
5VEntrada de alimentação (recomendada)-
3V3Entrada de alimentação de 3,3 V-
GND (3 pinos)Terra-
VCCSaída de alimentação (3,3 V por padrão)Não use para alimentar a placa
U0R (GPIO 3)RX serial: programação e Monitor SerialSó se você não precisar da porta serial
U0T (GPIO 1)TX serial: programação e Monitor SerialSó se você não precisar da porta serial
GPIO 0Clock da câmera (XCLK) e modo de inicializaçãoNão; só vai ao GND durante o carregamento
GPIO 16Ligado à PSRAM em muitas placasNão
GPIO 2SD DATA0Se o cartão SD não for usado; pino de strapping
GPIO 4SD DATA1 e LED de flashNo modo SD de 1 bit ou sem SD
GPIO 12SD DATA2No modo SD de 1 bit ou sem SD; precisa estar em LOW na inicialização
GPIO 13SD DATA3No modo SD de 1 bit ou sem SD; o pino livre mais seguro
GPIO 14SD CLKSe o cartão SD não for usado
GPIO 15SD CMDSe o cartão SD não for usado; pino de strapping
GPIO 33LED vermelho (fora da barra de pinos)Só o LED; escrever LOW acende
O pino VCC não é uma entrada: é a saída do regulador da placa e fornece 3,3 V por padrão. Ligar 5 V ali leva a linha de 3,3 V direto para 5 V e pode destruir o ESP32, então coloque sempre a alimentação no pino 5V. Além disso, se o GPIO 12 estiver em HIGH na inicialização, o ESP32 tenta rodar a flash a 1,8 V e a placa não inicia, então não ligue nesse pino um resistor de pull-up nem um módulo que o puxe para HIGH.

Como programar o ESP32-CAM? Dois jeitos

O chip USB-serial que permite às placas ESP32 comuns conversar com o computador não existe no ESP32-CAM. Para carregar código você tem duas opções: o adaptador ESP32-CAM-MB, que encaixa por baixo da placa (uma pequena placa-base com um chip CH340 e um conector micro USB), ou um adaptador USB-TTL que você já tenha (FTDI, CH340, CP2102). Seja qual for a escolha, a lógica é a mesma: se o GPIO 0 estiver em LOW na inicialização, o ESP32 entra no modo de download e espera o código; se estiver em HIGH, ele roda o programa da flash. O botão IO0 do adaptador MB e o fio IO0-GND que você coloca com um adaptador USB-TTL fazem exatamente isso.

Adaptador USB-TTL CP2102
Adaptador USB-TTL CP2102: os pinos GND, 5V, TX e RX são tudo de que você precisa para programar o ESP32-CAM.
Adaptador USB-TTLESP32-CAMObservações
GNDGNDTerra comum
5V5VAlimenta a placa; a saída de 3,3 V do adaptador não basta
TXU0R (GPIO 3)Cruzado: transmissor no receptor
RXU0T (GPIO 1)Cruzado: receptor no transmissor
-Entre IO0 e GNDSó durante o carregamento; um fio curto entre os dois pinos vizinhos

Se o seu adaptador tem um jumper de seleção 3,3 V / 5 V, coloque em 3,3 V para que a linha TX fique em um nível adequado aos pinos do ESP32. Mas alimente a placa pelo pino 5V do adaptador. A saída de 3,3 V da maioria dos adaptadores só fornece uns 50–100 mA; no momento em que o ESP32-CAM liga o Wi-Fi, essa alimentação despenca e a placa reinicia.

Ajustes da Arduino IDE: placa, esquema de partição e PSRAM

  1. Abra o Gerenciador de Placas na Arduino IDE e instale o pacote esp32 by Espressif Systems; o guia de instalação da Arduino IDE explica em detalhes.
  2. Selecione a placa AI Thinker ESP32-CAM em Ferramentas > Placa > esp32.
  3. Confira se o Partition Scheme está em Huge APP (3MB No OTA/1MB SPIFFS); o exemplo da câmera precisa de pelo menos 3 MB de espaço para o app.
  4. Ligue a placa ao adaptador e escolha a nova porta em Ferramentas > Porta (COMx no Windows, /dev/cu.usbserial... ou /dev/cu.wchusbserial... no macOS).
  5. Se nenhuma porta aparecer, instale o driver CH340 ou CP2102 e use um cabo USB que transmita dados.
AjusteValor recomendadoPor quê?
PlacaAI Thinker ESP32-CAMPSRAM, flash de 4 MB e o esquema de partição certo já vêm definidos
Partition SchemeHuge APP (3MB No OTA/1MB SPIFFS)Os 3 MB de espaço para o app de que o CameraWebServer precisa
PSRAMSempre ativada nesta definição de placaCom ESP32 Dev Module, coloque PSRAM: Enabled; no ESP32 Wrover Module ela já vem ativada
CPU Frequency240MHz (WiFi/BT)Velocidade máxima para a transferência de imagens e o Wi-Fi
Flash Mode / Flash FrequencyQIO / 80MHzTente DIO / 40MHz se o carregamento ou a inicialização falharem
Core Debug LevelNone (Info ao investigar problemas)Em Info, os detalhes da câmera e do FPS aparecem no Monitor Serial
Upload Speed460800 (fixo nesta placa)Se os carregamentos ficarem caindo, selecione ESP32 Wrover Module e tente 115200
Abra sempre o Monitor Serial em 115200 baud. As mensagens de inicialização só aparecem no momento de um reset, então, se a tela estiver vazia, aperte o botão RST da placa. Se você vir waiting for download, o IO0 ainda está ligado ao GND; tire o fio, aperte RST de novo e o seu programa começa a rodar.

O seu primeiro carregamento, passo a passo

  1. Faça a ligação: encaixe a placa no adaptador MB com os pinos alinhados ou ligue o adaptador USB-TTL como na tabela acima. Se estiver usando um adaptador USB-TTL, coloque também o fio curto entre IO0 e GND.
  2. Coloque a placa no modo de download: no adaptador MB, segure o botão IO0, aperte e solte o RST e depois solte o IO0. Com um adaptador USB-TTL, basta apertar RST com o fio IO0-GND no lugar. Alguns adaptadores MB com circuito de reset automático carregam sem apertar nenhum botão.
  3. Clique em Carregar na Arduino IDE. A saída mostra primeiro Connecting... e depois o progresso da gravação em porcentagem.
  4. Quando aparecer a linha Hard resetting via RTS pin..., o carregamento terminou. Se estiver usando um adaptador USB-TTL, tire agora o fio IO0-GND.
  5. Abra o Monitor Serial em 115200 baud e aperte RST; o programa novo começa a rodar.
C++ (Arduino IDE)
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 o carregamento deu certo, o pequeno LED vermelho no verso da placa pisca a cada meio segundo. Esse LED usa lógica invertida: escrever LOW acende e HIGH apaga. No Monitor Serial você deve ver cerca de 4 milhões de bytes de PSRAM; se aparecer No PSRAM, confira a placa selecionada e, se não resolver, talvez a sua placa não tenha chip de PSRAM. Rodar este teste curto antes do exemplo da câmera mostra na hora se um problema está no carregamento ou na câmera.

O exemplo CameraWebServer: imagem ao vivo no navegador

  1. Abra Arquivo > Exemplos > ESP32 > Camera > CameraWebServer.
  2. Escolha o modelo da câmera: na lista da aba board_config.h (versões mais novas) ou no topo do arquivo principal (versões antigas), coloque // na frente da linha CAMERA_MODEL_ESP_EYE e tire o // da frente da linha CAMERA_MODEL_AI_THINKER.
  3. Coloque o nome e a senha da sua rede Wi-Fi de 2,4 GHz nas linhas ssid e password.
  4. Coloque a placa no modo de download e carregue o sketch; depois tire a ligação do IO0 e aperte RST.
  5. No Monitor Serial você vai ver uma linha como Camera Ready! Use 'http://192.168.1.45' to connect; abra esse endereço no navegador de um celular ou computador na mesma rede.
  6. Inicie a imagem ao vivo com o botão Start Stream da página ou tire uma única foto com Get Still.
C++ (Arduino IDE)
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

A interface roda em dois servidores separados: a página de configurações e o endereço /capture, que devolve uma única foto, ficam na porta 80, enquanto a transmissão ao vivo fica em /stream na porta 81 (por exemplo, http://192.168.1.45:81/stream). Você pode colocar esse endereço de transmissão na sua própria página web ou em um software de automação residencial. No menu à esquerda dá para mudar a resolução, a qualidade do JPEG, o brilho, o contraste e o balanço de branco e, se a imagem estiver de cabeça para baixo, usar as chaves V-Flip e H-Mirror; as versões mais novas também têm um controle deslizante LED Intensity para o flash. A placa costuma atender só um espectador da transmissão ao vivo por vez, então uma transmissão aberta em uma segunda aba pode travar. Se a página nem abrir, confira se o celular e a placa estão na mesma rede; para problemas de conexão, veja ESP32 não conecta ao Wi-Fi.

Tabela de resolução e FPS do ESP32-CAM

No papel, o sensor OV2640 consegue entregar 15 quadros por segundo em 1600×1200, 30 em 800×600 e 60 no tamanho CIF. Na prática, a taxa de quadros é definida principalmente pela conexão Wi-Fi e pelo tamanho dos quadros JPEG: conforme a resolução e a qualidade sobem, cada quadro fica maior e atravessa a rede mais devagar. Os valores abaixo são faixas aproximadas vistas com o CameraWebServer em um bom sinal de Wi-Fi, com qualidade JPEG 10–12. Para medir a sua placa, coloque o Core Debug Level em Info; durante a transmissão, o Monitor Serial mostra uma linha como MJPG: ... (x fps) a cada quadro.

ResoluçãoPixelsFPS aprox. (transmissão Wi-Fi)Bom para
QQVGA160×12025–30Detecção de movimento, redes muito fracas
QVGA320×24020–30Carrinhos robô, vídeo ao vivo fluido
CIF400×29615–25Visualização fluida em telas pequenas
VGA640×48010–20Visualização ao vivo de uso geral
SVGA800×6008–15Visualização mais nítida; o maior tamanho utilizável sem PSRAM
XGA1024×7685–10Imagens detalhadas
HD1280×7204–8Enquadramento largo (16:9)
SXGA1280×10243–6Fotos
UXGA1600×12002–5Fotos na resolução máxima

No seu próprio código, você muda a resolução, a qualidade e a orientação pelo objeto do sensor depois que a câmera inicia com sucesso. A qualidade do JPEG é um número de 0 a 63, e um número menor significa qualidade maior; descer abaixo de 10 deixa os quadros maiores e pode gerar imagens pela metade.

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

Por que o ajuste de PSRAM do ESP32-CAM importa tanto?

A memória interna do ESP32 é de 520 KB, e a pilha do Wi-Fi usa boa parte dela. Já um único quadro JPEG de 1600×1200 pode ocupar 100–250 KB, dependendo da cena e da qualidade. Por isso o driver da câmera coloca os buffers de quadro na PSRAM. O CameraWebServer verifica a PSRAM com a função psramFound(): se ela existe, inicia na resolução máxima com dois buffers de quadro; se não, limita a resolução a SVGA (800×600) e mantém um único buffer na memória interna.

Se você pede uma resolução alta sem a PSRAM ativada, o Monitor Serial mostra frame buffer malloc failed seguido de Camera init failed with error 0xffffffff. A solução é selecionar AI Thinker ESP32-CAM como placa (com ESP32 Dev Module, coloque Ferramentas > PSRAM: Enabled) ou baixar a resolução e reduzir o número de buffers de quadro para 1. Alguns clones baratos podem nem ter chip de PSRAM; a linha da PSRAM no primeiro sketch de teste revela isso na hora.

Camera init failed with error 0x105 e outros erros da câmera

A maioria dos erros da câmera se resume a uma de três causas: o modelo de câmera errado no código, um cabo flat mal encaixado no conector ou uma alimentação insuficiente. Ler o código de erro no Monitor Serial estreita a causa rapidinho:

Mensagem no Monitor SerialSignificadoSolução
Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND) (câmera não encontrada)O ESP32 não encontrou nenhuma câmera no barramento SCCBConfira se CAMERA_MODEL_AI_THINKER está selecionado, reencaixe o cabo flat, alimente a placa com 5 V / 2 A
Detected camera not supported e 0x106A mesma situação nas versões mais novas do driver: nenhuma câmera encontrada ou reconhecidaOs mesmos passos do 0x105; se continuar, troque o módulo da câmera
frame buffer malloc failed e 0xffffffffNão foi possível reservar memória para o buffer de quadroAtive a PSRAM, baixe a resolução, coloque fb_count em 1
cam_hal: EV-VSYNC-OVF ou FB-OVFUm quadro novo chegou antes de o anterior ser processado, então um quadro foi puladoInofensivo de vez em quando; se for frequente, baixe a resolução e melhore o sinal do Wi-Fi
NO-SOI (falta o marcador de início do JPEG)Quadro JPEG corrompido ou incompletoConfira a alimentação e o cabo flat, coloque xclk_freq_hz em 10000000
Imagem pela metade, verde ou listradaO quadro não coube no buffer, ou a alimentação tem ruídoSuba o valor de qualidade do JPEG para 12 ou mais, melhore a alimentação
Ao encaixar o cabo flat, levante a trava preta do conector, empurre o cabo até o fim para que fique reto e feche a trava. Nunca encaixe nem desencaixe a câmera com a placa energizada; tanto a câmera quanto o ESP32 podem se danificar. Lembre também de tirar a película protetora da lente de um módulo de câmera novo, senão a imagem fica embaçada.

Erro de brownout e a alimentação certa (5 V / 2 A)

Se o Monitor Serial mostra Brownout detector was triggered e a placa fica reiniciando, a tensão de alimentação do ESP32 caiu por um instante abaixo de um nível seguro. O ESP32-CAM puxa picos de corrente curtos, mas altos, no momento em que liga o transmissor Wi-Fi e a câmera começa a capturar. Uma porta USB fraca, jumpers finos e longos ou a saída de 3,3 V do adaptador não acompanham esses picos. Estas são as soluções definitivas:

  • Use uma fonte que forneça 5 V e pelo menos 2 A e ligue-a no pino 5V da placa; o regulador da placa baixa para 3,3 V.
  • Mantenha os fios de alimentação curtos e grossos; protoboards e jumpers longos aumentam a queda de tensão.
  • Coloque um capacitor eletrolítico de 470–1000 µF entre os pinos 5V e GND da placa, o mais perto possível dela (terminal positivo no 5V).
  • Se alimentar pelo computador, ligue direto em uma porta na parte de trás do PC, em vez de um hub USB.
  • Para funcionar com bateria, use uma célula 18650 com um módulo elevador de 5 V; isso é bem mais estável que uma fileira de pilhas AA.
Bateria de íons de lítio 18650
Célula de íons de lítio 18650: junto com um módulo elevador de 5 V, dá uma alimentação estável a projetos com ESP32-CAM a bateria.

Na internet você vai encontrar muito a linha WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0), que desliga o detector de brownout no código. Ela acaba com os reinícios, mas não resolve o problema: a tensão continua caindo, e a placa pode passar a travar, gerar quadros corrompidos ou perder dados ao gravar na flash. Use só para um teste temporário; a lista completa das mensagens de reinício está no guia ESP32 brownout e Guru Meditation. Ao estimar a duração da bateria, considere que a placa puxa em média 180 mA transmitindo sem parar: uma 18650 de 2600 mAh com um conversor elevador de 85% de eficiência dá cerca de 1600 mAh do lado de 5 V, ou seja, umas 9 horas de transmissão. Você pode calcular os seus próprios números com a calculadora de duração da bateria; lembre que, mesmo em deep sleep, a placa puxa cerca de 6 mA por causa do regulador e da PSRAM.

Controlando o LED de flash (GPIO 4)

O LED branco forte na frente da placa é acionado por um transistor ligado ao GPIO 4, então o pino só chaveia o transistor, e a corrente alta do LED vem da linha de alimentação. digitalWrite(4, HIGH) acende e LOW apaga. O LED é muito forte e, se ficar aceso por muito tempo, tanto ele quanto a placa esquentam; o melhor é acender o flash só por algumas centenas de milissegundos ao tirar uma foto. O GPIO 4 também é a linha DATA1 do cartão microSD, então, quando o cartão funciona no modo de 4 bits, o flash pisca sozinho a cada leitura e gravação. Para evitar isso, inicie o cartão SD no modo de 1 bit (SD_MMC.begin("/sdcard", true)); em algumas placas o LED ainda pode brilhar bem de leve.

Salvando fotos em um cartão microSD com o ESP32-CAM

O sketch abaixo acende o flash, tira uma foto em 1600×1200 e a salva no cartão microSD como foto1.jpg, foto2.jpg... toda vez que você aperta um botão no GPIO 13. Formate o cartão microSD em FAT32 no computador; embora a documentação oficial fale em cartões de até 4 GB, cartões FAT32 de 16–32 GB costumam funcionar bem na prática. Ligue uma perna do botão no GPIO 13 e a outra no GND; o sketch ativa o resistor de pull-up interno, então não precisa de resistor extra. Para entender como funciona a ligação de botões, veja Como ligar um botão no Arduino.

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

Como o sketch inicia o cartão SD no modo de 1 bit, ele só usa os GPIO 2, 14 e 15, o que deixa o GPIO 4 para o flash e o GPIO 13 para o botão. Antes de tirar a foto, um quadro é capturado e devolvido na hora: a câmera produz quadros sem parar, então o primeiro quadro no buffer pode ter sido capturado antes de o flash acender, e a exposição automática precisa de uma pequena pausa para se ajustar à luz nova. O número do arquivo é definido olhando os arquivos que já estão no cartão, então as fotos antigas não são sobrescritas nem depois de um reinício. Para as regras gerais de registro de dados em um cartão SD, dê uma olhada no guia do módulo de cartão SD.

MicroPython e placas de câmera mais novas

Você também pode programar o ESP32-CAM com MicroPython, mas a versão oficial do MicroPython não inclui driver de câmera; é preciso gravar um firmware da comunidade com suporte à câmera. Por isso o caminho da Arduino IDE é bem mais tranquilo para iniciantes. Se você prefere não lidar com uma placa sem conector USB, considere também as placas de câmera baseadas no ESP32-S3, com USB e mais memória (por exemplo, a Seeed XIAO ESP32S3 Sense ou a ESP32-S3-EYE); essas placas também aparecem na lista de modelos do CameraWebServer.

Ideias de projetos com ESP32-CAM

  • Foto ao detectar movimento: tire uma foto quando um sensor PIR perceber alguém e envie para o seu celular; o passo a passo está em fotos do ESP32-CAM no Telegram.
  • Gravação em time-lapse: deixe a placa acordar a cada 10 minutos, tirar uma foto, salvar no cartão SD e voltar ao deep sleep; acompanhe uma planta crescendo ou o tempo mudando.
  • Câmera de campainha: fotografe a frente da sua porta quando o botão da campainha for apertado e envie uma notificação com um bot do Telegram.
  • Carrinho robô com vídeo: dirija o carrinho acompanhando uma transmissão ao vivo fluida em QVGA no celular.
  • Câmera para pets: assista à transmissão ao vivo na rede da sua casa e ligue o flash pela página web quando precisar.
  • Seu próprio painel de controle: coloque a transmissão ao vivo na sua própria página web e acrescente ao lado leituras de relés e sensores; o guia ESP32 WebSocket mostra o caminho.

Erros comuns e como corrigir

SintomaCausa provávelSolução
Failed to connect to ESP32: No serial data received (Timed out waiting for packet header nas versões antigas)A placa não está no modo de download, ou TX e RX estão erradosLigue o IO0 ao GND ou use o botão IO0 e aperte RST; confira se o TX vai ao U0R e o RX ao U0T
Wrong boot mode detected (0x13) (modo de inicialização errado)O GPIO 0 não estava em LOW na inicializaçãoAperte sempre o RST depois de fazer a ligação IO0-GND
waiting for download no Monitor SerialO IO0 ainda está ligado ao GNDTire o fio do IO0 e aperte RST
Caracteres estranhos no Monitor SerialBaud rate erradoColoque o Monitor Serial em 115200 baud
A placa não aparece na lista de portasDriver faltando, ou cabo só de cargaInstale o driver CH340 ou CP2102, use um cabo de dados
O carregamento falha com o cartão SD inseridoO GPIO 2 é ao mesmo tempo uma linha do SD e um pino de strappingTire o cartão microSD durante o carregamento
Imagem muito lenta ou travando com frequênciaSinal de Wi-Fi fraco ou resolução altaBaixe para VGA ou QVGA, aproxime a placa do roteador, use uma antena externa se precisar
O flash fica sempre aceso de leveCartão SD no modo de 4 bits, ou GPIO 4 flutuandoInicie o cartão SD no modo de 1 bit, defina o GPIO 4 como OUTPUT e escreva LOW
Se você quer colocar uma antena externa (IPEX), a posição de um minúsculo resistor de 0 Ω ao lado da antena define qual antena a placa usa; só encaixar a antena não basta, também é preciso mudar o resistor de posição. Se a placa não inicia ou o cartão SD não inicializa, desconecte os módulos ligados aos GPIO 2, 12 e 13 e tente de novo: os GPIO 2 e 12 são pinos de strapping, e o GPIO 13 é a linha DATA3 do cartão SD, que não pode estar em LOW enquanto o cartão é inicializado.

O ESP32-CAM é o jeito mais fácil de montar uma câmera Wi-Fi em uma placa acessível, e quase toda dificuldade que você vai encontrar vem da ligação de programação ou da alimentação. Acertando essas duas coisas, a placa transmite vídeo ao vivo pelo próprio servidor web, tira fotos e as salva em um cartão SD. No app BlueGrays você encontra projetos com ESP32 como conexão Wi-Fi, servidor web, mDNS, registro de dados em microSD e um alarme de movimento com notificações no Telegram, cada um com esquemas do circuito passo a passo e código pronto para usar.

Perguntas frequentes

Como programar o ESP32-CAM?

Como o ESP32-CAM não tem conector USB, você precisa de um adaptador ESP32-CAM-MB ou de um adaptador USB-TTL. Na Arduino IDE você seleciona a placa AI Thinker ESP32-CAM e coloca a placa no modo de download apertando RST com o GPIO 0 ligado ao GND (ou com o botão IO0 do MB apertado). Depois do carregamento, tire a ligação do IO0 e aperte RST de novo.

Dá para programar o ESP32-CAM com um Arduino Uno?

Sim; se você ligar o pino RESET do Uno ao GND, o chip USB dele funciona como uma ponte USB-serial. Nesse caso a ligação é direta, não cruzada: o D0 (RX) do Uno vai ao U0R, o D1 (TX) vai ao U0T, e o IO0 continua ligado ao GND. Como os sinais do Uno são de 5 V, isso leva o ESP32 ao limite; para uso frequente, um adaptador MB ou um adaptador USB-TTL de 3,3 V é mais seguro.

De qual tensão o ESP32-CAM precisa?

O recomendado é alimentar a placa com 5 V no pino 5V; o regulador da placa baixa para 3,3 V. Você também pode fornecer 3,3 V no pino 3V3, mas, se a fonte não aguentar os picos de corrente do Wi-Fi, a placa vai ficar reiniciando. Uma fonte que forneça pelo menos 2 A evita a maioria dos erros de brownout.

Como resolver o erro Camera init failed do ESP32-CAM?

Os códigos de erro 0x105 ou 0x106 significam que a câmera nem foi encontrada: primeiro confira se CAMERA_MODEL_AI_THINKER está selecionado no código, depois se o cabo flat está bem encaixado, e alimente a placa com 5 V / 2 A. Se o problema continuar, o módulo da câmera pode estar com defeito. Se você vir 0xffffffff junto com frame buffer malloc failed, ative a PSRAM ou baixe a resolução.

O ESP32-CAM funciona sem internet?

Sim. Para ver a imagem você só precisa de uma rede local, não da internet; o ESP32-CAM também pode criar a própria rede Wi-Fi com WiFi.softAP() e aí é acessado no navegador em 192.168.4.1. Dá até para usá-lo sem nenhuma rede, como uma câmera que só salva fotos em um cartão microSD.

O ESP32-CAM grava vídeo?

Os exemplos prontos transmitem vídeo ao vivo em MJPEG e tiram fotos individuais; eles não gravam um arquivo de vídeo diretamente. Há projetos da comunidade que gravam quadros JPEG seguidos em um cartão microSD para montar um arquivo AVI, mas a taxa de quadros é limitada mesmo em resoluções baixas. A placa não tem microfone, então também não grava som.

Ver todos os projetos
LED piscando com ESP32
#103Iniciante

LED piscando com ESP32

Ensina o uso básico de uma saída GPIO no ESP32. Fazemos um LED piscar ligando e desligando um pino digital. É a versão para ESP32 do clássico projeto blink do Arduino UNO: os comandos básicos de blink no ambiente Arduino são os mesmos, mas a disposição dos pinos e os níveis de 3,3 V dos GPIOs do ESP32 diferem dos do Arduino UNO.

4.7(37)
99
LED integrado do ESP32 piscando
#106Iniciante

LED integrado do ESP32 piscando

Faça o LED azul integrado do ESP32 DevKit V1 piscar. Nenhum componente externo é necessário! O primeiro projeto para experimentar ao comprar um ESP32. GPIO 2 está conectado ao LED integrado.

4.8(29)
53
Conexão Wi-Fi STA com ESP32 e display LCD
#127Avançado

Conexão Wi-Fi STA com ESP32 e display LCD

Neste projeto, conectamos o ESP32 à rede Wi-Fi de casa no modo estação (STA), de forma segura e tolerante a falhas. Guardamos o SSID e a senha em um arquivo secrets.h separado para evitar que sejam expostos no Git, configuramos um mecanismo de reconexão automática e exibimos o nível de sinal RSSI e o endereço IP em um display LCD I2C. O LED integrado funciona como indicador de status. É um gerenciador de conexão pronto para uso em produção.

4.4(21)
34
Servidor web assíncrono com ESP32 (IP no LCD)
#129Avançado

Servidor web assíncrono com ESP32 (IP no LCD)

Neste projeto, transformamos o ESP32 em um servidor web assíncrono que você pode controlar pelo celular ou computador na mesma rede Wi-Fi. Com a biblioteca ESPAsyncWebServer, o servidor processa várias requisições ao mesmo tempo (ao contrário do WebServer.h tradicional, que bloqueia a execução ao processar uma requisição). Você poderá abrir o endereço IP do ESP32 no navegador e clicar nos botões ON/OFF (as rotas /on e /off) para ligar e desligar o LED conectado ao GPIO 5.

4.8(16)
26
ESP32 mDNS: acesso via bluegrays-esp.local (com display LCD)
#131Avançado
Premium

ESP32 mDNS: acesso via bluegrays-esp.local (com display LCD)

Neste projeto, adicionamos o serviço mDNS (Multicast DNS) ao ESP32 para acessar o dispositivo por um nome de host fácil de ler, como bluegrays-esp.local, em vez de um endereço IP. Mesmo que o IP atribuído pelo DHCP mude, você pode acessar o dispositivo pelo mesmo nome. Também executamos um pequeno servidor web no dispositivo para enviar comandos de controle do LED pelo navegador no endereço http://bluegrays-esp.local/.

4.8(14)
23
Registrador de temperatura com ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avançado
Premium

Registrador de temperatura com ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Monte um registrador de temperatura com data e hora usando ESP32! Leia a temperatura e a umidade do DHT22 a cada minuto, obtenha a hora real do DS1307 RTC e grave os dados em CSV no cartão microSD. O OLED exibe a temperatura atual em letras grandes, a porcentagem de umidade, a data e a hora e o contador de registros. O arquivo /temp_log.csv no cartão SD pode ser aberto no Excel, Google Sheets ou pandas do Python para análise — ideal para monitorar estufas, acompanhar a temperatura de casa ou…

4.7(7)
12
Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
#145Avançado
Premium

Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)

Um sistema de alarme de segurança inteligente que aciona o buzzer e o LED quando o sensor PIR detecta movimento e, ao mesmo tempo, envia uma notificação instantânea ao proprietário pelo Telegram. Inclui um intervalo de espera de 30 segundos para limitar a frequência dos alarmes repetidos; esse mecanismo não valida as detecções do PIR nem elimina disparos falsos. Pode ser usado na segurança de casas, no monitoramento de garagens, depósitos ou salas de trabalho.

0.0(0)
9