Ativando a Visão da EchoVision: Do Zero ao Streaming em 5 Minutos

Seja bem-vindo de volta ao ecossistema Zion! Se no último post ensinamos sua EchoVision a falar, hoje vamos dar a ela o dom da visão.

Muitos desenvolvedores travam na hora de configurar câmeras no ESP32-S3 porque tentam adivinhar a pinagem ou usam frequências de clock erradas que geram artefatos na imagem. Neste tutorial, vamos direto ao ponto: usar o exemplo robusto da própria Espressif, mas com a “alma” (código) ajustada para o hardware da Zion.

O objetivo? Um servidor de streaming de vídeo funcional acessível pelo navegador do seu celular ou PC.


O que você vai precisar:

  • Placa EchoVision (ESP32-S3 N16R8)
  • Câmera OV2640 (geralmente enviada junto com o kit, conectada ao slot FPC)
  • Cabo USB-C de dados
  • Arduino IDE configurada

Passo 1: A Base Sólida (O Exemplo Nativo)

Não precisamos reinventar a roda para o servidor web. A biblioteca do ESP32 já traz um exemplo incrível que cria uma interface com controles de face detection, resolução e qualidade.

  1. Abra a Arduino IDE.
  2. Vá em Arquivo > Exemplos > ESP32 > Camera > CameraWebServer.
  3. Isso abrirá um projeto com vários arquivos (abas), como app_httpd.cpp, camera_index.h, etc. Não mexa nessas abas auxiliares, elas são o motor do servidor web.

Passo 2: O “Pulo do Gato” (Substituindo o Código)

O exemplo nativo vem configurado para placas genéricas da China (como AI-Thinker). Se você compilar direto, a tela ficará preta ou a câmera nem iniciará.

O segredo está no arquivo principal (o .ino). Vamos apagar todo o código que veio no arquivo principal CameraWebServer e substituir pelo Código Oficial Zion abaixo.

Este código já traz:

  • Pinagem Mapeada: Todos os pinos de dados (Y2-Y9), VSYNC, HREF e PCLK da EchoVision.
  • Clock Ajustado (10MHz): Essencial para estabilidade do sinal em cabos flat.
  • Gerenciamento de Memória: Detecta automaticamente se deve usar a PSRAM (alta qualidade) ou DRAM.

Copie e cole este código no lugar do conteúdo do arquivo .ino:

#include "esp_camera.h"
#include <WiFi.h>

// ============================================================================
// 1. PINAGEM DA Z-S3 ECHOVISION (Compatível com ESP32-S3-EYE)
// ============================================================================
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 4
#define SIOC_GPIO_NUM 5

#define Y9_GPIO_NUM 16
#define Y8_GPIO_NUM 17
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 12
#define Y5_GPIO_NUM 10
#define Y4_GPIO_NUM 8
#define Y3_GPIO_NUM 9
#define Y2_GPIO_NUM 11

#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13 // O pino crítico que define o clock de pixel
// ============================================================================

// Substitua pelas suas credenciais
const char* ssid = "SEU_WIFI_AQUI";
const char* password = "SUA_SENHA_AQUI";

void startCameraServer();

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  delay(2000); 
  Serial.println("\n--- INICIANDO Z-S3 ECHOVISION CAM ---");

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  
  // ==========================================================================
  // 2. CONFIGURAÇÕES DE ESTABILIDADE (O Segredo do Sucesso)
  // ==========================================================================
  config.xclk_freq_hz = 10000000;      // 10MHz: Evita travamento e ruído na imagem
  config.pixel_format = PIXFORMAT_JPEG; 
  config.grab_mode = CAMERA_GRAB_LATEST; // CRUCIAL: Evita o erro "FB-OVF" jogando fora frames velhos

  // Verificação Inteligente de Memória
  if(psramFound()){
    Serial.println("PSRAM Detectada! Configurando modo Performance.");
    // Com PSRAM, podemos arriscar resoluções maiores (VGA ou SVGA)
    config.frame_size = FRAMESIZE_VGA; // 640x480 (Bom equilíbrio)
    config.fb_location = CAMERA_FB_IN_PSRAM;
    config.jpeg_quality = 12; // Menor número = melhor qualidade (10-63)
    config.fb_count = 2;
  } else {
    Serial.println("AVISO: PSRAM não encontrada. Configurando modo Seguro (DRAM).");
    // Sem PSRAM, usamos pouca memória para não travar
    config.frame_size = FRAMESIZE_QVGA; // 320x240
    config.fb_location = CAMERA_FB_IN_DRAM;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // Inicializa a câmera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("ERRO CRÍTICO: Câmera falhou (0x%x). Verifique:\n1. Cabo Flat\n2. Config PSRAM na IDE\n", err);
    return;
  }

  // Ajustes do Sensor
  sensor_t * s = esp_camera_sensor_get();
  // s->set_vflip(s, 1);   // Descomente se a imagem estiver de cabeça para baixo
  // s->set_hmirror(s, 1); // Descomente se estiver espelhada

  // Conexão WiFi
  WiFi.begin(ssid, password);
  WiFi.setSleep(false); // Melhora a velocidade de resposta do WiFi e evita quedas no stream
  
  Serial.print("Conectando WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi Conectado!");
  
  Serial.println("--------------------------------------------------");
  Serial.print("ACESSE O STREAM EM: http://");
  Serial.println(WiFi.localIP());
  Serial.println("--------------------------------------------------");
  
  startCameraServer();
}

void loop() {
  // O servidor roda em background via interrupções e tasks do FreeRTOS.
  // O loop fica livre ou com um delay longo para economizar CPU.
  delay(10000);
}

Passo 3: Configuração da IDE (Não ignore isso!)

Para processar vídeo, a EchoVision precisa “respirar”. Se você não ativar a memória estendida (PSRAM), o código até compila, mas o esp_camera_init vai falhar ou a imagem ficará travando.

Configure exatamente assim em Ferramentas:

  • Board: ESP32S3 Dev Module
  • USB CDC On Boot: Enabled (Para ver o Serial)
  • Flash Size: 16MB (128Mb)
  • PSRAM: OPI PSRAM (O item mais importante!)
  • Partition Scheme: Default 4MB with Spiffs (Ou o esquema de 8MB se você já configurou para o tutorial de áudio).

Passo 4: Hora da Ação

  1. Conecte a EchoVision via USB-C.
  2. Clique em Upload (Seta para direita).
  3. Após o upload (“Hard Resetting via RTS pin…”), abra o Monitor Serial (Ctrl+Shift+M).
  4. Certifique-se que o Baud Rate está em 115200.
  5. Se tudo der certo, você verá a mensagem: ACESSE O STREAM EM: http://192.168.x.x

Copie esse IP, cole no navegador do seu celular (estando na mesma rede Wi-Fi) e clique em “Start Stream”.

Dica de Mestre: A imagem está escura ou com cores estranhas? No menu da interface web, desça até as configurações e ative AEC (Controle Automático de Exposição) e AWB (Balanço de Branco). A EchoVision ajustará a imagem automaticamente para o ambiente.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *