Olá, caro leitor. Neste artigo, apresentarei os procedimentos necessários para acessar o módulo de câmera VGA OV7670. O artigo será dividido em duas partes, sendo a segunda referente ao processo para capturar imagens.
Módulo de câmera VGA
O módulo de câmera VGA utiliza o sensor de CMOS OV7670. As principais características desse sensor são indicadas a seguir [1]:
- Resolução máxima: 640 x 480;
- Taxa de transferência: Máximo de 30 fps em modo VGA;
- Tensão de operação: 2.5 V à 3.0 V;
- Alta sensibilidade em ambientes com pouca luz;
- Interface SCCB (Serial Camera Control Bus), compatível com interface I2C;
- Suporta VGA, CIF – Formatos de saída: YUV/YCBCr 4:2:2, RGB 565/555, GRB 4:2:2, RAW RGB Data;
- Controle automático de funções de imagem;
- Controle automático de qualidade de imagem, como saturação, matiz, gama, nitidez e anti-blooming;
- Auto detecção de flicker (50/60 Hz);
- Tamanho da lente: 1/6 ”;
- Ângulo de visão: 24 graus.
As características descritas são referentes ao sensor de imagem. Outras informações podem ser obtidas tanto no Application Note quanto no Datasheet do OV7670.
Em relação ao módulo, duas versões podem ser encontradas. A primeira utiliza somente o sensor OV7670 e apresenta os pinos para conexão entre o sensor e outro dispositivo. Essa versão é mostrada na Figura 1.
A pinagem do módulo é mostrada na Figura 2.
Já na segunda versão, um buffer (FIFO – First In First Out) é utilizado para armazenar os dados do sensor CMOS. O dispositivo utilizado é o CI AL422, próprio para tratar sinais de vídeo. Essa versão é mostrada nas Figura 3 e 4.
A pinagem do módulo é mostrada na Figura 5.
A diferença da pinagem entre os módulos é que o segundo apresenta sinais de controle do módulo FIFO.
Interface de Comunicação SCCB
Independente do módulo, a interface de comunicação com o sensor é a mesma. Tal interface é chamada de SCCB e é compatível com o protocolo I2C. Assim, dois pinos são utilizados na comunicação, sendo um para a sincronização e outro para transferência de dados. Essa configuração é ilustrada na Figura 6.
Para estruturar a interface SCCB foram definidas cinco funções:
- SCCB_Init: Determina condição inicial dos sinais de controle da interface SCCB;
- SCCB_Start: Inicia comunicação;
- SCCB_Stop: Finaliza comunicação;
- SCCB_ReadByte: Faz a leitura de um byte;
- SCCB_WriteByte: Escreve um byte.
Tais funções foram declaradas no arquivo de cabeçalho SCCB.h. Cabe ressaltar que o projeto pode ser encontrado neste link.
#ifndef INCLUDES_SCCB_H_ #define INCLUDES_SCCB_H_ #include "HardwareProxy.h" void SCCB_Init(void); void SCCB_ReadByte(uint8_t * data); void SCCB_WriteByte(uint8_t data); void SCCB_Start(void); void SCCB_Stop(void); #define SCCB_DELAY() Hw_Delay((1)) #define SCCB_ADDR_WR (0x21 << 1) #endif
O sinal SIO_C é controlado pelo dispositivo master, indicando a transferência de 1 bit quando o sinal passa do nível lógico 0 para 1. Quando o barramento está ocioso, o sinal SIO_C deve permanecer em nível lógico 1. Assim, quando uma transferência é iniciada, o sinal SIO_C é colocado em nível lógico 0. Considerando isso, a condição dos sinais é definida na função SCCB_INIT.
void SCCB_Init(void)
{
//Configure SDA and SCL as output pins and determines the initial condition
Hw_SDA_OUTPUT();
Hw_SCL_OUTPUT();
Hw_SDA_LOW();
Hw_SCL_LOW();
//Generate a clock pulse
SCCB_DELAY();
Hw_SCL_HIGH();
SCCB_DELAY();
Hw_SDA_HIGH();
}
O início da transmissão é dado quando o sinal SIO_D passa do nível lógico 1 para 0, e na sequência o sinal de clock também vai a zero. Já o final da transmissão ocorre quando o sinal SIO_D é posto em nível lógico 1 enquanto o sinal SIO_C está em nível lógico 1. Essas duas situações são ilustradas na Figura 7.
void SCCB_Start(void)
{
//First, turn on the SDA and SCL lines
Hw_SDA_HIGH();
Hw_SCL_HIGH();
//Then, turn off the SDA line
SCCB_DELAY();
Hw_SDA_LOW();
//Finally, turn off the SCL line
SCCB_DELAY();
Hw_SCL_LOW();
SCCB_DELAY();
}
void SCCB_Stop(void)
{
//First, turn off the SDA and SCL lines
Hw_SDA_LOW();
Hw_SCL_LOW();
//Then, turn on the SCL line
SCCB_DELAY();
Hw_SCL_HIGH();
//Finally, turn on the SDA line
SCCB_DELAY();
Hw_SDA_HIGH();
}
Essas funções são usadas pelo módulo OV7670 para as operações de escrita e leitura dos registradores de controle. Para tal, foram definidas as funções de transferência de dados entre os dispositivos.
void SCCB_WriteByte(uint8_t data)
{
uint8_t i;
//Perform left shift on data variable
//Check the MSB and then changes the SDA line to the corresponding value
for(i=0; i<8; i++)
{
//Activate or deactivate the SDA line
if((data & 0x80) != 0)
{
Hw_SDA_HIGH();
}
else
{
Hw_SDA_LOW();
}
//Generate a clock pulse
SCCB_DELAY();
Hw_SCL_HIGH();
SCCB_DELAY();
Hw_SCL_LOW();
SCCB_DELAY();
//shift left one bit
data = data << 1;
}
Hw_SDA_INPUT();
//Generate a clock pulse
SCCB_DELAY();
Hw_SCL_HIGH();
SCCB_DELAY();
Hw_SCL_LOW();
}
void SCCB_ReadByte(uint8_t * data)
{
int8_t i = 7;
uint8_t byte=0;
Hw_SDA_INPUT();
//Get 8 bits
do
{
//Generate a clock pulse
SCCB_DELAY();
Hw_SCL_HIGH();
SCCB_DELAY();
//Captures SDA level
if(Hw_READ_SDA())
{
byte = byte | (1 << (uint8_t)i);
}
Hw_SCL_LOW();
i--;
}while(i>=0);
Hw_SDA_HIGH();
//Generate a clock pulse
SCCB_DELAY();
Hw_SCL_HIGH();
SCCB_DELAY();
Hw_SCL_LOW();
if(data != NULL){
*data = byte;
}
}
Registradores de Controle
Com a interface SCCB implementada é possível configurar os registradores de controle do chip para o modo de operação desejado. Essas configurações são realizadas a partir de uma sequência correta de operações, chamadas ciclos de transmissão, que são classificadas da seguinte maneira:
- Ciclo de escrita dividido em três fases;
- Ciclo de escrita dividido em duas fases;
- Ciclo de leitura dividido em duas fases.
De modo geral, cada fase de transmissão envolve a transferência de 8 bits de dados e um nono bit X, com função Don’t Care. Além disso, na primeira fase da transmissão ocorre a escrita do endereço do dispositivo no barramento SCCB.
Ciclo de escrita dividido em três fases
Esse ciclo é utilizado para escrever em um registrador do dispositivo. Assim, a segunda informação transferida corresponde ao endereço do registrador seguido do valor que será armazenado.
void OV7670_WriteRegister(uint8_t addr, uint8_t data)
{
//Start of transmission
SCCB_Start();
SCCB_WriteByte(SCCB_ADDR_WR);
SCCB_WriteByte((uint8_t)addr);
SCCB_WriteByte((uint8_t)data);
//End of transmission
SCCB_Stop();
}
Ciclo de escrita e leitura dividido em duas fases
Esse procedimento é utilizado para indicar o endereço de um registrador que será acessado para função de leitura. Cabe ressaltar que essa etapa ocorre no ciclo de escrita dividido em três fases.
Para ler o valor do registrador é necessário determinar novamente o ID do dispositivo e, em seguida, capturar o valor.
uint8_t OV7670_ReadRegister(uint8_t addr)
{
uint8_t result;
//Start of transmission
SCCB_Start();
//ID Address + Sub-address
SCCB_WriteByte(SCCB_ADDR_WR);
SCCB_DELAY();
SCCB_WriteByte((uint8_t)addr);
//End of transmission
SCCB_Stop();
SCCB_DELAY();
//Start of transmission
SCCB_Start();
//ID Address + Read Data
SCCB_WriteByte(SCCB_ADDR_WR | 0x01);
SCCB_ReadByte(&result);
//End of transmission
SCCB_Stop();
return result;
}
Próximo artigo
No próximo artigo será apresentado o procedimento para capturar um frame do módulo OV7670 utilizando o buffer AL422. Além do controle o buffer, a interface SCCB será utilizada para realizar a configuração dos registradores de controle do módulo OV7670.
O projeto pode ser acessado neste link.
Saiba mais
Aplicação com câmera usando Qt5
Calibração de câmeras – Parte 1
Utilizando Câmeras em Sistemas Linux Embarcado
Referências
[1] Módulo câmera VGA OV7670 [2] Serial Camera Control Bus Functional SpecificationImagem destacada: https://en.wikipedia.org/wiki/Mode_13h#/media/File:VGA_palette_with_black_borders.svg












Bom dia, é possível com esta camera tira fotos e armazenar em um cartão de memoria?
olá, vamos ver se voce consegue me ajudar, preciso fazer reconhecimento facial com essa câmera, acoplada a um Arduíno uno, é possível? algum site que o senhor indica?
É possível sim, porem o arduino possibilita a captura de um frame a cada 3 – 5 segundos. Utilizei o arduino junto com o modulo OV7670 para adquirir e enviar os dados para o PC.
Checa esse link:
https://github.com/tensorflow/models/tree/master/research/object_detection
Utilizei TensorFlow para a detecção de objetos e pessoas, voce pode treinar uma rede neural para fazer o reconhecimento facial.
Estou tentando ha um tempão botar pra funcionar os módulos OV9655 e OV2640. Consegui com resolução 320×240. Acho que a documentação das câmeras é bem limitada e de acordo com algumas pessoas as datasheets disponíveis estão erradas. O fabricante nunca retorna quando solicito guias de usuário e datasheets. Agora, estou tentando com resoluções maiores. Para isso, estou usando uma memoria externa. Aguardo a próxima parte pra ver se entendo melhor alguns pontos que não ficaram tao claros pra mim enquanto trabalhava no projeto.