Câmera VGA OV7670: Manual Técnico Completo

Câmera VGA OV7670 — manual técnico completo

Introdução

Neste manual, será apresentado como instalar, configurar e utilizar o módulo Câmera VGA OV7670. Se desejar adquirir este produto, clique aqui.

Este material foi elaborado sob rigorosos parâmetros de engenharia eletrônica e processamento de sinais digitais, servindo como guia de referência técnica para projetistas, integradores e desenvolvedores de sistemas embarcados. A câmera digital baseada no circuito integrado OV7670 da OmniVision é um dispositivo de captura de imagens CMOS amplamente utilizado em projetos de visão computacional embarcada, rastreamento de linhas, detecção de movimento e robótica autônoma com plataformas microcontroladas como Arduino, ESP32, AVR, PIC e ARM Cortex. Ao longo dos tópicos a seguir, são explorados os limites elétricos, o barramento de controle SCCB (Serial Camera Control Bus), a temporização de sinais de sincronismo, cálculos de memória e algoritmos em C++ validados em bancada.

Especificações técnicas

O módulo integra o sensor de imagem monolítico CMOS de alta sensibilidade OmniVision OV7670, dotado de lente focal padrão ajustável com rosca M12 (F1.8/6 mmF1.8 / 6\,\text{mm}) e circuito impresso de suporte com desacoplamento de sinal e componentes passivos SMD.

Principais especificações

A tabela abaixo resume as propriedades ópticas, formatos de amostragem e parâmetros de processamento do módulo:

ParâmetroEspecificação Técnica
Circuito Integrado SensorOmniVision OV7670 (CMOS Image Sensor)
Tamanho Óptico do Sensor1/6′′1/6^{\prime\prime}
Resolução Máxima Nativa640×480640 \times 480 pixels (Padrão VGA)
Matriz de Resoluções SuportadasVGA (640×480640 \times 480), CIF (352×288352 \times 288), QCIF (176×144176 \times 144), QQVGA (160×120160 \times 120)
Formatos de Saída de CorRaw RGB, RGB565 / RGB555 / RGB444, YUV (4:2:24:2:2), YCbCr (4:2:24:2:2)
Taxa Máxima de Quadros (Frame Rate)Até 30 fps30\,\text{fps} em resolução VGA
Ângulo de Visão (FOV)Aproximadamente 25∘25^\circ a 60∘60^\circ (dependente da lente instalada)
Relação Sinal-Ruído (SNR)46 dB46\,\text{dB}
Faixa Dinâmica (Dynamic Range)52 dB52\,\text{dB}
Sensibilidade Fotométrica1,3 V/(lux⋅s)1{,}3\,\text{V} / (\text{lux} \cdot \text{s})
Interface de Controle de RegistradoresSCCB (Serial Camera Control Bus) — compatível com protocolo I2C
Interface de Dados de PixelBarramento paralelo digital síncrono de 8 bits (D0D_0 a D7D_7)
Sinais de SincronismoVSYNC (Quadro), HREF (Linha) e PCLK (Pixel Clock)
Frequência de Clock Externo (XCLK)10 MHz10\,\text{MHz} a 48 MHz48\,\text{MHz} (típico 8 MHz8\,\text{MHz} a 24 MHz24\,\text{MHz})
Ajuste de FocoAnel mecânico rosqueável na lente com trava manual
Dimensões Físicas da Placa35,0 mm×35,0 mm×26,0 mm35{,}0\,\text{mm} \times 35{,}0\,\text{mm} \times 26{,}0\,\text{mm} (com lente montada)

Características elétricas e operacionais

O módulo requer alimentação de baixa tensão e opera com níveis lógicos estritamente compatíveis com barramentos LVCMOS / LVTTL de 3,3 V3{,}3\,\text{V}:

Grandeza Elétrica / OperacionalMínimoTípicoMáximoUnidade
Tensão de Alimentação do Módulo (VCC / 3V3)3,03{,}03,33{,}33,63{,}6V\text{V}
Corrente Ativa em Operação Contínua202030304545mA\text{mA}
Consumo de Potência Ativa (30 fps30\,\text{fps})—60609090mW\text{mW}
Corrente em Modo Standby / Sleep (PWDN em nível alto)—<20< 204040μA\mu\text{A}
Nível Lógico de Entrada Alto (VIHV_{IH})0,7×VCC0{,}7 \times \text{VCC}—VCC+0,3\text{VCC} + 0{,}3V\text{V}
Nível Lógico de Entrada Baixo (VILV_{IL})−0,3-0{,}3—0,3×VCC0{,}3 \times \text{VCC}V\text{V}
Nível Lógico de Saída Alto (VOHV_{OH})2,42{,}4—VCC\text{VCC}V\text{V}
Nível Lógico de Saída Baixo (VOLV_{OL})0,00{,}0—0,40{,}4V\text{V}
Temperatura de Operação−30-30+25+25+70+70∘C^\circ\text{C}
Temperatura Estável de Imagem00+25+25+50+50∘C^\circ\text{C}

⚠️ Atenção: Os pinos de entrada de controle e clock da câmera OV7670 (SIOC, SIOD, XCLK, RESET e PWDN) não toleram nível lógico de 5,0 V. Ao conectar o módulo a placas microcontroladas com nível lógico de 5 V5\,\text{V} (como Arduino Uno R3, Arduino Mega 2560 ou microcontroladores PIC de 5 V5\,\text{V}), é mandatório o uso de translações de nível lógico ou divisores de tensão resistivos. A aplicação direta de 5 V5\,\text{V} nos pinos do sensor provoca sobretensão irreversível nos transistores de silício do chip.

Descrição do produto

O que é o OV7670?

O OV7670 é um circuito integrado sensor de imagem colorida CMOS de alta performance desenvolvido pela OmniVision Technologies. Ele engloba em um único componente uma matriz ativa de fotodiodos de 640×480640 \times 480 pontos, circuitos de amplificação analógica de baixo ruído, conversores analógico-digitais dedicados e um processador digital de sinal de imagem (ISP — Image Signal Processor) responsável por controle automático de ganho (AGC), exposição automática (AEC), balanço de branco automático (AWB) e calibração de nível de preto.

Na versão em módulo para prototipagem e desenvolvimento, o componente é montado em uma placa de circuito impresso com soquete para lente M12 e barra de 18 pinos macho no espaçamento padrão de 2,54 mm2{,}54\,\text{mm} (pitch standard). Essa arquitetura disponibiliza diretamente o barramento digital de dados de 8 bits e as linhas de temporização síncronas para captura contínua de quadros em sistemas microprocessados sem periféricos de vídeo analógico complexos.

Para que serve?

O módulo OV7670 atua como o dispositivo óptico de entrada para aquisição de vídeo e fotografia em tempo real, atendendo às seguintes aplicações práticas:

  • Robótica Móvel Autônoma: rastreamento de linhas industriais, reconhecimento de marcos visuais (QR Codes e marcadores AprilTag) e identificação de obstáculos em arenas de competição;
  • Sistemas de Segurança e Monitoramento: captura de fotografias sob disparo de sensores de presença e transmissão remota de quadros via rede cabeada ou sem fio;
  • Inspeção e Triagem Industrial: classificação automatizada de peças e objetos por cor dominante, contraste e dimensões geométricas em esteiras transportadoras.

Por que devo usar?

  • Processador ISP Integrado no Chip: executa correções ópticas avançadas (gama, redução de ruído, saturação, nitidez e correção de lentes) diretamente no hardware sem sobrecarregar a memória e a CPU do microcontrolador;
  • Excelente Relação Custo-Benefício: fornece resolução fotográfica VGA completa com controle pixel a pixel a uma fração do custo de câmeras USB industriais ou módulos baseados em protocolos MIPI CSI;
  • Flexibilidade de Modos de Cor e Resolução: permite reconfigurar a resolução sob demanda para resoluções menores (como QQVGA 160×120160 \times 120), viabilizando algoritmos rápidos de processamento com microcontroladores de memória RAM reduzida.

Quando devo usar?

O módulo OV7670 é a escolha ideal para:

  • Projetos em que o microcontrolador hospedeiro dispõe de pinos de entrada paralela rápidos ou suporte a DMA (Direct Memory Access), como a família ESP32, placas STM32 e microcontroladores Raspberry Pi RP2040;
  • Aplicações que necessitam de imagens em cores de baixa a média resolução para processamento local ou streaming serial rápido.

Quando não devo usar:

  • Projetos baseados exclusivamente em microcontroladores com arquitetura de 8 bits e memória estática ultrarreduzida (como o ATmega328P do Arduino Uno, que conta com apenas 2 kB2\,\text{kB} de SRAM), caso o objetivo seja armazenar um quadro fotográfico completo de 640×480640 \times 480 pixels em memória sem hardware intermediário. Para o Arduino Uno convencional, o processamento direto sem buffer requer amostragem em resoluções minúsculas (ex.: 160×120160 \times 120) em streaming contínuo pela serial ou o uso da versão do módulo com chip de memória FIFO onboard (OV7670 com AL422B);
  • Projetos de visão computacional de alta resolução (Full HD ou 4K), vigilância noturna em infravermelho de longo alcance ou reconhecimento facial com redes neurais convolucionais profundas (onde módulos como a OV2640 ou câmeras USB conectadas a SBCs como Raspberry Pi 4/5 são recomendados).

Pinout e diagrama de entradas/saídas

O módulo de câmera OV7670 possui uma barra dupla de 18 pinos dispostos em 2 fileiras de 9 pinos (passo 2,54 mm2{,}54\,\text{mm}). A tabela abaixo descreve cada pino, sua direção de sinal e sua função lógica:

PinoDireçãoNome do SinalDescrição Técnica e Nível Lógico
3V3AlimentaçãoEntrada de VCCTensão contínua regulada de 3,0 V3{,}0\,\text{V} a 3,6 V3{,}6\,\text{V} DC (típico 3,3 V3{,}3\,\text{V}).
GNDAlimentaçãoTerra de ReferênciaPotencial de referência comum do sistema (0 V0\,\text{V}).
SIOCEntradaSCCB Clock (SCL)Linha de clock serial do barramento SCCB (compatível com I2C até 400 kHz400\,\text{kHz}). Requer pull-up.
SIODBidirecionalSCCB Data (SDA)Linha de dados serial do barramento SCCB (compatível com I2C). Requer resistor de pull-up.
VSYNCSaídaVertical SyncSincronismo vertical de quadro. Pulso em nível alto indica a transição entre quadros sucessivos.
HREFSaídaHorizontal ReferenceReferência horizontal de linha. Nível alto indica transmissão de dados de pixels válidos na linha.
PCLKSaídaPixel ClockClock de saída de pixel. Cada borda de subida/descida valida um novo byte nos pinos D0∼D7D_0 \sim D_7.
XCLKEntradaMaster System ClockClock mestre fornecido pelo microcontrolador ao sensor (frequência entre 8 MHz8\,\text{MHz} e 24 MHz24\,\text{MHz}).
D7SaídaData Bit 7Bit mais significativo (MSB) do barramento paralelo de dados de pixel.
D6SaídaData Bit 6Bit 6 de dados de pixel.
D5SaídaData Bit 5Bit 5 de dados de pixel.
D4SaídaData Bit 4Bit 4 de dados de pixel.
D3SaídaData Bit 3Bit 3 de dados de pixel.
D2SaídaData Bit 2Bit 2 de dados de pixel.
D1SaídaData Bit 1Bit 1 de dados de pixel.
D0SaídaData Bit 0Bit menos significativo (LSB) do barramento paralelo de dados de pixel.
RESETEntradaHardware ResetEntrada de reinicialização ativa em nível baixo (0 V0\,\text{V}). Manter em 3,3 V3{,}3\,\text{V} para operação normal.
PWDNEntradaPower Down ModeModo de economia de energia. Nível alto (3,3 V3{,}3\,\text{V}) desliga o sensor; conectar a GND (0 V0\,\text{V}) para operar.

Como fazer a ligação

Requisitos de instalação e alimentação

Para assegurar estabilidade de sinal e imunidade a ruídos de alta frequência na transmissão paralela de vídeo, atenda aos seguintes critérios:

  1. Fonte de Alimentação Limpa: alimente o pino 3V3 estritamente com fonte estável de 3,3 V3{,}3\,\text{V} capaz de fornecer pelo menos 100 mA100\,\text{mA}. Instale um capacitor cerâmico de desacoplamento de 100 nF100\,\text{nF} em paralelo com um capacitor eletrolítico ou tântalo de 10 μF10\,\mu\text{F} bem próximo aos terminais de alimentação do módulo;
  2. Compatibilidade de Nível Lógico (3,3 V): caso utilize um Arduino com lógica de 5 V5\,\text{V}, os sinais provenientes do Arduino para a câmera (XCLK, SIOC, SIOD, RESET e PWDN) devem passar por conversores bidirecionais de nível lógico de alta velocidade (baseados em MOSFETs tipo BSS138) ou divisores resistivos;
  3. Resistores de Pull-up nas Linhas SCCB/I2C: adicione resistores de pull-up de 4,7 kΩ4{,}7\,\text{k}\Omega entre as linhas SIOC e SIOD e o barramento de 3,3 V3{,}3\,\text{V};
  4. Comprimento Reduzido dos Jumpers: o barramento paralelo opera com frequências de clock de pixel da ordem de vários megahertz. Condutores longos causam reflexão de sinal e capacitância parasita excessiva. Utilize fios curtos com comprimento máximo de 10 cm10\,\text{cm} a 15 cm15\,\text{cm}.

Diagrama de ligação elétrica

O infográfico a seguir demonstra a organização em blocos das linhas de alimentação, barramento de controle SCCB/I2C, sinais de temporização de clock e barramento paralelo de dados do módulo OV7670:

Diagrama de ligação elétrica do módulo Câmera VGA OV7670

Tabela de conexões dos terminais

A conexão padronizada entre a câmera OV7670 e uma placa microcontroladora típica de 3,3 V3{,}3\,\text{V} (como a família ESP32 DevKit) é detalhada na tabela a seguir:

Terminal da OV7670Conexão no ESP32 DevKitTipo de SinalObservação Técnica
3V3Pino 3V3 da PlacaAlimentação DCTensão contínua regulada de 3,3 V3{,}3\,\text{V}
GNDPino GND da PlacaReferência 0VTerra comum de sinal e alimentação
SIOCPino GPIO 22 (SCL)Entrada de ClockBarramento SCCB com pull-up de 4,7 kΩ4{,}7\,\text{k}\Omega a 3,3 V
SIODPino GPIO 21 (SDA)Dados BidirecionalBarramento SCCB com pull-up de 4,7 kΩ4{,}7\,\text{k}\Omega a 3,3 V
VSYNCPino GPIO 25Saída da CâmeraPulso de sincronismo vertical (fim/início de quadro)
HREFPino GPIO 26Saída da CâmeraReferência horizontal (indica linha ativa)
PCLKPino GPIO 27Saída da CâmeraClock de amostragem de byte de pixel
XCLKPino GPIO 0 (PWM / LEDC)Entrada da CâmeraSinal de clock mestre de alta frequência (10 MHz10\,\text{MHz} a 20 MHz20\,\text{MHz})
D7Pino GPIO 35Saída de DadosBit 7 do barramento paralelo (MSB)
D6Pino GPIO 34Saída de DadosBit 6 do barramento paralelo
D5Pino GPIO 39Saída de DadosBit 5 do barramento paralelo
D4Pino GPIO 36Saída de DadosBit 4 do barramento paralelo
D3Pino GPIO 19Saída de DadosBit 3 do barramento paralelo
D2Pino GPIO 18Saída de DadosBit 2 do barramento paralelo
D1Pino GPIO 5Saída de DadosBit 1 do barramento paralelo
D0Pino GPIO 4Saída de DadosBit 0 do barramento paralelo (LSB)
RESETPino 3V3 (ou GPIO dedicado)Entrada da CâmeraNível alto (3,3 V3{,}3\,\text{V}) para operação contínua
PWDNPino GNDEntrada da CâmeraNível baixo (0 V0\,\text{V}) para manter o módulo ativo

💡 Dica: Caso a conexão seja realizada em um Arduino Uno operando a 5 V5\,\text{V}, todos os sinais de saída do Arduino direcionados à câmera (como a geração do sinal XCLK no pino digital D11 e as linhas I2C) devem passar por divisores de tensão com resistores de 1 kΩ1\,\text{k}\Omega e 2 kΩ2\,\text{k}\Omega para limitar a tensão a aproximadamente 3,33 V3{,}33\,\text{V}. Os sinais que saem da câmera em direção ao Arduino (VSYNC, HREF, PCLK e D0..D7) possuem amplitude nativa de 3,3 V3{,}3\,\text{V} e são reconhecidos de forma segura como nível alto pelas entradas do ATmega328P (VIH(min⁡)≈3,0 VV_{IH(\min)} \approx 3{,}0\,\text{V}).

Cuidados e observações de segurança

⚠️ Atenção: Nunca conecte o terminal de alimentação 3V3 à linha de 5V da sua fonte ou placa microcontroladora. O circuito integrado OV7670 opera internamente com tensões de núcleo de 1,8 V1{,}8\,\text{V} derivadas na própria placa e queima irreversivelmente quando submetido a 5 V5\,\text{V}.

⛔ Perigo: O módulo OV7670 é um componente puramente eletrônico sensível a descargas eletrostáticas (ESD) e opera estritamente em baixa tensão contínua (3,3 V3{,}3\,\text{V} DC). NUNCA submeta nenhum de seus terminais à rede elétrica alternada de 127 V127\,\text{V} ou 220 V220\,\text{V} AC. O contato acidental com potenciais de rede elétrica causa queima explosiva imediata do sensor, destruição de todos os equipamentos conectados via USB e grave risco de choque elétrico.

Como usar

Guia de operação passo a passo

  1. Montagem e Conferência da Tensão:
    • Realize as ligações com a fonte de bancada ou microcontrolador desenergizado;
    • Meça com um multímetro na escala de tensão contínua o pino de alimentação para certificar-se de que a tensão sobre o módulo é exatamente de 3,3 V3{,}3\,\text{V};
  2. Geração do Sinal de Clock Mestre (XCLK):
    • O sensor OV7670 não inicia sua lógica interna nem responde ao barramento I2C/SCCB se não receber pulsos de clock externos contínuos no pino XCLK;
    • Configure previamente no firmware um gerador de onda quadrada de alta frequência (usando o periférico PWM / LEDC do ESP32 ou o Timer2 do Arduino) ajustado entre 8 MHz8\,\text{MHz} e 20 MHz20\,\text{MHz};
  3. Comunicação I2C / SCCB e Leitura de Identificação:
    • O endereço de escrita de 8 bits do registrador SCCB da OV7670 é 0x42, o que corresponde ao endereço I2C de 7 bits padrão 0x21 na biblioteca <Wire.h> da Arduino IDE;
    • Faça uma leitura dos registradores de identificação do fabricante (PID no registrador 0x0A e VER no registrador 0x0B) para validar a conectividade física do barramento serial;
  4. Envio da Sequência de Inicialização dos Registradores:
    • Grave a tabela de inicialização que define o modo de saída desejado (como resolução QQVGA ou CIF e formato de cor RGB565 ou YUV);
  5. Captura e Sincronismo dos Dados de Imagem:
    • Monitore a borda do pino VSYNC para detectar o começo do quadro;
    • Monitore o pino HREF para ler a linha horizontal ativa;
    • A cada borda de subida do pino PCLK, capture o byte presente no barramento paralelo D0 a D7;
  6. Ajuste Manual do Foco Óptico:
    • Gire suavemente o anel rosqueável da lente cilíndrica M12 enquanto visualiza a imagem capturada na tela do computador até obter nitidez geométrica ideal no objeto focalizado.

Modos de operação e ajustes

Cálculo da Memória de Buffer e Taxa de Transmissão

A quantidade de memória necessária para armazenar um quadro de imagem descompactado depende diretamente da resolução escolhida e da profundidade de bits do formato de cor:

Memoˊria por Quadro=Largura×Altura×Bytes por Pixel\text{Memória por Quadro} = \text{Largura} \times \text{Altura} \times \text{Bytes por Pixel}

Para o formato de cores RGB565 (2 bytes por pixel), temos os seguintes tamanhos de buffer de memória:

Em resolução nativa VGA (640×480640 \times 480 pixels):

BufferVGA=640×480×2=614.400 bytes≈600 kB\text{Buffer}_{\text{VGA}} = 640 \times 480 \times 2 = 614.400\,\text{bytes} \approx 600\,\text{kB}

Em resolução intermediária CIF (352×288352 \times 288 pixels):

BufferCIF=352×288×2=202.752 bytes≈198 kB\text{Buffer}_{\text{CIF}} = 352 \times 288 \times 2 = 202.752\,\text{bytes} \approx 198\,\text{kB}

Em resolução reduzida QQVGA (160×120160 \times 120 pixels):

BufferQQVGA=160×120×2=38.400 bytes≈37,5 kB\text{Buffer}_{\text{QQVGA}} = 160 \times 120 \times 2 = 38.400\,\text{bytes} \approx 37{,}5\,\text{kB}

💡 Dica: O microcontrolador ATmega328P do Arduino Uno possui apenas 2048 bytes2048\,\text{bytes} (2 kB2\,\text{kB}) de memória SRAM, tornando inviável reter um quadro inteiro de 37,5 kB37{,}5\,\text{kB} ou 600 kB600\,\text{kB} na memória. No Arduino Uno sem chip de FIFO externa, os pixels devem ser processados diretamente na chegada linha a linha ou transmitidos byte a byte via porta serial em baud rate ultra-alto (1.000.000 bps1.000.000\,\text{bps}). Por outro lado, o microcontrolador ESP32 conta com 520 kB520\,\text{kB} de SRAM interna, acomodando tranquilamente buffers inteiros em resolução QQVGA e QCIF.

Divisor Resistivo de Tensão para Sinais de 5V

Quando o sinal lógico de comando for emitido por saídas digitais de 5 V5\,\text{V} (Arduino Uno), a redução para o patamar seguro de 3,3 V3{,}3\,\text{V} é calculada pela fórmula do divisor de tensão:

Vout=Vin⋅R2R1+R2V_{\text{out}} = V_{\text{in}} \cdot \frac{R_2}{R_1 + R_2}

Utilizando resistores comerciais de precisão com R1=1,0 kΩR_1 = 1{,}0\,\text{k}\Omega e R2=2,0 kΩR_2 = 2{,}0\,\text{k}\Omega:

Vout=5,0 V⋅2000 Ω1000 Ω+2000 Ω=5,0 V⋅23≈3,33 VV_{\text{out}} = 5{,}0\,\text{V} \cdot \frac{2000\,\Omega}{1000\,\Omega + 2000\,\Omega} = 5{,}0\,\text{V} \cdot \frac{2}{3} \approx 3{,}33\,\text{V}

O valor obtido de 3,33 V3{,}33\,\text{V} enquadra-se com margem de segurança dentro da janela operacional do pino de entrada da câmera (3,0 V≤V≤3,6 V3{,}0\,\text{V} \le V \le 3{,}6\,\text{V}).

Exemplos práticos de uso

O código em C++ a seguir foi desenvolvido para microcontroladores da família ESP32 na Arduino IDE. O firmware inicializa o gerador de clock mestre XCLK em 10 MHz10\,\text{MHz} via hardware LEDC, configura o barramento SCCB via <Wire.h>, consulta os registradores de identificação da câmera e aguarda a sincronização do primeiro quadro:

#include <Arduino.h>
#include <Wire.h>

// Definição dos pinos de controle SCCB (I2C)
#define SIOD_PIN  21  // SDA do ESP32
#define SIOC_PIN  22  // SCL do ESP32

// Definição do pino de Clock Mestre (XCLK)
#define XCLK_PIN  0   // Saída de clock para a câmera

// Definição dos pinos de sincronismo
#define VSYNC_PIN 25  // Sincronismo vertical
#define HREF_PIN  26  // Referência horizontal
#define PCLK_PIN  27  // Pixel clock

// Endereço I2C de 7 bits do sensor OV7670 (0x42 no formato de 8 bits)
#define OV7670_I2C_ADDR 0x21

// Registradores de identificação do chip
#define REG_PID   0x0A  // Product ID MSB (esperado: 0x76)
#define REG_VER   0x0B  // Product ID LSB (esperado: 0x70 ou 0x73)
#define REG_COM7  0x12  // Reset e controle de formato

/**
 * Escreve um valor em um registrador do sensor via SCCB/I2C
 */
bool writeRegister(uint8_t reg, uint8_t value) {
  Wire.beginTransmission(OV7670_I2C_ADDR);
  Wire.write(reg);
  Wire.write(value);
  return (Wire.endTransmission() == 0);
}

/**
 * Lê o valor de um registrador do sensor via SCCB/I2C
 */
uint8_t readRegister(uint8_t reg) {
  Wire.beginTransmission(OV7670_I2C_ADDR);
  Wire.write(reg);
  Wire.endTransmission(false);
  
  Wire.requestFrom((uint8_t)OV7670_I2C_ADDR, (uint8_t)1);
  if (Wire.available()) {
    return Wire.read();
  }
  return 0xFF; // Retorna 0xFF em caso de erro de leitura
}

/**
 * Inicializa a geração de clock mestre externo (XCLK) em 10 MHz
 */
void setupXCLK() {
  // Configura o canal PWM 0 com frequência de 10 MHz e resolução de 2 bits (50% duty cycle)
  ledcSetup(0, 10000000, 2);
  ledcAttachPin(XCLK_PIN, 0);
  ledcWrite(0, 2); // 50% de ciclo de trabalho em resolução de 2 bits (0 a 3)
}

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    delay(10);
  }

  Serial.println(F("========================================"));
  Serial.println(F("RoboBuilders - Teste da Câmera OV7670"));
  Serial.println(F("========================================"));

  // 1. Inicializa o clock mestre XCLK (mandatório antes do I2C)
  setupXCLK();
  Serial.println(F("[OK] Clock mestre XCLK gerado em 10 MHz no GPIO 0"));
  delay(50); // Aguarda a estabilização do oscilador interno da câmera

  // 2. Inicializa o barramento I2C para comunicação SCCB
  Wire.begin(SIOD_PIN, SIOC_PIN, 100000); // Clock I2C a 100 kHz
  Serial.println(F("[OK] Barramento I2C iniciado"));

  // 3. Aplica reinicialização por software no sensor
  writeRegister(REG_COM7, 0x80); // Bit 7 em 1 executa software reset
  delay(100);                    // Aguarda reset completo dos circuitos

  // 4. Lê os registradores de identificação do modelo
  uint8_t pid = readRegister(REG_PID);
  uint8_t ver = readRegister(REG_VER);

  Serial.print(F("Leitura de Identificacao: PID = 0x"));
  Serial.print(pid, HEX);
  Serial.print(F(" | VER = 0x"));
  Serial.println(ver, HEX);

  if (pid == 0x76) {
    Serial.println(F("[SUCESSO] Sensor OV7670 identificado corretamente!"));
  } else {
    Serial.println(F("[ALERTA] Falha na comunicacao SCCB. Verifique alimentacao e pull-ups."));
  }

  // 5. Configuração dos pinos de sincronismo
  pinMode(VSYNC_PIN, INPUT);
  pinMode(HREF_PIN, INPUT);
  pinMode(PCLK_PIN, INPUT);
}

void loop() {
  // Monitoramento simples do sinal de sincronismo vertical (VSYNC)
  static unsigned long lastFrameTime = 0;
  static unsigned long frameCount = 0;

  // Aguarda borda de subida do sinal VSYNC (indica novo quadro)
  if (digitalRead(VSYNC_PIN) == HIGH) {
    frameCount++;
    
    if (millis() - lastFrameTime >= 1000) {
      Serial.print(F("Taxa de quadros detectada: "));
      Serial.print(frameCount);
      Serial.println(F(" FPS"));
      
      frameCount = 0;
      lastFrameTime = millis();
    }

    // Aguarda retorno a nível baixo para evitar contagem múltipla do mesmo quadro
    while (digitalRead(VSYNC_PIN) == HIGH) {
      yield();
    }
  }
}

Projetos

Para aprofundar suas habilidades práticas em visão computacional e streaming de vídeo com microcontroladores modernos, consulte o projeto prático publicado no blog da RoboBuilders:

Conclusão

Neste manual técnico, foram apresentados todos os aspectos essenciais para a integração e operação do módulo Câmera VGA OV7670:

  • Arquitetura e Sensores: especificações do sensor de imagem CMOS VGA de 640×480640 \times 480 pixels com processador ISP integrado;
  • Limites Elétricos e Operacionais: exigência de alimentação estabilizada em 3,3 V3{,}3\,\text{V} DC e necessidade de translação de nível lógico em placas de 5 V5\,\text{V};
  • Temporização e Conexões: mapeamento detalhado dos 18 pinos do módulo, cobrindo barramento serial SCCB/I2C, clock mestre XCLK, sinais de sincronismo (VSYNC, HREF, PCLK) e barramento paralelo de dados de 8 bits;
  • Dimensionamento Matemático: cálculo do volume de memória necessário para armazenamento de quadros e equacionamento de divisores resistivos;
  • Firmware Validado: implementação em C++ com geração de clock de 10 MHz10\,\text{MHz} via hardware e leitura de registradores internos via I2C.

Solução de problemas

Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Câmera VGA OV7670: Manual Técnico Completo e eu ajudarei a encontrar a solução.

O assistente usa IA e pode errar. Confirme informações críticas no datasheet oficial do fabricante.