Kit Robô Avançado 4wd Camera Tutoriais Esp32 Wifi App RB2056 AD174 – Curso Completo

Introdução
O Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 (RB2056) da RoboBuilders é uma plataforma robótica educacional de alto nível tecnológico, desenvolvida para explorar sistemas embarcados de tempo real, controle dinâmico de tração e transmissão de vídeo sem fio. O núcleo de processamento do robô é centralizado no poderoso módulo ESP32-CAM, composto por um microcontrolador de arquitetura de 32 bits com núcleo duplo Xtensa LX6 operando a frequências de até , conectividade de rede sem fio Wi-Fi 802.11 b/g/n, Bluetooth v4.2 BR/EDR e BLE (Bluetooth Low Energy), além de uma memória PSRAM (Pseudo Static Random Access Memory) externa de 4 MB dedicada ao buffer de captura e codificação de imagens. A plataforma embarca um sensor óptico CMOS de 2 megapixels OV2640 acoplado a uma antena externa omnidirecional de 2,4 GHz com pigtail coaxial IPEX para alcance estendido de rádiofrequência, um robusto estágio de acionamento de potência em ponte H dupla L298N, tração integral distribuída em quatro motores DC com caixa de redução metálica/plástica (motores TT de relação 1:48), e um chassi estrutural duplo em acrílico usinado com rodas de borracha de alta aderência. O sistema implementa conectividade local em modo de ponto de acesso autônomo (SoftAP — Software-enabled Access Point), permitindo tanto a transmissão contínua de fluxo de vídeo em formato MJPEG (Motion JPEG) sobre requisições HTTP (Hypertext Transfer Protocol) em navegadores web quanto o controle remoto bidirecional de baixa latência através de soquetes de rede TCP (Transmission Control Protocol) e do aplicativo móvel proprietário KUONGSHUN.
Este material didático foi elaborado para atuar como uma referência definitiva de engenharia para estudantes de robótica, desenvolvedores de firmware, engenheiros eletrônicos e entusiastas da automação. O curso conduz o projetista por uma jornada técnica estruturada em módulos rigorosamente espelhados na documentação e engenharia oficial do fabricante Kuongshun: iniciando pelo reconhecimento volumétrico e montagem mecânica do chassi passo a passo; avançando para a configuração criteriosa do ambiente na Arduino IDE (Integrated Development Environment), instalação dos drivers do conversor USB-Serial CH340 e fixação da versão de suporte da placa de silício no pacote ESP32 2.0.12; aprofundando-se na cinemática de tração diferencial e nos sketches de locomoção básica autônoma; e culminando na implementação dos servidores de streaming e teleoperação via interface Web responsiva e aplicativo Android embarcado.
O que você vai aprender:
- Compreender a arquitetura interna do SoC ESP32-CAM, seu barramento DVP com a câmera OV2640 e a alocação de quadros de vídeo na memória PSRAM externa;
- Montar passo a passo a estrutura mecânica do chassi 4WD, suportes dos motores TT, módulo driver L298N, suporte da câmera e antena de alto ganho com suas respectivas ferragens;
- Dimensionar o circuito de alimentação e barramento elétrico composto por duas células de íons de lítio 18650, chave geral e proteção contra afundamento de tensão (brownout reset);
- Configurar o ecossistema de desenvolvimento na Arduino IDE, instalando o driver USB-Serial CH340 e fixando de forma estável o pacote de placas ESP32 na versão pinada 2.0.12;
- Dominar a cinemática de tração 4WD com acionamento diferencial (skid-steer), modulando largura de pulsos (PWM) e sentido de giro dos quatro motores através do driver L298N;
- Analisar e compilar códigos-fonte linha a linha para marcha à frente, marcha à ré, conversões e aceleração suave via loops de controle analógico;
- Configurar a rede local sem fio em modo SoftAP (Access Point) com SSID broadcast
KUONGSHUN-AD174e autenticação WPA2-PSK;- Desenvolver um servidor HTTP embarcado multitarefa na biblioteca
esp_http_serverpara streaming contínuo de vídeo MJPEG via chunked transfer encoding;- Estabelecer um servidor TCP na porta 100 para decodificação de tramas binárias de telemetria e pilotagem remota em tempo real;
- Instalar o aplicativo oficial KUONGSHUN.apk no smartphone Android através de link direto, configurando permissões de rádio e operando o robô com joystick virtual;
- Diagnosticar falhas sistêmicas de hardware e firmware através de um guia completo de troubleshooting, solucionando perda de pacotes, aquecimento e inversão de eixos.
Material utilizado: Kit Robô Avançado 4wd Camera Tutoriais Esp32 Wifi App RB2056 AD174.
Visão Geral do Kit e Arquitetura de Hardware
A engenharia do Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 (RB2056) combina de maneira otimizada o poder computacional de um microcontrolador dual-core moderno com a robustez eletromecânica clássica dos acionamentos por ponte H. Diferente de projetos tradicionais de robótica educacional que demandam duas placas físicas separadas (como um microcontrolador Arduino Uno acoplado a um módulo ESP32 externo por cabos seriais adicionais), o kit AD174 simplifica drasticamente a topologia física ao concentrar toda a inteligência do sistema — inteligência de máquina, roteamento de rede Wi-Fi, servidor web, servidor TCP de telemetria, streaming de vídeo e geração de sinais de temporização PWM de alta frequência — diretamente dentro de uma única placa controladora ESP32-CAM, montada sobre uma placa de expansão e gravação USB Tipo-C com conversor CH340.
O Módulo Microcontrolador ESP32-CAM e a Câmera OV2640
O coração do robô é o consagrado módulo ESP32-CAM, fabricado pela AI-Thinker e baseado no silício ESP32-D0WDQ6 da Espressif Systems. Esse microchip integra dois núcleos de processamento Xtensa 32-bit LX6 com clock configurável entre e , entregando até 600 DMIPS de capacidade de cálculo. Em seu encapsulamento interno, o microcontrolador conta com de memória SRAM (Static Random Access Memory) e de memória ROM para inicialização do bootloader.
Entretanto, aplicações de visão computacional e streaming de vídeo de alta resolução impõem uma demanda de armazenamento que supera com folga a memória interna nativa dos microcontroladores padrão. Um único quadro (frame) de imagem capturado na resolução SVGA ( pixels) em formato bruto RGB565 consumiria:
Este valor excede a totalidade da SRAM do microcontrolador. Por essa razão, a placa ESP32-CAM integra em seu circuito impresso um chip de memória externa PSRAM de (), comunicando-se com o processador através de um barramento QSPI (Quad Serial Peripheral Interface) de alta velocidade a . O subsistema de software da Espressif ativa e mapeia automaticamente essa memória no espaço de endereçamento do heap do sistema através do compilador e das diretivas do firmware, permitindo que a biblioteca esp_camera.h aloque múltiplos buffers de recepção de imagem (frame buffers) diretamente na PSRAM com a chamada CAMERA_FB_IN_PSRAM.
O sensor óptico conectado ao módulo é o OmniVision OV2640, um sensor CMOS de alta sensibilidade e baixo consumo de energia que conta com um motor de compressão JPEG embutido no próprio silício. Isso significa que a conversão dos dados brutos dos fotodiodos para o fluxo binário comprimido .jpg é realizada diretamente pelo hardware do sensor óptico antes da transferência para o ESP32. A interface física entre a câmera OV2640 e a placa ESP32-CAM é constituída por um barramento paralelo DVP (Digital Video Port) de 8 linhas de dados ( a ), três linhas de sincronismo e temporização de varredura (, e ), uma linha de sinal de clock mestre gerada pelo ESP32 (, configurada a ), linhas de energia e reset (, ), e o barramento serial de configuração de dois fios SCCB (Serial Camera Control Bus, protocolo compatível com ) composto pelos pinos (dados) e (clock).
A tabela abaixo descreve detalhadamente o pinout elétrico de interligação entre o sensor OV2640 e os terminais GPIO do ESP32-CAM:
| Sinal da Câmera OV2640 | Função do Barramento | Pino GPIO no ESP32-CAM | Características Elétricas e Temporização |
|---|---|---|---|
| PWDN | Power Down (Ativação em nível alto) | GPIO 32 | Controla o estado de repouso de baixo consumo da câmera |
| RESET | Reset por hardware | -1 (Não conectado) | O reset é gerenciado por software através do barramento SCCB |
| XCLK | Master Clock de entrada do sensor | GPIO 0 | Sinal de clock gerado pelo canal LEDC0 a |
| SIOD | Linha de Dados de Configuração SCCB | GPIO 26 | Comunicação serial tipo para ajuste de registradores |
| SIOC | Linha de Clock de Configuração SCCB | GPIO 27 | Clock de sincronismo serial SCCB (frequência típica de ) |
| Y9 | Bit de Dados de Vídeo 7 (MSB) | GPIO 35 | Pino de entrada digital DVP (canal de leitura rápida de pixels) |
| Y8 | Bit de Dados de Vídeo 6 | GPIO 34 | Pino de entrada digital DVP |
| Y7 | Bit de Dados de Vídeo 5 | GPIO 39 | Pino de entrada digital DVP |
| Y6 | Bit de Dados de Vídeo 4 | GPIO 36 | Pino de entrada digital DVP |
| Y5 | Bit de Dados de Vídeo 3 | GPIO 21 | Pino de entrada digital DVP |
| Y4 | Bit de Dados de Vídeo 2 | GPIO 19 | Pino de entrada digital DVP |
| Y3 | Bit de Dados de Vídeo 1 | GPIO 18 | Pino de entrada digital DVP |
| Y2 | Bit de Dados de Vídeo 0 (LSB) | GPIO 5 | Pino de entrada digital DVP |
| VSYNC | Sincronismo Vertical de Quadro | GPIO 25 | Pulso que demarca o início e o término de um quadro completo de imagem |
| HREF | Referência Horizontal de Linha | GPIO 23 | Sinal que valida a transmissão dos bytes de pixels de uma linha ativa |
| PCLK | Pixel Clock de Saída do Sensor | GPIO 22 | Clock síncrono com cada byte de pixel disponibilizado em |
| LED Flash | Iluminação auxiliar de alta intensidade | GPIO 4 | Transistor de chaveamento de corrente conectado a LED branco ultra-brilhante |
⚠️ Atenção aos pinos compartilhados: Na placa ESP32-CAM, o pino GPIO 4 aciona diretamente o LED flash de alta potência. Devido à sua intensidade e consumo de corrente (podendo atingir mais de em plena luminosidade), o controle de brilho deve ser executado obrigatoriamente através de modulação por largura de pulso (PWM) configurada no periférico de hardware LEDC (LED Control) do ESP32, evitando sobrecarga térmica na placa. Além disso, os pinos GPIO 13, 14, 15, 2 e 12 são estrategicamente utilizados para o controle do driver L298N, exigindo atenção à ordem de inicialização do periférico de rádio Wi-Fi para que não ocorram acionamentos involuntários dos motores durante o boot.
O Driver de Potência de Ponte H Dupla L298N
Para controlar o sentido de rotação e a velocidade angular dos quatro motores de corrente contínua, o robô utiliza o consagrado circuito integrado L298N, montado em um módulo de potência com dissipador de calor de alumínio anodizado aletado. O L298N é um circuito monolítico de 15 pinos encapsulado no padrão Multiwatt15, composto internamente por duas pontes H completas construídas com transistores bipolares de junção (TBJ) em configuração Darlington de alta corrente.
Cada meia-ponte H do L298N suporta uma tensão de alimentação de carga () de até e corrente contínua de até por canal, com picos tolerados de até para transientes de partida de motores. O módulo integra internamente oito diodos de supressão de surtos de comutação indutiva (flyback diodes), essenciais para dissipar com segurança a força contraeletromotriz gerada pela indutância das bobinas dos motores quando a corrente é repentinamente interrompida pelo chaveamento dos transistores:
Sem esses diodos de recirculação rápida, picos de alta tensão reversa poderiam perfurar a junção semicondutora dos transistores do L298N e induzir ruído de alta frequência nas trilhas de alimentação lógica do ESP32-CAM.
O módulo L298N conta ainda com um regulador de tensão linear integrado LM7805 de . Um jumper removível localizado atrás do borne de alimentação de três vias seleciona o modo de operação do regulador:
- Com o jumper inserido: O regulador LM7805 interno reduz a tensão das baterias ( presentes no borne de entrada ) para fornecer estáveis no borne , alimentando os circuitos lógicos internos do próprio L298N e servindo como fonte de alimentação primária para a placa ESP32-CAM.
- Com o jumper removido: Obrigatório caso a tensão de alimentação dos motores ultrapasse (para evitar queima do regulador por dissipação térmica excessiva), exigindo uma fonte externa de no borne correspondente. No kit AD174, alimentado com duas baterias 18650 ( nominais), o jumper deve permanecer obrigatoriamente inserido.
Os quatro motores TT do chassi são agrupados em pares elétricos paralelos: os dois motores do lado esquerdo são conectados em conjunto aos bornes OUT1 e OUT2 (Canal A), enquanto os dois motores do lado direito são conectados em conjunto aos bornes OUT3 e OUT4 (Canal B). A velocidade de rotação de cada lado é controlada pelos pinos de habilitação ENA e ENB, enquanto o sentido de rotação é determinado pelas entradas digitais IN1, IN2, IN3 e IN4.
A tabela abaixo apresenta a matriz completa de sinais de controle entre o microcontrolador ESP32-CAM e os bornes de potência do driver L298N:
| Pino no ESP32-CAM | Entrada no Driver L298N | Mapeamento no Firmware | Função Técnica de Controle | Nível Lógico e Operação Resultante |
|---|---|---|---|---|
| GPIO 2 | ENA (Enable A) | ENA | Habilita e controla a velocidade dos motores do lado Esquerdo | PWM () via canal LEDC2 do ESP32 |
| GPIO 12 | ENB (Enable B) | ENB | Habilita e controla a velocidade dos motores do lado Direito | PWM () via canal LEDC12 do ESP32 |
| GPIO 33 | IN1 | gpLb (Left Backward) | Comanda a rotação reversa dos motores esquerdos | Nível lógico ALTO (HIGH) para ré do lado esquerdo |
| GPIO 15 | IN2 | gpLf (Left Forward) | Comanda a rotação frontal dos motores esquerdos | Nível lógico ALTO (HIGH) para avanço do lado esquerdo |
| GPIO 14 | IN3 | gpRb (Right Backward) | Comanda a rotação reversa dos motores direitos | Nível lógico ALTO (HIGH) para ré do lado direito |
| GPIO 13 | IN4 | gpRf (Right Forward) | Comanda a rotação frontal dos motores direitos | Nível lógico ALTO (HIGH) para avanço do lado direito |
Tabela-Mestre de Especificações Técnicas do Kit AD174
| Parâmetro Técnico | Especificação e Faixa Nominal de Operação |
|---|---|
| Modelo Comercial e SKU | Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 (Código RoboBuilders: RB2056) |
| Microcontrolador Central | ESP32-CAM (SoC ESP32-D0WDQ6, Dual-Core 32-bit Xtensa LX6 @ ) |
| Memória Volátil e Não-Volátil | SRAM interna, PSRAM externa QSPI, Flash SPI |
| Sensor de Imagem | OmniVision OV2640 (CMOS UXGA 2 MP, lente , campo de visão ) |
| Formatos e Resoluções de Vídeo | JPEG nativo, resoluções QVGA (), VGA () e SVGA () |
| Conectividade Sem Fio | Wi-Fi 802.11 b/g/n () com antena externa omnidirecional de e conector IPEX/SMA |
| Modo de Operação de Rádio | Ponto de Acesso Autônomo (SoftAP) com IP fixo padrão 192.168.4.1, canal 5 e DHCP interno |
| Estágio de Potência dos Motores | Ponte H Dupla L298N (suporta até contínuos e de pico por canal, dissipador aletado) |
| Atuadores Eletromecânicos | 4 motores de corrente contínua com caixa de redução (TT Motor, redução 1:48, rotação ) |
| Chassi Estrutural | Acrílico usinado a laser de alta transparência e de espessura, montagem em dois pavimentos |
| Rodas e Tração | 4 rodas de plástico ABS de de diâmetro com pneus de borracha sintética frisada |
| Alimentação Elétrica | 2 baterias recarregáveis de íons de lítio formato 18650 ( nominais, plena carga) |
| Interface de Programação | Porta USB Tipo-C integrada na placa base com conversor serial CH340 de alta velocidade |
| Aplicativo de Controle Remoto | Aplicativo proprietário KUONGSHUN (disponível em formato APK para Android e App Store para iOS) |
Inventário Detalhado do Kit (Packing List Oficial)
Antes de iniciar a montagem física do robô, realize a conferência minuciosa de todos os componentes fornecidos na embalagem oficial do kit Kuongshun AD174:
- Plataforma Estrutural Acrílica:
- 1x Chassi inferior de acrílico transparente de com furação padrão para fixação dos suportes dos motores TT, colunas espaçadoras e módulo driver L298N;
- 1x Chassi intermediário de suporte de componentes com recortes de ventilação e aberturas para passagem de cabos;
- 2x Peças acrílicas para montagem do suporte angulado da câmera ESP32-CAM e antena WiFi.
- Eletrônica de Controle e Sensores:
- 1x Módulo microcontrolador ESP32-CAM com câmera OV2640 instalada no conector FPC de 24 pinos;
- 1x Placa base de desenvolvimento e expansão para ESP32-CAM com conector USB Tipo-C e conversor USB-Serial CH340;
- 1x Módulo driver de motor ponte H dupla L298N com dissipador de calor e bornes para conexão dos motores e bateria;
- 1x Antena externa de 2,4 GHz com conector SMA fêmea e cabo pigtail coaxial com terminal IPEX miniatura.
- Atuadores e Conjunto de Rodagem:
- 4x Motores DC amarelos com caixa de redução plástica (TT Motors) de eixo duplo e relação de transmissão 1:48;
- 4x Suportes metálicos usinados em liga de alumínio anodizado preto para fixação dos motores TT ao chassi;
- 4x Rodas de plástico injetado de com pneus de borracha de alta tração e encaixe com chaveta nos eixos dos motores.
- Sistema de Alimentação e Fiação:
- 1x Suporte plástico para 2 baterias de lítio padrão 18650 com chave gangorra liga/desliga de dois polos e cabos pré-estanhados;
- 1x Conjunto completo de cabos jumpers coloridos com terminais macho-fêmea e fêmea-fêmea para interligação dos sinais de controle;
- 1x Cabo de dados e alimentação padrão USB Tipo-A para USB Tipo-C.
- Ferragens de Fixação e Ferramental:
- 10x Espaçadores sextavados de latão fêmea-fêmea padrão M3 para separação dos andares do chassi;
- 18x Parafusos Philips de cabeça escareada M3 em aço niquelado;
- 8x Parafusos Philips longos de cabeça redonda M3 para travamento dos suportes dos motores TT;
- 9x Porcas sextavadas métricas padrão M3;
- 4x Parafusos Philips de cabeça redonda M2 para fixação da placa ESP32-CAM;
- 4x Porcas sextavadas métricas padrão M2;
- 4x Parafusos Philips autoatarraxantes de cabeça redonda M2 para travamento central das rodas nos eixos dos motores;
- 1x Chave de fenda Philips com cabo ergonômico para montagem integral do kit.
Somatória Geral: Mais de 60 elementos físicos perfeitamente balanceados compõem o kit robótico, formando um sistema mecatrônico completo, rígido e de altíssima confiabilidade operacional.
Guia de Montagem Mecânica (Assembly Guide)
A montagem estrutural do Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 constitui o alicerce fundamental para a estabilidade dinâmica, precisão de navegação e integridade dos sensores de visão. Um chassi montado com folgas mecânicas ou motores desalinhados induz forças parasitas de deriva lateral, sobrecarga nos enrolamentos e trepidações excessivas no fluxo de vídeo da câmera OV2640.
Fundamentos da Cinemática Diferencial e Tração 4WD
O robô opera através de um arranjo cinemático de tração diferencial por deslizamento (skid-steer mobile robot), no qual não há um mecanismo de esterçamento convencional com articulações de direção (geometria de Ackermann). Em vez disso, o controle angular e a rotação do veículo são gerados exclusivamente pela diferença relativa entre as velocidades angulares das rodas do lado esquerdo () e do lado direito ().
Considerando que as quatro rodas possuem raio nominal idêntico () e que a bitola transversal do robô (distância entre os centros das rodas esquerdas e direitas) é denotada por (), a velocidade linear longitudinal desenvolvida por cada lado do chassi é dada por:
A velocidade linear resultante de translação do centro de massa do robô () corresponde à média aritmética simples das velocidades dos dois lados:
A velocidade angular de guinada do robô em torno de seu próprio eixo vertical (), responsável pela mudança de orientação azimutal, é obtida dividindo a diferença das velocidades tangenciais pela largura da bitola:
A trajetória curvilínea percorrida pelo chassi descreve um arco circular em torno de um Centro Instantâneo de Rotação (CIR). O raio desse círculo de manobra (), medido a partir do ponto central do chassi, é deduzido pela relação entre a velocidade linear de translação e a velocidade angular de rotação:
Analisando a equação do raio de curvatura, evidenciam-se três condições fundamentais de controle:
- Translação Retilínea Pura (): A diferença , resultando em velocidade angular nula () e raio de curvatura infinito (). O robô move-se em linha reta perfeitamente alinhada.
- Curva Suave em Movimento ( e ambos positivos): O robô translada para frente ao mesmo tempo em que gira em torno de um CIR externo ao chassi (), executando curvas suaves com velocidade regulada por PWM.
- Rotação no Próprio Eixo ou Giro em Pião (): As rodas de um lado giram para frente com velocidade , enquanto as rodas do lado oposto giram para trás com velocidade . Substituindo na equação:
Nessa condição extrema, a velocidade linear de translação é estritamente zero e o raio de curvatura é nulo: o chassi gira estacionariamente sobre o centro geométrico de sua base, alcançando a taxa máxima de rotação angular para evasão de obstáculos em espaços confinados.
Para que a rotação estacionária ocorra com eficiência, o torque produzido pelos motores deve superar a força de atrito lateral gerada pelo arraste dos pneus sobre o solo. A força de atrito dinâmico lateral desenvolvida por cada pneu é regida pelo coeficiente de atrito cinético e pela fração da força normal sustentada pela roda:
onde representa a massa total do robô montado e é a aceleração da gravidade. Assim, a distribuição equilibrada de massa entre a dianteira e a traseira do chassi é essencial para equalizar as cargas normais nos quatro pontos de contato.
A montagem física do kit Kuongshun AD174 é realizada em 8 passos lógicos numerados e sequenciais, ilustrados pelas imagens extraídas diretamente da engenharia do fabricante.
Passo 0 – Distinção de Orientação e Faces do Chassi Acrílico Inferior
Antes de aplicar qualquer parafuso, remova a película protetora de papel kraft marrom de todas as placas de acrílico para expor as superfícies transparentes límpidas. Em seguida, identifique a placa acrílica do chassi inferior e determine sua orientação correta no plano de trabalho.
A face superior e a extremidade dianteira da base acrílica são diferenciadas pela distribuição métrica das furações circulares de fixação: observe a distância entre o par de furos localizado na região frontal demarcada pelas setas do diagrama técnico. A distância entre os furos é mais ampla na porção superior e mais estreita na porção inferior. A extremidade com furação mais larga identifica indubitavelmente a parte frontal do robô.


💡 Dica de bancada: Mantenha a placa com a extremidade frontal voltada para a parte superior de sua mesa de montagem. Marque sutilmente a face superior com uma etiqueta adesiva removível para assegurar que nenhum componente seja parafusado na face invertida.
Passo 1 – Fixação dos Espaçadores Sextavados de Latão M3
O chassi é sustentado por 10 colunas espaçadoras sextavadas de latão com rosca dupla fêmea padrão M3 . Essas colunas elevam o pavimento superior, protegem os componentes eletrônicos contra impactos e servem como barreira estrutural para os cabos de potência.
Posicione os parafusos Philips de cabeça escareada M3 inseridos a partir da face inferior (face de baixo) do chassi acrílico nos 10 orifícios de ancoragem designados. Na face superior, rosqueie manualmente cada espaçador de latão de e efetue o aperto final moderado com a chave de fenda. A cabeça escareada do parafuso deve ficar perfeitamente embutida na chanfradura do acrílico para que a face inferior permaneça lisa.

⚠️ Atenção mecânica: O aperto dos parafusos em peças acrílicas deve ser firme, porém suave. O acrílico usinado possui alta rigidez, mas é susceptível a trincas radiais por concentração de tensão se for submetido a torque angular excessivo.
Passo 2 – Montagem dos Motores DC de Tração (TT Motors)
A tração do robô utiliza 4 motores DC com caixa de redução plástica integrados (motores amarelos padrão TT). Cada motor é fixado por um suporte metálico rígido em liga de alumínio em formato de L.
Subpasso 2.1 – Fixação dos Suportes Metálicos nos Motores TT
Pegue cada motor TT e observe suas duas faces laterais: uma das faces possui um ressalto plástico cilíndrico saliente (bump), enquanto a face oposta é plana com os pontos de solda dos fios expostos. O suporte metálico deve ser posicionado obrigatoriamente na face plana oposta ao ressalto cilíndrico.
Insira dois parafusos Philips longos de cabeça redonda M3 atravessando o suporte de alumínio e o corpo plástico do motor. Na face oposta, rosqueie duas porcas sextavadas métricas M3 e aperte o conjunto. Repita o procedimento de maneira idêntica para os quatro motores.

Subpasso 2.2 – Fixação dos Conjuntos de Motor no Chassi Acrílico
Com os quatro motores devidamente equipados com seus suportes metálicos, monte-os nas quatro extremidades laterais do chassi inferior.
Atente-se à orientação espacial dos motores: os ressaltos plásticos externos dos motores devem apontar para fora do chassi (lado em que o eixo do motor se projeta para receber as rodas), enquanto as soldas e terminais elétricos dos fios devem ficar voltados para a região interna central do chassi, protegidos de atritos laterais. Fixe a base de cada suporte metálico ao acrílico utilizando dois parafusos de cabeça escareada M3 inseridos por baixo do chassi.

Passo 3 – Instalação do Módulo Driver de Motores L298N
O módulo driver de ponte H L298N é o componente eletrônico de maior peso e volume térmico do pavimento inferior. Ele deve ser posicionado centralizadamente sobre a base acrílica para otimizar o centro de gravidade e reduzir o comprimento dos cabos que vão aos motores.
Posicione o módulo L298N sobre os quatro furos de montagem correspondentes na placa acrílica. Alinhe a placa de modo que os bornes de potência de saída de dois terminais fiquem alinhados com as laterais do veículo: os bornes OUT1/OUT2 apontando para o par de motores esquerdos e os bornes OUT3/OUT4 apontando para o par de motores direitos. Fixe a placa de circuito impresso utilizando quatro parafusos Philips de cabeça escareada M3 inseridos pela parte inferior do chassi.

Passo 4 – Instalação do Suporte de Baterias 18650 com Chave Geral
O sistema é alimentado por um suporte plástico moldado que acomoda duas baterias recarregáveis cilíndricas padrão 18650 ligadas em série, fornecendo uma tensão nominal de ( com carga máxima a por célula).
Posicione o suporte de baterias na região traseira do chassi, garantindo que o interruptor de alavanca/gangorra liga/desliga permaneça voltado para a face posterior externa do robô, facilitando o acionamento e corte de emergência da alimentação pelo operador sem obstruções mecânicas. Fixe o suporte de baterias à base acrílica através de quatro parafusos Philips de cabeça escareada M3 .

Passo 5 – Montagem e Instalação do Suporte da Câmera ESP32-CAM
A câmera OV2640 deve ser sustentada em uma elevação angular ideal de visão frontal para fornecer horizonte visual limpo e sem oclusões no streaming de vídeo. O suporte é confeccionado em acrílico cortado a laser e parafusos de precisão.
Subpasso 5.1 – Junção das Partes da Torre de Suporte
Pegue as duas peças acrílicas que compõem a torre articulada de sustentação da câmera. Encaixe uma porca sextavada M3 no alojamento sextavado usinado da peça base e segure-a com a ponta do dedo. Em seguida, sobreponha a segunda peça acrílica e rosqueie um parafuso de cabeça escareada M3 até fixar o suporte em ângulo rígido.

Subpasso 5.2 – Fixação da Placa ESP32-CAM no Suporte Acrílico
Com a torre de suporte montada, alinhe os quatro pequenos furos de fixação de canto da placa controladora ESP32-CAM com a furação da torre plástica. Utilize quatro parafusos de precisão de cabeça redonda M2 e quatro porcas sextavadas métricas M2.
Certifique-se de que a lente cilíndrica da câmera OV2640 permaneça centralizada na abertura e voltada para a frente, e que o cabo flat FPC da câmera não sofra torções acentuadas contra a borda do circuito impresso.

Subpasso 5.3 – Acoplamento da Torre de Câmera ao Chassi Intermediário
Apoie o conjunto completo montado da câmera sobre a placa acrílica intermediária do robô e fixe-o firmemente utilizando dois parafusos de cabeça escareada M3 . O conjunto deve ficar posicionado na extremidade frontal, apontando para a dianteira do veículo.

Passo 6 – Instalação da Antena Externa Wi-Fi 2.4 GHz e Conector SMA
Para viabilizar uma transmissão de vídeo em alta definição com taxa de quadros estável sem perdas de pacotes ou latência induzida por reflexões eletromagnéticas do chassi, o robô utiliza uma antena externa omnidirecional de 2,4 GHz conectada via cabo pigtail coaxial de baixa perda.
Passe o cabo coaxial fino através do orifício guia usinado na placa acrílica superior. Conecte com extrema delicadeza o conector em miniatura IPEX macho no soquete receptor fêmea de rádiofrequência localizado na superfície da placa ESP32-CAM (pressione levemente até ouvir um estalo sutil de travamento mecânico). Em seguida, monte o conector rosqueável SMA fêmea na furação acrílica traseira, respeitando rigorosamente a ordem mecânica dos anéis de pressão: primeiro a arruela dentada estrela, seguida da porca sextavada de latão dourada. Rosqueie a antena flexível articulada externamente.


Passo 7 – Instalação das 4 Rodas de Tração de Borracha
As quatro rodas são injetadas em plástico ABS reforçado com anéis externos de borracha sintética com sulcos transversais que maximizam o atrito estático com pisos lisos ou carpetes.
O cubo de cada roda possui uma cavidade com duplo chanfro em D, projetada para se acoplar com precisão cirúrgica aos eixos chatos dos motores TT. Alinhe a chaveta de cada roda com o chanfro do eixo do respectivo motor e empurre a roda firmemente até o batente. Para evitar desencaixes durante arrancadas ou reversões bruscas de torque, introduza um parafuso Philips autoatarraxante de cabeça redonda M2 no centro do cubo de cada roda e aperte-o até encostar na rosca plástica do eixo do motor.

Passo 8 – Esquema e Guia de Fiação Elétrica Completo (Wiring Guide)
Com todos os elementos mecânicos firmemente aparafusados e o segundo andar acrílico posicionado sobre os espaçadores de latão, execute a interligação elétrica do sistema de potência, do circuito de alimentação e dos barramentos lógicos de comando.

Siga estritamente a tabela de interconexão elétrica para evitar curto-circuitos ou polarizações invertidas:
| Origem do Sinal / Terminal | Destino Físico no Circuito | Função Elétrica e Descrição |
|---|---|---|
| Cabo Vermelho (+Baterias 18650) | Borne VMS (12V) do L298N | Entrada de tensão não regulada das baterias () via chave geral |
| Cabo Preto (-Baterias 18650) | Borne GND do L298N | Referência de terra comum de potência |
| Borne +5V do L298N | Pino 5V da placa base ESP32-CAM | Saída regulada do LM7805 que alimenta o ESP32 |
| Borne GND do L298N | Pino GND da placa base ESP32-CAM | Referência de terra comum lógica (essencial para retorno de sinais) |
| Motores Esquerdos (Fios Vermelho/Preto) | Bornes OUT1 e OUT2 do L298N | Alimentação dos dois motores de tração do lado esquerdo (em paralelo) |
| Motores Direitos (Fios Vermelho/Preto) | Bornes OUT3 e OUT4 do L298N | Alimentação dos dois motores de tração do lado direito (em paralelo) |
| Pino GPIO 2 do ESP32-CAM | Borne ENA do L298N | Sinal PWM de controle de velocidade do lado esquerdo (remover jumper ENA) |
| Pino GPIO 12 do ESP32-CAM | Borne ENB do L298N | Sinal PWM de controle de velocidade do lado direito (remover jumper ENB) |
| Pino GPIO 33 do ESP32-CAM | Borne IN1 do L298N | Sinal de sentido de rotação ré da esteira esquerda (gpLb) |
| Pino GPIO 15 do ESP32-CAM | Borne IN2 do L298N | Sinal de sentido de rotação avanço da esteira esquerda (gpLf) |
| Pino GPIO 14 do ESP32-CAM | Borne IN3 do L298N | Sinal de sentido de rotação ré da esteira direita (gpRb) |
| Pino GPIO 13 do ESP32-CAM | Borne IN4 do L298N | Sinal de sentido de rotação avanço da esteira direita (gpRf) |
⚠️ Aviso de segurança elétrica: NUNCA conecte o cabo USB Tipo-C no computador com o interruptor das baterias ligado se houver dúvida sobre as conexões de terra (GND) e alimentação. Sempre revise a integridade dos cabos antes de fechar o circuito.
Preparação do Ambiente de Programação (Programming Preparation)
Para compilar e transferir os firmwares do robô para o módulo ESP32-CAM, é indispensável configurar com rigor o ecossistema de desenvolvimento da Arduino IDE, o driver de comunicação serial USB e o pacote de suporte às placas ESP32. Pequenas divergências de versão nos pacotes de suporte de placas podem impedir a compilação ou gerar falhas catastróficas em tempo de execução, como falhas no buffer de captura da câmera OV2640 ou travamentos no temporizador PWM dos motores.
Instalação da Arduino IDE e do Driver Serial CH340
A plataforma Arduino IDE é o ambiente de desenvolvimento integrado de código aberto utilizado para escrever, compilar e descarregar código nos microcontroladores. O kit é plenamente compatível tanto com a versão clássica estável (Arduino IDE 1.8.x) quanto com a versão moderna (Arduino IDE 2.x).


Durante o processo de instalação no Windows, selecione todas as opções de componentes padrão (incluindo o driver USB nativo do Arduino) e prossiga clicando sucessivamente em Next e Install. Quando a barra de progresso for concluída, encerre o instalador.


Instalação do Driver USB-Serial CH340 no Windows
A placa de desenvolvimento base do ESP32-CAM utiliza o chip conversor de protocolo CH340 (fabricado pela WCH - QinHeng Electronics) para intermediar os sinais entre a porta USB do computador e os pinos de transmissão/recepção assíncrona (UART0: GPIO 1 TX e GPIO 3 RX) do microcontrolador ESP32.
Se ao conectar a placa pela primeira vez através do cabo USB Tipo-C o Windows não atribuir uma porta de comunicação serial válida (exibindo o dispositivo no Gerenciador de Dispositivos com um ponto de exclamação amarelo ou rotulado como “Dispositivo Desconhecido”), instale o driver oficial:
- Acesse os arquivos do kit na pasta
2_Programming_Preparation/1. Installation of Arduino IDE and CH340 driver/CH340 Serial Driver/CH340 Driver File-Windows/USB_Drive_CH341_3_1; - Execute o arquivo
SETUP.EXEcomo Administrador; - Na janela do assistente de instalação do driver, clique no botão INSTALL;
- Aguarde a mensagem de confirmação “Driver install success!” e reinicie o computador caso solicitado.


Para confirmar o reconhecimento do hardware, conecte a placa ESP32-CAM via cabo USB Tipo-C, abra o Gerenciador de Dispositivos do Windows (devmgmt.msc) e expanda a seção Portas (COM e LPT). Uma nova porta serial será exibida com o nome USB-SERIAL CH340 (COMxx), onde xx representa o número atribuído pelo sistema operacional (por exemplo, COM3, COM5 ou COM12).

Instalação do Driver CH340 no macOS
Para usuários do sistema Apple macOS, acesse a pasta CH340 Driver File-MAC no pacote do fabricante e instale o pacote assinado CH34xVCPDriver.pkg. Acesse Ajustes do Sistema > Privacidade e Segurança e autorize a extensão de kernel caso o sistema bloqueie a execução. O dispositivo será identificado no terminal como /dev/cu.usbserial-xxxx ou /dev/cu.wchusbserialxxxx.
Instalação do Pacote de Placas ESP32 e Fixação Estrita da Versão 2.0.12
A arquitetura do ESP32 não faz parte da instalação nativa da Arduino IDE. Para habilitar o suporte às placas baseadas no silício Espressif, é necessário adicionar a URL oficial dos repositórios de placas nas preferências da IDE.
Abra a Arduino IDE, acesse o menu Arquivo > Preferências (ou Ctrl + Vírgula) e localize o campo denominado URLs Adicionais para o Gerenciadores de Placas. Insira a seguinte URL:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json


Clique em OK para salvar as configurações. Em seguida, acesse o menu Ferramentas > Placa > Gerenciador de Placas… (ou clique no ícone correspondente na barra lateral esquerda da Arduino IDE 2.x). Na caixa de pesquisa superior, digite esp32.
Localize o pacote oficial mantido pela Espressif Systems.

⛔ REGRA INVIOLÁVEL DE COMPATIBILIDADE — FIXAR NA VERSÃO 2.0.12: No menu suspenso de seleção de versões do pacote esp32, selecione obrigatoriamente a versão 2.0.12. NÃO instale versões da série 3.x (ex.: 3.0.0, 3.0.4 ou superiores).
Por que a versão 3.x falha no kit AD174? A série 3.0 do núcleo ESP32 migrou a base de compilação do ESP-IDF v4.4 para o ESP-IDF v5.1. Nessa grande reformulação estrutural, a Espressif alterou radicalmente as APIs de periféricos de hardware:
- As funções de temporização e modulação PWM
ledcSetup(),ledcAttachPin()eledcWrite()foram sumariamente extintas do cabeçalho de compatibilidade e substituídas porledcAttach(pin, freq, res). Como os firmwares do kit AD174 utilizam os canais PWM dedicados para os motores e farol flash através dessas funções tradicionais, a compilação no core 3.x é abortada com erros fatais de símbolo indefinido (error: 'ledcSetup' was not declared in this scope).- O driver da câmera OV2640 sofreu alterações no gerenciamento de DMA (Direct Memory Access) que provocam corrupção de fluxo em streams MJPEG de alta taxa quando associados à alocação em PSRAM.
Portanto, assegure-se de que a versão instalada seja rigorosamente a 2.0.12.

Método Alternativo: Instalador Offline Executável
Caso a sua conexão com a internet apresente lentidão ou o download das ferramentas pelo Gerenciador de Placas falhe repetidamente, o fabricante Kuongshun disponibiliza no pacote do kit um instalador offline direto para Windows:
- Feche completamente a Arduino IDE;
- Navegue até a pasta
2_Programming_Preparation/2. Install the ESP32 plugin in the Arduino IDE; - Execute o instalador
esp32_package_2.0.12_arduinome.exe; - Siga as etapas na tela para descompactar e registrar todos os compiladores e cabeçalhos do ESP32 versão 2.0.12 diretamente na pasta
%LOCALAPPDATA%\Arduino15\packages\esp32; - Ao reabrir a Arduino IDE, as placas ESP32 estarão prontamente disponíveis no menu.


Parâmetros Obrigatórios de Configuração da Placa na Arduino IDE
Antes de carregar qualquer código no robô, verifique e configure rigorosamente os seguintes parâmetros no menu Ferramentas da Arduino IDE:
| Parâmetro no Menu Ferramentas | Valor de Configuração Obrigatório | Justificativa Técnica de Engenharia |
|---|---|---|
| Placa (Board) | ESP32 Dev Module | Mapeamento padrão com suporte aos pinos e periféricos do módulo AI-Thinker |
| Porta (Port) | COMxx (Porta serial do CH340) | Porta física USB associada à placa pelo sistema operacional |
| CPU Frequency | 240MHz (WiFi/BT) | Frequência máxima de processamento para atender o encoder JPEG e o rádio |
| Flash Frequency | 80MHz | Clock de leitura e escrita da memória flash SPI |
| Flash Mode | QIO (ou DIO) | Modo de barramento de 4 vias paralelas de alta performance |
| Partition Scheme | Huge APP (3MB No OTA/1MB SPIFFS) | Garante espaço de memória suficiente para o binário do servidor web e Wi-Fi |
| Core Debug Level | None (ou Error) | Desativa mensagens de debug desnecessárias na UART0 |
| PSRAM | Enabled | OBRIGATÓRIO: Ativa o acesso ao chip de 4 MB de PSRAM para buffer de vídeo |
| Upload Speed | 921600 (ou 115200 caso haja instabilidade) | Velocidade de gravação da memória flash do ESP32 |
Tabela-Mestre de Bibliotecas do Curso
Todas as bibliotecas e cabeçalhos requeridos para compilar os projetos práticos do Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 já estão integralmente embutidos no pacote oficial de placas ESP32 versão 2.0.12. Não há necessidade de baixar bibliotecas avulsas de terceiros no Gerenciador de Bibliotecas, garantindo total repetibilidade e eliminando conflitos de dependências transitivas:
| Biblioteca (#include) | Função e Papel no Projeto | Origem no Pacote ESP32 2.0.12 | Repositório Oficial Espressif | Lições em que é Utilizada |
|---|---|---|---|---|
esp_camera.h | Driver de controle de registradores, DMA e captura da câmera OV2640 | Integrada nativamente ao core ESP32 | espressif/esp32-camera | Lição 2 e Lição 3 |
WiFi.h | Gerenciamento da pilha TCP/IP e rádio Wi-Fi nos modos Estação e SoftAP | Integrada nativamente ao core ESP32 | espressif/arduino-esp32 | Lição 2 e Lição 3 |
esp_http_server.h | Servidor HTTP multithreaded embarcado no FreeRTOS para streaming MJPEG | Integrada nativamente ao ESP-IDF | espressif/esp-idf | Lição 2 e Lição 3 |
soc/soc.h | Definições de registradores básicos e barramentos do silício ESP32 | Integrada nativamente ao core ESP32 | espressif/arduino-esp32 | Lição 2 e Lição 3 |
soc/rtc_cntl_reg.h | Registradores de baixo nível do Real Time Clock e detector de brownout | Integrada nativamente ao core ESP32 | espressif/arduino-esp32 | Lição 2 e Lição 3 |
| Nativa do C++ / Arduino | Funções de GPIO (pinMode, digitalWrite, analogWrite, Serial) | Nativas do compilador Xtensa | arduino/ArduinoCore-API | Lição 1 |
💡 Conferência prévia: Para garantir que a toolchain esteja 100% funcional, abra a Arduino IDE, crie um sketch em branco (
setupeloopvazios), selecione a placaESP32 Dev Modulee clique em Verificar (Ctrl + R). A compilação deve finalizar com a mensagem “Compilação terminada” e alocação mínima de memória flash.
Lição 1 – Primeiros Movimentos do Robô (Get The Car Moving)
Nesta primeira lição prática, iniciamos a programação do Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 explorando o controle eletromecânico fundamental dos quatro motores de tração através da ponte H dupla L298N. O objetivo é compreender como sinais digitais discretos (níveis lógicos ALTO e BAIXO) e sinais analógicos sintetizados por modulação em largura de pulso (PWM) comandam os transistores internos do circuito integrado para orientar o fluxo de corrente contínua, governando os sentidos de rotação, velocidade e frenagem do veículo.
Arquitetura de Acionamento e Tabela de Verdade dos Motores
O controle do chassi 4WD agrupa os quatro motores em dois canais de tração: o par de motores esquerdos (conectados em paralelo nos bornes OUT1 e OUT2 do L298N) e o par de motores direitos (conectados em paralelo nos bornes OUT3 e OUT4 do L298N). O microcontrolador ESP32-CAM utiliza seis pinos digitais de saída para governar esse estágio de potência:
- GPIO 2 (
ENA): Habilitação e modulação de velocidade do lado esquerdo; - GPIO 12 (
ENB): Habilitação e modulação de velocidade do lado direito; - GPIO 33 (
gpLb- Left Backward): Comanda o sentido reverso das rodas esquerdas; - GPIO 15 (
gpLf- Left Forward): Comanda o sentido de avanço das rodas esquerdas; - GPIO 14 (
gpRb- Right Backward): Comanda o sentido reverso das rodas direitas; - GPIO 13 (
gpRf- Right Forward): Comanda o sentido de avanço das rodas direitas.
A lógica de acionamento das bobinas dos motores obedece estritamente à seguinte tabela de verdade:
| ENA (GPIO 2) | ENB (GPIO 12) | gpLb (GPIO 33) | gpLf (GPIO 15) | gpRb (GPIO 14) | gpRf (GPIO 13) | Estado Cinemático Resultante do Robô |
|---|---|---|---|---|---|---|
| HIGH | HIGH | LOW | HIGH | LOW | HIGH | Avanço em Linha Reta (Forward): Ambos os lados giram para frente em velocidade máxima |
| HIGH | HIGH | HIGH | LOW | HIGH | LOW | Marcha a Ré (Backward): Ambos os lados giram para trás em velocidade máxima |
| HIGH | HIGH | HIGH | LOW | LOW | HIGH | Conversão à Esquerda (Turn Left): Lado esquerdo gira para trás, lado direito para frente |
| HIGH | HIGH | LOW | HIGH | HIGH | LOW | Conversão à Direita (Turn Right): Lado esquerdo gira para frente, lado direito para trás |
| HIGH | HIGH | LOW | LOW | LOW | LOW | Parada Rápida por Frenagem Elétrica (Stop): Terminais dos motores em curto-circuito |
| HIGH | HIGH | HIGH | HIGH | HIGH | HIGH | Parada por Curto-Circuito Lógico (Stop): Entradas idênticas em nível alto |
| LOW | LOW | N/A | N/A | N/A | N/A | Parada por Desabilitação (Inércia / Coast): Canais da ponte H desligados |
Fundamentos Teóricos da Modulação por Largura de Pulso (PWM)
Para variar a rotação dos motores sem dissipar energia em resistores em série, utiliza-se a técnica de Modulação por Largura de Pulso (PWM — Pulse-Width Modulation). Em vez de fornecer uma tensão contínua linear variável, o circuito entrega uma onda quadrada com frequência constante e alterna ciclicamente a saída entre a tensão máxima de saturação da bateria () durante o tempo ativo e zero volts durante o tempo inativo :
A razão entre o tempo ativo e o período total é definida como o Ciclo de Trabalho ou Duty Cycle ():
A tensão média eficaz resultante aplicada aos bornes do motor corresponde diretamente ao produto do Duty Cycle pela tensão da fonte:
No ambiente Arduino, a resolução padrão do PWM é de 8 bits, discretizando o intervalo em passos inteiros (de a ). Assim, ao executar analogWrite(pino, 128), o duty cycle configurado é:
Como a bobina de um motor de corrente contínua atua como uma carga indutiva em série com uma resistência de armadura () e uma força contraeletromotriz induzida (), a corrente elétrica não varia instantaneamente, mas é suavizada pela constante de tempo indutiva . O torque mecânico instantâneo desenvolvido no eixo do motor é linearmente proporcional à corrente média:
Contudo, todo motor DC com caixa de redução plástica apresenta um atrito estático mecânico interno nos dentes das engrenagens e no contato das escovas com o comutador. Existe, portanto, uma tensão mínima de partida (zona morta ou deadband), tipicamente correspondente a valores de PWM entre e . Abaixo desse limiar de energia, o torque eletromagnético é insuficiente para romper a inércia estática e o motor apenas emite um zumbido característico de alta frequência sem produzir movimento mecânico.
Procedimento Geral de Gravação e Upload de Sketches
Para carregar os sketches desta lição na placa ESP32-CAM, siga o roteiro canônico do fabricante Kuongshun:
- Conecte a placa ESP32-CAM ao computador através do cabo USB Tipo-C;
- Na Arduino IDE, selecione o modelo de placa em Ferramentas > Placa > esp32 > ESP32 Dev Module;
- Selecione a porta de comunicação em Ferramentas > Porta > COMxx (identificada no Gerenciador de Dispositivos com o driver CH340);
- Abra o arquivo
.inodesejado; - Clique no botão Carregar (Upload, ícone de seta apontando para a direita na barra superior);
- Aguarde a compilação do código e o processo de gravação na memória flash. O console inferior exibirá as porcentagens de escrita (
Writing at 0x00010000... (100 %)) e concluirá com a mensagem “Leaving… Hard resetting via RTS pin…”. - Desconecte o cabo USB do computador, coloque o robô no chão, instale as duas baterias 18650 no suporte com a polaridade correta e ligue a chave geral. Caso o robô não inicialize o movimento de imediato, pressione uma vez o botão RST (Reset) localizado na placa base da ESP32-CAM.
Projeto 1.1 – Movimento de Avanço Contínuo (Forward)
O sketch Forward.ino configura todos os pinos de controle dos motores como saídas digitais e comuta os canais da ponte H para impor rotação de avanço com velocidade máxima em ambos os lados do chassi.
📦 Bibliotecas desta lição: nenhuma — o código utiliza apenas as funções nativas de GPIO (
pinMode,digitalWrite,Serial) embutidas no compilador do núcleo ESP32. Nada a baixar ou instalar.
// ============================================================================
// Projeto 1.1: Movimento de Avanço Contínuo para Frente (Forward.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM com Driver L298N | Tração 4WD
// ============================================================================
// Definição dos pinos de interface com o módulo de potência L298N
#define ENA 2 // Pino GPIO 2 conectado à habilitação do Canal A (Velocidade Lado Esquerdo)
#define ENB 12 // Pino GPIO 12 conectado à habilitação do Canal B (Velocidade Lado Direito)
#define gpRb 14 // Pino GPIO 14: Entrada IN3 do L298N (Roda Direita para Trás / Backward)
#define gpRf 13 // Pino GPIO 13: Entrada IN4 do L298N (Roda Direita para Frente / Forward)
#define gpLb 33 // Pino GPIO 33: Entrada IN1 do L298N (Roda Esquerda para Trás / Backward)
#define gpLf 15 // Pino GPIO 15: Entrada IN2 do L298N (Roda Esquerda para Frente / Forward)
// Função de configuração de hardware executada uma única vez na inicialização
void setup() {
// Inicializa a interface de comunicação serial a 9600 bps para telemetria
Serial.begin(9600);
// Configura todos os seis pinos de comando do L298N como saídas digitais ativas
pinMode(gpLb, OUTPUT); // Configura o pino GPIO 33 como saída
pinMode(gpLf, OUTPUT); // Configura o pino GPIO 15 como saída
pinMode(gpRb, OUTPUT); // Configura o pino GPIO 14 como saída
pinMode(gpRf, OUTPUT); // Configura o pino GPIO 13 como saída
pinMode(ENA, OUTPUT); // Configura o pino GPIO 2 como saída
pinMode(ENB, OUTPUT); // Configura o pino GPIO 12 como saída
}
// Loop de execução contínua do microcontrolador
void loop() {
// Habilita os canais de potência A e B do driver L298N em nível alto (100% de tensão)
digitalWrite(ENA, HIGH); // Ativa o canal de potência dos motores esquerdos
digitalWrite(ENB, HIGH); // Ativa o canal de potência dos motores direitos
// Configura o sentido de rotação dos motores do lado esquerdo para frente
digitalWrite(gpLb, LOW); // Desativa o comando reverso do lado esquerdo
digitalWrite(gpLf, HIGH); // Ativa o comando de avanço do lado esquerdo
// Configura o sentido de rotação dos motores do lado direito para frente
digitalWrite(gpRb, LOW); // Desativa o comando reverso do lado direito
digitalWrite(gpRf, HIGH); // Ativa o comando de avanço do lado direito
// Envia mensagem informativa para o Monitor Serial da Arduino IDE
Serial.println("Forward");
}
Teste e Validação do Projeto 1.1
Após efetuar o upload do código e alimentar o robô pelas baterias, coloque-o sobre o chão. As quatro rodas devem girar sincronizadamente no sentido de avanço, impulsionando o robô em linha reta para frente. Caso o robô gire em torno do próprio eixo ou mova-se para trás, consulte o diagnóstico de inversão de fiação no final deste manual (Passo 8 / Troubleshooting).
Projeto 1.2 – Movimento de Marcha a Ré (Backward)
O sketch Backward.ino inverte a polaridade elétrica nas escovas dos quatro motores, fazendo com que o fluxo de corrente contínua atravesse as armaduras no sentido oposto, gerando torque reverso e deslocando o robô para trás.
📦 Bibliotecas desta lição: nenhuma — o código utiliza apenas as funções nativas de GPIO (
pinMode,digitalWrite,Serial). Nada a baixar ou instalar.
// ============================================================================
// Projeto 1.2: Movimento de Marcha a Ré Contínua (Backward.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM com Driver L298N | Tração 4WD
// ============================================================================
// Definição dos pinos de interface com o módulo L298N
#define ENA 2 // Pino GPIO 2: Habilitação dos motores esquerdos
#define ENB 12 // Pino GPIO 12: Habilitação dos motores direitos
#define gpRb 14 // Pino GPIO 14: Sentido reverso dos motores direitos
#define gpRf 13 // Pino GPIO 13: Sentido de avanço dos motores direitos
#define gpLb 33 // Pino GPIO 33: Sentido reverso dos motores esquerdos
#define gpLf 15 // Pino GPIO 15: Sentido de avanço dos motores esquerdos
void setup() {
// Inicializa o canal serial a 9600 bps para monitoramento
Serial.begin(9600);
// Configura os pinos de controle da ponte H como saídas digitais
pinMode(gpLb, OUTPUT); // Saída do sentido ré esquerdo
pinMode(gpLf, OUTPUT); // Saída do sentido frente esquerdo
pinMode(gpRb, OUTPUT); // Saída do sentido ré direito
pinMode(gpRf, OUTPUT); // Saída do sentido frente direito
pinMode(ENA, OUTPUT); // Saída de habilitação esquerda
pinMode(ENB, OUTPUT); // Saída de habilitação direita
}
void loop() {
// Habilita as duas saídas de potência do L298N em condução máxima
digitalWrite(ENA, HIGH); // Habilita canal A em saturação
digitalWrite(ENB, HIGH); // Habilita canal B em saturação
// Configura o lado esquerdo para rotação reversa
digitalWrite(gpLb, HIGH); // Coloca IN1 em nível alto (ré ativada)
digitalWrite(gpLf, LOW); // Coloca IN2 em nível baixo (avanço desligado)
// Configura o lado direito para rotação reversa
digitalWrite(gpRb, HIGH); // Coloca IN3 em nível alto (ré ativada)
digitalWrite(gpRf, LOW); // Coloca IN4 em nível baixo (avanço desligado)
// Imprime confirmação do comando no Monitor Serial
Serial.println("Back");
}
Projeto 1.3 – Conversão à Esquerda (Turn Left)
Para realizar uma manobra de conversão fechada ou rotação no próprio eixo para a esquerda, o lado esquerdo do veículo deve girar para trás enquanto o lado direito gira para frente. O par de torques opostos gera um momento angular no sentido anti-horário (visto de cima), fazendo o robô girar sobre o centro de sua bitola.
📦 Bibliotecas desta lição: nenhuma — o código utiliza apenas comandos de GPIO nativos.
// ============================================================================
// Projeto 1.3: Conversão e Rotação à Esquerda (Turn_left.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM com Driver L298N | Tração 4WD
// ============================================================================
#define ENA 2 // Pino GPIO 2: Habilitação canal esquerdo
#define ENB 12 // Pino GPIO 12: Habilitação canal direito
#define gpRb 14 // Pino GPIO 14: Marcha ré direita
#define gpRf 13 // Pino GPIO 13: Avanço direito
#define gpLb 33 // Pino GPIO 33: Marcha ré esquerda
#define gpLf 15 // Pino GPIO 15: Avanço esquerdo
void setup() {
Serial.begin(9600);
pinMode(gpLb, OUTPUT);
pinMode(gpLf, OUTPUT);
pinMode(gpRb, OUTPUT);
pinMode(gpRf, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
}
void loop() {
// Habilita potência máxima nas duas pontes H
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
// Rodas esquerdas giram no sentido REVERSO (gpLb = HIGH, gpLf = LOW)
digitalWrite(gpLb, HIGH);
digitalWrite(gpLf, LOW);
// Rodas direitas giram no sentido FRONTAL (gpRb = LOW, gpRf = HIGH)
digitalWrite(gpRb, LOW);
digitalWrite(gpRf, HIGH);
Serial.println("Left");
}
Projeto 1.4 – Conversão à Direita (Turn Right)
Inversamente à manobra anterior, para girar no sentido horário para a direita, as rodas do lado esquerdo devem girar para frente enquanto as rodas do lado direito giram em marcha a ré.
📦 Bibliotecas desta lição: nenhuma — comandos nativos de GPIO do núcleo ESP32.
// ============================================================================
// Projeto 1.4: Conversão e Rotação à Direita (Turn_right.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM com Driver L298N | Tração 4WD
// ============================================================================
#define ENA 2 // Pino GPIO 2: Habilitação canal esquerdo
#define ENB 12 // Pino GPIO 12: Habilitação canal direito
#define gpRb 14 // Pino GPIO 14: Marcha ré direita
#define gpRf 13 // Pino GPIO 13: Avanço direito
#define gpLb 33 // Pino GPIO 33: Marcha ré esquerda
#define gpLf 15 // Pino GPIO 15: Avanço esquerdo
void setup() {
Serial.begin(9600);
pinMode(gpLb, OUTPUT);
pinMode(gpLf, OUTPUT);
pinMode(gpRb, OUTPUT);
pinMode(gpRf, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
}
void loop() {
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
// Rodas esquerdas giram no sentido FRONTAL (gpLb = LOW, gpLf = HIGH)
digitalWrite(gpLb, LOW);
digitalWrite(gpLf, HIGH);
// Rodas direitas giram no sentido REVERSO (gpRb = HIGH, gpRf = LOW)
digitalWrite(gpRb, HIGH);
digitalWrite(gpRf, LOW);
Serial.println("Right");
}
Projeto 1.5 – Controle Suave de Velocidade via PWM (Speed Control)
O sketch Speed_control.ino demonstra o controle contínuo e progressivo de aceleração e frenagem suave através de sinais PWM gerados nos pinos ENA (GPIO 2) e ENB (GPIO 12). A rotina executa uma rampa linear ascendente de velocidade de até em passos de , sustenta a velocidade de pico durante e em seguida executa uma rampa descendente de desaceleração até a imobilização completa.
📦 Bibliotecas desta lição: nenhuma — usa a função nativa
analogWrite()suportada no núcleo ESP32 2.0.12.
// ============================================================================
// Projeto 1.5: Controle Dinâmico de Velocidade via Rampa PWM (Speed_control.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM com Driver L298N | Tração 4WD
// ============================================================================
#define ENA 2 // Pino GPIO 2: Controle de PWM do motor esquerdo
#define ENB 12 // Pino GPIO 12: Controle de PWM do motor direito
#define gpRb 14 // Pino GPIO 14: Ré direita
#define gpRf 13 // Pino GPIO 13: Avanço direito
#define gpLb 33 // Pino GPIO 33: Ré esquerda
#define gpLf 15 // Pino GPIO 15: Avanço esquerdo
void setup() {
Serial.begin(9600);
pinMode(gpLb, OUTPUT);
pinMode(gpLf, OUTPUT);
pinMode(gpRb, OUTPUT);
pinMode(gpRf, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
}
void loop() {
// Configura a direção do movimento permanentemente para frente
digitalWrite(gpLb, LOW); // Desativa ré esquerda
digitalWrite(gpLf, HIGH); // Ativa avanço esquerdo
digitalWrite(gpRb, LOW); // Desativa ré direita
digitalWrite(gpRf, HIGH); // Ativa avanço direito
// Rampa de Aceleração Suave: incrementa o ciclo de trabalho de 0 a 255
for (int i = 0; i <= 255; i++) {
analogWrite(ENB, i); // Aplica nível PWM nos motores direitos
analogWrite(ENA, i); // Aplica nível PWM nos motores esquerdos
delay(20); // Pausa de 20 ms entre incrementos (~5,1 segundos de rampa)
}
// Mantém a velocidade máxima estabelecida durante 1 segundo
delay(1000);
// Rampa de Desaceleração Gradual: reduz o ciclo de trabalho de 255 a 0
for (int i = 255; i >= 0; i--) {
analogWrite(ENB, i); // Reduz nível PWM nos motores direitos
analogWrite(ENA, i); // Reduz nível PWM nos motores esquerdos
delay(20); // Pausa de 20 ms entre decrementos (~5,1 segundos de rampa)
}
// Permanece em repouso durante 1 segundo antes de repetir o ciclo
delay(1000);
}
Projeto 1.6 – Rotina Autônoma Integrada em Loop (AUTO_GO)
O sketch AUTO_GO.ino consolida todas as funções de locomoção em um código estruturado modularmente por funções independentes (forward(), back(), left(), right()), executando uma sequência de demonstração contínua: o robô avança durante 1 segundo, retrocede durante 1 segundo, gira à esquerda durante 1 segundo e gira à direita durante 1 segundo, repetindo o padrão indefinidamente.
📦 Bibliotecas desta lição: nenhuma — arquitetura em funções C++ nativas.
// ============================================================================
// Projeto 1.6: Ciclo Autônomo Completo de Movimentação (AUTO_GO.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM com Driver L298N | Tração 4WD
// ============================================================================
// Definição dos pinos de interface com o módulo L298N
#define ENA 2 // GPIO 2: Habilitação Lado Esquerdo
#define ENB 12 // GPIO 12: Habilitação Lado Direito
#define gpRb 14 // GPIO 14: Sentido Ré Direito
#define gpRf 13 // GPIO 13: Sentido Avanço Direito
#define gpLb 33 // GPIO 33: Sentido Ré Esquerdo
#define gpLf 15 // GPIO 15: Sentido Avanço Esquerdo
// Sub-rotina para movimentação retilínea para frente
void forward() {
digitalWrite(ENA, HIGH); // Habilita canal A em velocidade máxima
digitalWrite(ENB, HIGH); // Habilita canal B em velocidade máxima
digitalWrite(gpLb, LOW); // Desativa ré esquerda
digitalWrite(gpLf, HIGH); // Ativa avanço esquerdo
digitalWrite(gpRb, LOW); // Desativa ré direita
digitalWrite(gpRf, HIGH); // Ativa avanço direito
Serial.println("Forward");// Transmite status na porta serial
}
// Sub-rotina para movimentação de marcha a ré
void back() {
digitalWrite(ENA, HIGH); // Habilita canal A
digitalWrite(ENB, HIGH); // Habilita canal B
digitalWrite(gpLb, HIGH); // Ativa ré esquerda
digitalWrite(gpLf, LOW); // Desativa avanço esquerdo
digitalWrite(gpRb, HIGH); // Ativa ré direita
digitalWrite(gpRf, LOW); // Desativa avanço direito
Serial.println("Back");
}
// Sub-rotina para conversão e giro à esquerda
void left() {
digitalWrite(ENA, HIGH); // Habilita canal A
digitalWrite(ENB, HIGH); // Habilita canal B
digitalWrite(gpLb, HIGH); // Lado esquerdo gira para trás
digitalWrite(gpLf, LOW);
digitalWrite(gpRb, LOW); // Lado direito gira para frente
digitalWrite(gpRf, HIGH);
Serial.println("Left");
}
// Sub-rotina para conversão e giro à direita
void right() {
digitalWrite(ENA, HIGH); // Habilita canal A
digitalWrite(ENB, HIGH); // Habilita canal B
digitalWrite(gpLb, LOW); // Lado esquerdo gira para frente
digitalWrite(gpLf, HIGH);
digitalWrite(gpRb, HIGH); // Lado direito gira para trás
digitalWrite(gpRf, LOW);
Serial.println("Right");
}
// Rotina de inicialização e configuração de pinos
void setup() {
Serial.begin(9600); // Inicializa porta serial a 9600 baud
pinMode(gpLb, OUTPUT); // Configura todos os 6 pinos como saídas ativas
pinMode(gpLf, OUTPUT);
pinMode(gpRb, OUTPUT);
pinMode(gpRf, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
}
// Loop principal de execução cíclica
void loop() {
forward(); // Executa movimento para frente
delay(1000); // Mantém o deslocamento ativo durante 1000 ms (1 segundo)
back(); // Executa movimento de ré
delay(1000); // Mantém o deslocamento ativo durante 1 segundo
left(); // Executa conversão à esquerda
delay(1000); // Mantém o giro ativo durante 1 segundo
right(); // Executa conversão à direita
delay(1000); // Mantém o giro ativo durante 1 segundo
}
Lição 2 – Controle do Robô via Interface Web e Streaming de Vídeo (WIFI Camera Car Code for Web)
Nesta lição, integramos a visão computacional embarcada e a teleoperação sem fio através de um servidor web autônomo executado inteiramente dentro da placa ESP32-CAM. O robô gera seu próprio ponto de acesso Wi-Fi (SoftAP), hospeda uma página web responsiva com botões interativos e transmite um fluxo ininterrupto de vídeo em tempo real no formato MJPEG (Motion JPEG). Qualquer dispositivo conectado à rede local — como um smartphone Android ou iOS, tablet ou notebook — pode abrir o navegador web, visualizar a transmissão da câmera OV2640 e pilotar o robô sem a necessidade de instalar aplicativos externos ou depender de roteadores domésticos.
Arquitetura de Rede e Protocolo de Streaming MJPEG
Ao ser inicializado, o firmware do robô coloca o rádio Wi-Fi do ESP32 no modo de Ponto de Acesso (Access Point), criando a rede sem fio com o identificador de serviço (SSID) KUONGSHUN-AD174 e chave de segurança WPA2-PSK 12345678. O microcontrolador atribui a si próprio o endereço IP estático padrão 192.168.4.1 e inicializa dois servidores de rede em paralelo:
- Servidor HTTP na Porta 80 (
httpd_start): Gerencia requisições de página (/), comandos de movimentação e ajuste de parâmetros (/control), captura de foto instantânea (/capture) e o fluxo contínuo de vídeo (/stream); - Servidor de Soquete TCP na Porta 100 (
WiFiServer server(100)): Canal de comunicação raw para troca assíncrona de comandos de controle de baixa latência.
O streaming de vídeo utiliza o padrão aberto MJPEG através do tipo de conteúdo MIME multipart/x-mixed-replace. Quando o navegador solicita o endpoint http://192.168.4.1:81/stream (ou a rota /stream), o servidor responde com o cabeçalho HTTP:
HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace;boundary=123456789000000000000987654321
Access-Control-Allow-Origin: *
A cada novo quadro de imagem capturado pelo sensor OV2640 e comprimido pelo circuito interno em formato JPEG, o ESP32 envia a linha delimitadora (boundary), o cabeçalho específico da imagem (Content-Type: image/jpeg e Content-Length) e o bloco binário comprimido de pixels:
--123456789000000000000987654321
Content-Type: image/jpeg
Content-Length: 14520
<bytes binários da imagem JPEG>
O navegador web interpreta essa resposta especial substituindo instantaneamente a imagem anterior na tela pela nova imagem recebida, sem nunca fechar a conexão HTTP e sem gerar sobrecarga de handshake de novas requisições.
Proteção Contra Afundamento de Tensão (Brownout Reset)
Ao transmitir sinais de rádio Wi-Fi em potência máxima () e simultaneamente comutar os transistores da ponte H para acionar os motores DC, ocorrem picos instantâneos de corrente que podem ultrapassar . Se as baterias 18650 apresentarem leve resistência interna ou não estiverem em plena carga, a tensão no barramento de pode sofrer uma breve ondulação transitória (ripple) e cair abaixo do limiar do detector de brownout interno do ESP32 (), provocando um reset involuntário do processador.
Para conferir máxima resiliência e estabilidade ao robô em bancada, o firmware do fabricante desativa intencionalmente o detector de subtensão do subsistema RTC logo no início da função setup():
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Desativa o detector de brownout
Código-Fonte Completo do Projeto Web
O projeto é estruturado em três arquivos de código: o sketch principal (ESP32CAM_L298N_Web.ino), o módulo de inicialização da câmera e rede (CameraWebServer.cpp) e o despachante de rotas e comandos HTTP (app_httpd.cpp).
📦 Bibliotecas desta lição:
esp_camera.h— driver nativo de câmera integrado no pacote de placas ESP32 2.0.12.WiFi.h— biblioteca nativa de gerenciamento de rádio Wi-Fi.soc/soc.hesoc/rtc_cntl_reg.h— cabeçalhos de registradores de baixo nível do chip ESP32.- Todas estão integradas nativamente ao pacote oficial de placas ESP32 versão 2.0.12. Nada a baixar separadamente.
Arquivo 1: ESP32CAM_L298N_Web.ino
// ============================================================================
// Projeto 2: Servidor Web e Streaming MJPEG (ESP32CAM_L298N_Web.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM | Câmera OV2640 | Driver L298N
// ============================================================================
#include "esp_camera.h" // Driver oficial de controle da câmera OV2640
#include <WiFi.h> // Biblioteca de rede Wi-Fi nativa do ESP32
#include "soc/soc.h" // Definições de hardware e registradores do silício
#include "soc/rtc_cntl_reg.h" // Registradores do controlador de baixo consumo e brownout
// Seleciona o perfil de pinagem para a placa AI-Thinker ESP32-CAM
#define CAMERA_MODEL_AI_THINKER
// Definições de pinos auxiliares
#define LED 4 // LED flash de alta potência no pino GPIO 4
#define RXD2 14 // Pino RX da segunda UART (caso seja utilizada ponte externa)
#define TXD2 13 // Pino TX da segunda UART
// Declaração da função externa de inicialização da câmera e do servidor HTTP
void CameraWebServer_init();
// Inicializa o servidor de soquete TCP na porta 100
WiFiServer server(100);
// Mapeamento dos pinos de interface com o módulo L298N (variáveis globais exportadas)
extern int gpLb = 14; // Entrada IN3 do L298N (Ré do lado direito)
extern int gpLf = 13; // Entrada IN4 do L298N (Avanço do lado direito)
extern int gpRb = 33; // Entrada IN1 do L298N (Ré do lado esquerdo)
extern int gpRf = 15; // Entrada IN2 do L298N (Avanço do lado esquerdo)
extern int gpLed = 4; // LED flash no pino GPIO 4
extern int ENR = 2; // Canal PWM de velocidade do lado direito
extern int ENL = 12; // Canal PWM de velocidade do lado esquerdo
// Função de inicialização e configuração dos pinos de controle dos motores
void initMotors() {
// Configura os terminais de controle de direção como saídas digitais
pinMode(gpLb, OUTPUT); // Ré Direita
pinMode(gpLf, OUTPUT); // Frente Direita
pinMode(gpRb, OUTPUT); // Ré Esquerda
pinMode(gpRf, OUTPUT); // Frente Esquerda
pinMode(gpLed, OUTPUT); // Farol Flash LED
pinMode(ENR, OUTPUT); // Habilitação Direita
pinMode(ENL, OUTPUT); // Habilitação Esquerda
// Configura os canais de modulação PWM via temporizador de hardware LEDC
// Canal 2, frequência de 5000 Hz, resolução de 8 bits (valores de 0 a 255)
ledcSetup(2, 5000, 8);
// Canal 12, frequência de 5000 Hz, resolução de 8 bits
ledcSetup(12, 5000, 8);
// Vincula os pinos físicos ENR e ENL aos seus respectivos canais de hardware
ledcAttachPin(ENR, 2);
ledcAttachPin(ENL, 12);
// Inicializa a velocidade com ciclo de trabalho em zero (motores imobilizados)
ledcWrite(ENR, 0);
ledcWrite(ENL, 0);
// Garante que todas as entradas de direção inicializem em nível lógico baixo
digitalWrite(gpLf, LOW);
digitalWrite(gpRb, LOW);
digitalWrite(gpRf, LOW);
digitalWrite(gpLb, LOW);
}
void setup() {
// Desativa o detector de brownout para prevenir reinicializações sob transientes de corrente
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// Inicializa a comunicação serial com o computador a 115200 bps
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);
Serial.setDebugOutput(true); // Habilita logs detalhados do driver de câmera
Serial.println();
// Inicializa o sensor óptico OV2640 e sobe a rede Wi-Fi SoftAP
CameraWebServer_init();
// Inicializa e desliga os motores de tração
initMotors();
// Configura o canal PWM 7 para controle proporcional do LED flash
ledcSetup(7, 5000, 8);
ledcAttachPin(gpLed, 7); // Vincula o pino 4 ao canal 7
// Inicializa a escuta no servidor TCP porta 100
server.begin();
// Executa uma sequência de 5 piscadas rápidas no LED flash para indicar boot bem-sucedido
for (int i = 0; i < 5; i++) {
ledcWrite(7, 10); // Liga o LED com intensidade moderada
delay(50);
ledcWrite(7, 0); // Desliga o LED
delay(50);
}
}
void loop() {
// O processamento principal do streaming e das rotas é gerenciado assincronamente
// pelas tarefas do FreeRTOS iniciadas pela biblioteca esp_http_server.
}
Arquivo 2: CameraWebServer.cpp
// ============================================================================
// Módulo de Inicialização da Câmera OV2640 e do Access Point Wi-Fi
// ============================================================================
#include "esp_system.h"
#include "esp_camera.h"
#include <WiFi.h>
// Credenciais de fábrica do Ponto de Acesso gerado pelo robô
const char *ssid = "KUONGSHUN-AD174"; // Nome da rede Wi-Fi transmitida
const char *password = "12345678"; // Chave de autenticação WPA2-PSK
String wifi_name;
// Mapeamento dos pinos do barramento DVP do módulo AI-Thinker ESP32-CAM
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// Função de registro e inicialização do servidor HTTP declarada em app_httpd.cpp
void startCameraServer();
void CameraWebServer_init() {
camera_config_t config; // Estrutura de configuração do driver de câmera
// Configuração dos temporizadores do sinal de clock mestre
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
// Atribuição dos pinos do barramento paralelo de 8 bits
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;
// Atribuição das linhas de sincronismo e clock
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_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
// Frequência do sinal de clock XCLK em 20 MHz
config.xclk_freq_hz = 20000000;
config.frame_size = FRAMESIZE_UXGA; // Resolução máxima do sensor
config.pixel_format = PIXFORMAT_JPEG; // Fluxo comprimido JPEG nativo
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM; // Aloca buffers na memória PSRAM
config.jpeg_quality = 12; // Nível de qualidade (0 a 63; menor = melhor)
config.fb_count = 1; // Número de buffers alocados
// Otimização de buffers caso o chip de PSRAM externa de 4 MB seja detectado
if (config.pixel_format == PIXFORMAT_JPEG) {
if (psramFound()) {
config.jpeg_quality = 10; // Qualidade superior de imagem
config.fb_count = 2; // Double-buffering para streaming fluído
config.grab_mode = CAMERA_GRAB_LATEST;// Sempre descarta quadros atrasados
} else {
// Caso a PSRAM falhe, reduz a resolução para SVGA e aloca na DRAM interna
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
}
// Inicializa o hardware do sensor com a configuração definida
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Falha na inicializacao da camera! Codigo de erro: 0x%x
", err);
return;
}
// Obtém ponteiro para a estrutura de registradores finos do sensor
sensor_t *s = esp_camera_sensor_get();
// Configura a resolução inicial padrão em QVGA (320x240) para streaming rápido
s->set_framesize(s, FRAMESIZE_QVGA);
// Ajuste de orientação óptica: espelhamento vertical e horizontal
s->set_vflip(s, 1); // Inverte verticalmente a imagem para corrigir a montagem física
s->set_hmirror(s, 1); // Corrige a orientação horizontal em espelho
// Ajusta a potência de transmissão do rádio Wi-Fi para o nível máximo estável
WiFi.setTxPower(WIFI_POWER_19_5dBm);
// Inicializa o ponto de acesso Wi-Fi local
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password, 5); // SSID, senha e canal de transmissão 5
// Inicia o despachante de requisições HTTP
startCameraServer();
Serial.print("
Camera Pronta! Conecte-se em: http://");
Serial.print(WiFi.softAPIP());
Serial.println("
");
}
Arquivo 3: Fragmento do Despachante de Comandos em app_httpd.cpp
O arquivo app_httpd.cpp processa as requisições GET encaminhadas ao endpoint /control. Ao receber comandos com as chaves var e val, ele comuta os estados dos motores e ajusta os parâmetros de câmera:
// Função de acionamento unificado dos quatro motores e velocidade PWM
void WheelAct(int speed_R, int speed_L, int nLf, int nLb, int nRf, int nRb) {
ledcWrite(ENR, speed_R); // Aplica PWM no motor direito
ledcWrite(ENL, speed_L); // Aplica PWM no motor esquerdo
digitalWrite(gpLf, nLf); // Frente esquerda
digitalWrite(gpLb, nLb); // Ré esquerda
digitalWrite(gpRf, nRf); // Frente direita
digitalWrite(gpRb, nRb); // Ré direita
}
// Manipulador de requisições do endpoint /control
static esp_err_t cmd_handler(httpd_req_t *req) {
char* buf;
size_t buf_len;
char variable[32] = {0,};
char value[32] = {0,};
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char*)malloc(buf_len);
if (!buf) {
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK &&
httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) {
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
}
free(buf);
}
int val = atoi(value);
sensor_t * s = esp_camera_sensor_get();
// Rota de alteração de resolução da câmera
if (!strcmp(variable, "framesize")) {
if (s->pixformat == PIXFORMAT_JPEG) s->set_framesize(s, (framesize_t)val);
}
// Rota de alteração do brilho do farol LED Flash
else if (!strcmp(variable, "flash")) {
ledcWrite(7, val); // Aplica duty cycle de 0 a 255 no GPIO 4
}
// Rota de ajuste da velocidade dos motores
else if (!strcmp(variable, "speed")) {
if (val > 255) val = 255;
else if (val < 0) val = 0;
speed = val;
}
// Rota de movimentação física do robô
else if (!strcmp(variable, "car")) {
if (val == 1) { // Avanço (Forward)
WheelAct(speed, speed, HIGH, LOW, HIGH, LOW);
} else if (val == 2) { // Conversão à Direita (Turn Right)
WheelAct(speed, speed, LOW, HIGH, HIGH, LOW);
} else if (val == 3) { // Conversão à Esquerda (Turn Left)
WheelAct(speed, speed, HIGH, LOW, LOW, HIGH);
} else if (val == 4) { // Marcha a Ré (Backward)
WheelAct(speed, speed, LOW, HIGH, LOW, HIGH);
} else if (val == 0) { // Parada Imediata (Stop)
WheelAct(0, 0, LOW, LOW, LOW, LOW);
}
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, "OK", 2);
}
Guia Passo a Passo de Operação da Interface Web
- Gravação do Firmware: Carregue o projeto
ESP32CAM_L298N_Webna placa ESP32-CAM via cabo USB Tipo-C; - Alimentação Autônoma: Desconecte o cabo USB, insira duas baterias 18650 carregadas no suporte traseiro e acione o interruptor liga/desliga. O farol LED flash piscará 5 vezes para sinalizar que o sistema está operacional;
- Conexão Wi-Fi: No smartphone ou computador, abra a lista de redes Wi-Fi disponíveis, selecione a rede
KUONGSHUN-AD174e digite a senha12345678. Caso o sistema operacional informe que a rede não possui conexão com a internet, confirme e marque para “Permanecer Conectado”; - Acesso ao Portal: Abra o navegador Google Chrome, Safari ou Mozilla Firefox e digite o endereço IP:
http://192.168.4.1


A interface web apresenta os seguintes controles ergonômicos:
- Botão de Streaming (Ícone de Câmera): Inicia a recepção contínua do fluxo de vídeo em tempo real na tela;
- Botão Snapshot: Congela o quadro atual e salva uma fotografia da visualização;
- Teclas Direcionais em Cruz (D-Pad Virtual): Botões para avançar, retroceder, virar à esquerda e virar à direita. O acionamento opera sob retenção contínua (press and hold): enquanto o botão for mantido pressionado, o robô se desloca; ao soltar, os motores são imediatamente desativados;
- Slider de Velocidade: Ajusta dinamicamente o valor do PWM de a ;
- Slider de Iluminação Flash: Regula o brilho do LED branco do GPIO 4 para navegação em ambientes escuros;
- Seletor de Resolução: Permite alternar instantaneamente entre resoluções QVGA (), VGA () e SVGA ().


Lição 3 – Controle do Robô via Aplicativo Mobile KUONGSHUN (WIFI Camera Car Code for APP)
Nesta lição avançada, exploramos a integração do Kit Robô Avançado 4WD com Câmera ESP32-CAM AD174 com o aplicativo móvel oficial KUONGSHUN. Ao invés de trafegar comandos baseados em strings de texto através de requisições HTTP individuais, o firmware implementa um servidor de soquetes TCP bruto na porta 100 e uma máquina de estados de alto desempenho capaz de decodificar pacotes binários compactados em tempo real. Isso reduz drasticamente a sobrecarga de cabeçalhos de rede e a latência de controle, proporcionando respostas instantâneas ao joystick virtual com transmissão simultânea de vídeo em alta taxa de quadros.
Download e Instalação do Aplicativo Mobile
O aplicativo oficial está hospedado e disponível para download direto e irrestrito para dispositivos Android:
📱 Download Direto do Aplicativo:
- Pacote Android (APK): Baixar Aplicativo Oficial Android: KUONGSHUN.apk (Arquivo
.apkoficial da Kuongshun, versão estável, tamanho ).- Instalação no Android: Transfira ou baixe o arquivo
KUONGSHUN.apkdiretamente no seu smartphone. Ao abrir o arquivo no gerenciador de arquivos, caso o sistema Android exiba um aviso de segurança sobre aplicativos de fontes desconhecidas, acesse as configurações do instalador e selecione “Permitir desta fonte”. Durante a inicialização, conceda integralmente as permissões de Localização (Location) e Dispositivos Próximos (Nearby Devices), essenciais para que o sistema operacional permita a varredura e conexão com pontos de acesso locais.- Dispositivos Apple iOS: No iPhone ou iPad, acesse a App Store, pesquise pelo termo
kuongshune realize a instalação gratuita do aplicativo oficial do fabricante.
Arquitetura de Comunicação e Protocolo de Pacotes Binários
A comunicação entre o smartphone e o ESP32-CAM ocorre sobre um fluxo contínuo de bytes TCP bidirecional na porta 100. Para garantir que nenhum ruído elétrico ou fragmentação de pacotes de rede provoque movimentos erráticos no chassi, o firmware implementa um protocolo estruturado com delimitadores fixos de sincronismo e identificadores de dispositivo.
Cada pacote de comando emitido pelo aplicativo possui a seguinte estrutura binária padronizada:
| Byte do Pacote | Nome do Campo | Valor Hexadecimal | Função Técnica no Protocolo |
|---|---|---|---|
| Byte 0 | Header 1 | 0xFF | Primeiro byte de sincronismo obrigatório da trama (Sync Byte 1) |
| Byte 1 | Header 2 | 0x55 | Segundo byte de sincronismo obrigatório da trama (Sync Byte 2) |
| Byte 2 | Data Length | Variável | Comprimento em bytes dos dados que compõem o corpo da mensagem |
| Bytes 3 a 9 | Header Reservado | 0x00 ... | Parâmetros de contexto e flags de roteamento interno |
| Byte 10 | Device ID | 0x0C / 0x05 / 0x0D | Identificador do subsistema acionado (Motores, LED Flash ou Velocidade) |
| Byte 11 | Sub-comando | 0x00 | Tipo de operação (escrita direta de registrador) |
| Byte 12 | Command Value | 0x00 ... 0xFF | Valor do comando (código da direção, nível de brilho ou valor de PWM) |
Os identificadores de subsistema (Device ID) aceitos pelo decodificador são:
0x0C(Controle dos Motores de Tração):- Valor
0x01: Movimento para Frente (Forward)WheelAct(speed, speed, HIGH, LOW, HIGH, LOW); - Valor
0x02: Marcha a Ré (Backward)WheelAct(speed, speed, LOW, HIGH, LOW, HIGH); - Valor
0x03: Giro à Esquerda (Turn Left)WheelAct(speed, speed, HIGH, LOW, LOW, HIGH); - Valor
0x04: Giro à Direita (Turn Right)WheelAct(speed, speed, LOW, HIGH, HIGH, LOW); - Valor
0x00: Parada Imediata (Stop)WheelAct(0, 0, LOW, LOW, LOW, LOW).
- Valor
0x05(Farol Flash LED):- Valor
0 ... 255: Define o duty cycle no canal PWM do GPIO 4. Valores inferiores a 50 são automaticamente forçados para zero para poupar bateria e evitar aquecimento desnecessário.
- Valor
0x0D(Ajuste Global de Velocidade):- Valor
0 ... 255: Atualiza a variável globalspeed, determinando a potência com que os comandos direcionais serão executados.
- Valor
Temporizador de Segurança (Watchdog de Conexão)
Se o usuário afastar-se do robô e o sinal Wi-Fi for interrompido enquanto o botão de avanço estiver acionado, o robô poderia continuar em movimento até colidir. Para prevenir acidentes, o firmware integra um temporizador de inatividade de 3 segundos (timeoutDuration = 3000). Se nenhum pacote válido for recebido dentro dessa janela temporal ou se a estação cliente desconectar-se do SoftAP, a função de segurança desativa imediatamente os motores através da chamada WheelAct(0, 0, LOW, LOW, LOW, LOW) e envia a trama de parada de emergência Stop[17].
Código-Fonte Completo do Projeto APP (ESP32CAM_L298N_APP.ino)
📦 Bibliotecas desta lição:
WiFi.h,esp_camera.h,soc/soc.h,soc/rtc_cntl_reg.h— todas integradas nativamente ao pacote de placas ESP32 versão 2.0.12.- Os arquivos auxiliares
CameraWebServer.cppeapp_httpd.cppsão os mesmos da Lição 2, adaptados com as rotas de suporte à câmera do aplicativo.
// ============================================================================
// Projeto 3: Servidor TCP e Controle via Aplicativo (ESP32CAM_L298N_APP.ino)
// Fabricante: Kuongshun Electronic | Adaptado para RoboBuilders
// Placa: ESP32-CAM | Câmera OV2640 | Driver L298N | App KUONGSHUN
// ============================================================================
#include <WiFi.h> // Suporte a redes Wi-Fi e pilha TCP/IP
#include "esp_camera.h" // Driver de controle da câmera OV2640
#include "soc/soc.h" // Definições de registradores do ESP32
#include "soc/rtc_cntl_reg.h" // Desativação do brownout reset
// Instancia o servidor de soquete TCP escutando conexões na porta 100
WiFiServer server(100);
// Pacote binário pré-formatado de 17 bytes para comando de parada de emergência
byte Stop[17] = {0xff, 0x55, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00};
// Variáveis globais do analisador sintático de pacotes (parser)
char buffer[52]; // Buffer de armazenamento temporário da trama
byte RX_package[17] = {0}; // Pacote de recepção descompactado
byte dataLen, index_a = 0; // Indicador de tamanho de dados e ponteiro de índice
unsigned char prevc = 0; // Armazena o byte anterior para detectar o cabeçalho 0xFF 0x55
int dataIndex = 0; // Índice do registrador de dados
int LED_mode = 0, LED_val = 0; // Modo e intensidade de brilho do LED Flash
int speed = 225; // Velocidade PWM padrão de inicialização (faixa de 0 a 255)
String sendBuff; // Buffer de transmissão serial/TCP
String Version = "Firmware Version is 0.12.21"; // Versão do firmware embarcado
bool ED_client = true; // Flag de controle de desconexão de cliente
bool WA_en = false; // Flag de habilitação de processamento
bool isStart = false; // Sinalizador de detecção de início válido de pacote
#define gpLED 4 // Pino do LED flash branco de alta intensidade
// Declaração da rotina de inicialização de câmera e rede SoftAP
void CameraWebServer_init();
// Mapeamento dos pinos do L298N compartilhados com o módulo Web
extern int gpLb = 14; // Entrada IN3: Ré direita
extern int gpLf = 13; // Entrada IN4: Frente direita
extern int gpRb = 33; // Entrada IN1: Ré esquerda
extern int gpRf = 15; // Entrada IN2: Frente esquerda
extern int gpLed = 4; // Pino do LED Flash
extern int ENR = 2; // PWM de velocidade direita
extern int ENL = 12; // PWM de velocidade esquerda
bool st = false;
unsigned long lastDataTimes = 0;
// Sub-rotina de acionamento das pontes H e modulação PWM nos motores
void WheelAct(int speed_R, int speed_L, int nLf, int nLb, int nRf, int nRb) {
ledcWrite(ENR, speed_R); // Atualiza duty cycle no canal PWM direito
ledcWrite(ENL, speed_L); // Atualiza duty cycle no canal PWM esquerdo
digitalWrite(gpLf, nLf); // Define nível lógico no avanço esquerdo
digitalWrite(gpLb, nLb); // Define nível lógico no recuo esquerdo
digitalWrite(gpRf, nRf); // Define nível lógico no avanço direito
digitalWrite(gpRb, nRb); // Define nível lógico no recuo direito
}
// Configuração dos pinos dos motores e canais de hardware LEDC
void initMotors() {
pinMode(gpLb, OUTPUT);
pinMode(gpLf, OUTPUT);
pinMode(gpRb, OUTPUT);
pinMode(gpRf, OUTPUT);
pinMode(gpLed, OUTPUT);
pinMode(ENR, OUTPUT);
pinMode(ENL, OUTPUT);
// Configura canais LEDC 2 e 12 a 5 kHz e 8 bits de resolução
ledcSetup(2, 5000, 8);
ledcSetup(12, 5000, 8);
ledcAttachPin(ENR, 2);
ledcAttachPin(ENL, 12);
ledcWrite(ENR, 0); // Inicia parado
ledcWrite(ENL, 0);
digitalWrite(gpLf, LOW);
digitalWrite(gpRb, LOW);
digitalWrite(gpRf, LOW);
digitalWrite(gpLb, LOW);
}
// Funções de acesso ao buffer interno de telemetria
unsigned char readBuffer(int index_r) {
return buffer[index_r];
}
void writeBuffer(int index_w, unsigned char c) {
buffer[index_w] = c;
}
// Decodificador de comandos do aplicativo mobile
void parseData() {
isStart = false; // Reseta a flag de busca de pacote
int device = readBuffer(10);// Byte 10 identifica o subsistema
int val = readBuffer(12);// Byte 12 carrega o parâmetro de comando
switch (device) {
// Caso 0x0C: Comandos direcionais de locomoção
case 0x0C: {
switch (val) {
case 0x01: // Frente (Forward)
WheelAct(speed, speed, HIGH, LOW, HIGH, LOW);
break;
case 0x02: // Ré (Backward)
WheelAct(speed, speed, LOW, HIGH, LOW, HIGH);
break;
case 0x03: // Giro à Esquerda (Turn Left)
WheelAct(speed, speed, HIGH, LOW, LOW, HIGH);
break;
case 0x04: // Giro à Direita (Turn Right)
WheelAct(speed, speed, LOW, HIGH, HIGH, LOW);
break;
case 0x00: // Parada (Stop)
WheelAct(0, 0, LOW, LOW, LOW, LOW);
break;
default:
break;
}
} break;
// Caso 0x05: Ajuste de luminosidade do Farol Flash
case 0x05: {
if (val < 50) val = 0; // Limiar mínimo de corte para evitar brilho residual
ledcWrite(7, val); // Aplica duty cycle no GPIO 4
delay(5);
} break;
// Caso 0x0D: Atualização da velocidade global
case 0x0D: {
speed = val; // Atualiza a potência dos motores
} break;
}
}
void setup() {
// Desativa o circuito detector de brownout
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
Serial.begin(115200);
Serial.setDebugOutput(true);
// Inicializa o servidor web de vídeo e o Ponto de Acesso Wi-Fi KUONGSHUN-AD174
CameraWebServer_init();
// Abre o servidor TCP de comando na porta 100
server.begin();
delay(100);
// Inicializa o hardware dos motores e configura o canal PWM 7 no LED Flash
initMotors();
ledcSetup(7, 5000, 8);
ledcAttachPin(gpLed, 7);
// Pisca o LED Flash 5 vezes confirmando prontidão de rede
for (int i = 0; i < 5; i++) {
ledcWrite(7, 20);
delay(50);
ledcWrite(7, 0);
delay(50);
}
}
// Sub-rotina de recepção, sincronismo e tratamento de pacotes TCP
void RXpack_func() {
WiFiClient client = server.available(); // Verifica se há novo cliente conectado
if (client) {
WA_en = true;
ED_client = true;
unsigned long previousMillis = millis(); // Registra o tempo da conexão
const unsigned long timeoutDuration = 3000; // Watchdog de 3000 ms (3 segundos)
Serial.println("[Cliente Conectado na Porta 100]");
while (client.connected()) {
// Interrompe caso o tempo de inatividade exceda 3 segundos com flag st ativa
if ((millis() - previousMillis) > timeoutDuration && client.available() == 0 && st == true) {
break;
}
// Lê dados disponíveis no canal TCP
if (client.available()) {
previousMillis = millis(); // Reinicia o temporizador do watchdog
unsigned char c = client.read() & 0xff;
Serial.write(c);
st = false;
if (c == 200) st = true;
// Máquina de estados: detecta o delimitador 0xFF seguido de 0x55
if (c == 0x55 && isStart == false) {
if (prevc == 0xff) {
index_a = 1;
isStart = true; // Início de pacote válido confirmado
}
} else {
prevc = c;
if (isStart) {
if (index_a == 2) {
dataLen = c; // Armazena o comprimento dos dados
} else if (index_a > 2) {
dataLen--;
}
writeBuffer(index_a, c); // Grava byte no buffer de comando
}
}
index_a++;
if (index_a > 120) { // Proteção contra overflow de buffer
index_a = 0;
isStart = false;
}
// Quando a totalidade do pacote é recebida, dispara o decodificador
if (isStart && dataLen == 0 && index_a > 3) {
isStart = false;
parseData(); // Interpreta e executa o comando nos motores
index_a = 0;
}
} else if ((millis() - previousMillis) > timeoutDuration && Serial.available() == 0 && st == true) {
// Dispara parada de emergência por perda de telemetria
WheelAct(0, 0, LOW, LOW, LOW, LOW);
}
// Encaminha dados recebidos pela porta serial de volta ao cliente TCP
if (Serial.available()) {
char c = Serial.read();
sendBuff += c;
client.print(sendBuff);
Serial.print(sendBuff);
sendBuff = "";
}
// Monitora periodicamente a quantidade de estações conectadas ao SoftAP
static unsigned long Test_time = 0;
if (millis() - Test_time > 1000) {
Test_time = millis();
if (0 == (WiFi.softAPgetStationNum())) {
Serial.write(Stop, 17);
break; // Nenhum dispositivo associado ao Wi-Fi; encerra
}
}
}
// Finaliza a conexão do cliente e imobiliza o robô
Serial.write(Stop, 17);
client.stop();
Serial.println("[Cliente Desconectado]");
} else {
// Se o cliente foi perdido, garante parada imediata dos motores
if (ED_client == true) {
ED_client = false;
Serial.write(Stop, 17);
WheelAct(0, 0, LOW, LOW, LOW, LOW);
}
}
}
void loop() {
// Executa continuamente a rotina de recepção de pacotes na porta 100
RXpack_func();
}
Guia de Operação e Pareamento com o Aplicativo Mobile
Para operar o robô através do smartphone ou tablet utilizando o aplicativo KUONGSHUN, siga os passos ilustrados:
- Gravação e Inicialização: Grave o firmware
ESP32CAM_L298N_APPna placa ESP32-CAM. Desconecte o cabo USB e ligue as baterias 18650 na chave geral; - Conexão à Rede Wi-Fi: No smartphone, abra as configurações de Wi-Fi, conecte-se à rede
KUONGSHUN-AD174com a senha12345678e confirme para manter a conexão mesmo sem internet;


- Abertura do Aplicativo: Abra o aplicativo KUONGSHUN instalado no dispositivo. Na tela inicial, selecione o idioma desejado (caso prefira, mantenha em inglês);


- Seleção do Modelo: Na galeria de veículos, toque na opção
ESP32-CAM Two-wheel Drive(perfil correspondente aos modelos de tração diferencial com câmera da Kuongshun); - Conexão TCP e Streaming: No canto superior direito da tela de pilotagem, toque no ícone de conexão (símbolo de plugue/antena). O aplicativo abrirá o soquete TCP na porta 100 e requisitará o stream de vídeo. A mensagem
Connected Successfullysurgirá na tela, exibindo imediatamente o vídeo ao vivo capturado pela câmera OV2640;


- Pilotagem em Tempo Real:
- Teclas Direcionais (D-Pad Virtual): Pressione e segure o botão de seta para frente, ré, esquerda ou direita. O botão se iluminará no app e o robô executará o movimento correspondente. Ao retirar o dedo da tela, o botão se apaga e os motores são imobilizados instantaneamente;
- Controles de Vídeo: O botão Play inicia a renderização do vídeo, Pause congela o quadro e o botão de fechar desativa a tela de visualização;
- Slider de Brilho do Farol: Deslize a barra para graduar a intensidade do LED flash no pino GPIO 4;
- Slider de Velocidade: Ajuste a velocidade angular dos motores entre potência mínima e máxima.
⚠️ Solução para “Connected Fail”: Se ao tocar no ícone de conexão surgir o aviso “Connected Fail”, certifique-se de que o smartphone continua associado à rede Wi-Fi
KUONGSHUN-AD174. Alguns sistemas Android desconectam-se automaticamente de redes sem acesso à internet para voltar aos dados móveis; desative os Dados Móveis temporariamente durante os ensaios de laboratório para assegurar tráfego exclusivo pela interface Wi-Fi.
Guia Diagnóstico de Falhas e Solução de Problemas (Troubleshooting)
A operação de sistemas robóticos complexos integrando rádiofrequência, vídeo em alta definição e atuadores indutivos de potência exige uma abordagem sistemática de diagnóstico. A tabela abaixo sintetiza os sintomas mais frequentes observados em bancada, suas causas raízes eletromecânicas e as soluções corretivas imediatas:
| Sintoma Observado | Causa Raiz Mais Provável | Ação Corretiva Recomendada |
|---|---|---|
A rede Wi-Fi KUONGSHUN-AD174 não aparece na busca do smartphone | 1. Tensão insuficiente nas baterias 18650. 2. Chave geral na posição OFF. 3. Jumper regulador de 5V do L298N desconectado. 4. Mau contato no cabo de alimentação de 5V da placa ESP32. | 1. Meça a tensão do pack de baterias com um multímetro; se for inferior a , recarregue as duas células 18650 em carregador externo apropriado. 2. Verifique se o LED de energia do driver L298N acende em vermelho ao ligar a chave geral. 3. Certifique-se de que o jumper de 5V atrás do borne do L298N está inserido. 4. Pressione o botão RST da placa base da ESP32-CAM. |
| A imagem do vídeo aparece de cabeça para baixo ou espelhada horizontalmente | A orientação mecânica do sensor OV2640 varia conforme a revisão de fabricação do módulo (ESP32-CAM-V0.3 vs ESP32-CAM-V2.0). | No arquivo CameraWebServer.cpp, localize as instruções de orientação óptica do sensor (s->set_vflip e s->set_hmirror). Se o seu módulo for a revisão V0.3, altere a chamada de s->set_vflip(s, 1); para s->set_vflip(s, 0);. Para desativar o espelhamento horizontal, altere s->set_hmirror(s, 1); para s->set_hmirror(s, 0); e recarregue o firmware. |
| O aplicativo mobile KUONGSHUN exibe o erro “Connected Fail” | 1. O smartphone desconectou do hotspot Wi-Fi do robô devido ao recurso de “troca inteligente para dados móveis”. 2. Permissões de Localização e Dispositivos Próximos negadas no Android. | 1. Desative temporariamente os Dados Móveis (4G/5G) no celular durante o teste. 2. Acesse Configurações > Aplicativos > KUONGSHUN > Permissões e conceda permissão irrestrita para Localização e Dispositivos Próximos. 3. Reconecte o Wi-Fi em KUONGSHUN-AD174 e toque novamente no ícone de conexão do aplicativo. |
| O robô move-se em sentido contrário ao botão pressionado (ex.: avança quando deveria dar ré) | Inversão física da fiação dos motores nos bornes de saída OUT1/OUT2 ou OUT3/OUT4 do driver L298N. | 1. Se apenas um dos lados estiver invertido (fazendo o robô girar em falso em vez de andar em linha reta), inverta fisicamente a posição dos dois fios correspondentes nos bornes OUT do L298N. 2. Alternativamente, ajuste o mapeamento lógico dos pinos gpLf/gpLb ou gpRf/gpRb diretamente no código-fonte. |
| O robô reinicia espontaneamente ou a conexão Wi-Fi cai assim que os motores aceleram | Queda abrupta de tensão no barramento de alimentação (voltage dip) provocada pela alta corrente de partida indutiva dos 4 motores TT, disparando o reset do ESP32. | 1. Assegure-se de que as baterias 18650 possuem capacidade de corrente adequada e estão com mais de sob carga. 2. Confirme que a instrução WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); está presente no início da função setup().3. Conecte um capacitor eletrolítico de desacoplamento de diretamente entre os pinos 5V e GND da placa ESP32-CAM para absorver transientes de corrente. |
| O streaming de vídeo apresenta congelamentos frequentes ou alta latência (atraso) | 1. Resolução de imagem configurada em nível muito elevado para a banda de rádio local. 2. Conexão do pigtail IPEX da antena externa frouxa ou desconectada. | 1. Reduza a resolução de captura para QVGA () ou VGA () na interface web ou via s->set_framesize(s, FRAMESIZE_QVGA).2. Verifique o travamento mecânico do conector IPEX miniatura na placa ESP32-CAM e certifique-se de que a antena de 2,4 GHz externa esteja rosqueada com firmeza. |
Erro de compilação na Arduino IDE: 'ledcSetup' was not declared in this scope | O pacote de placas ESP32 instalado no Gerenciador de Placas está na série 3.x (onde a API LEDC antiga foi extinta). | Acesse Ferramentas > Placa > Gerenciador de Placas, busque por esp32 e faça o downgrade obrigatório para a versão oficial pinada 2.0.12, ou execute o instalador offline esp32_package_2.0.12_arduinome.exe fornecido no kit. |
Diagnóstico Físico de Revisões da Câmera ESP32-CAM (V0.3 vs V2.0)
Durante o ciclo de vida do kit AD174, a Kuongshun adotou duas revisões principais do circuito impresso da placa controladora ESP32-CAM:


- Revisão ESP32-CAM-V0.3: Utiliza montagem de sensor invertida mecanicamente em . Para essa revisão, o arquivo
CameraWebServer.cppdeve manters->set_vflip(s, 0);para que o teto da sala não apareça na parte inferior da tela. - Revisão ESP32-CAM-V2.0: Possui o sensor soldado com orientação física direta. Requer a instrução
s->set_vflip(s, 1);ativada por software para compensação de perspectiva da torre acrílica do chassi.
Ajuste de Resolução e Latência de Vídeo
Para aplicações que priorizem a taxa de atualização contínua de quadros por segundo (FPS) sobre a nitidez estática, o projetista pode fixar a resolução diretamente no momento da inicialização do sensor no arquivo CameraWebServer.cpp:
// Opção 1: Resolução QVGA (320x240 pixels) - Recomendada para pilotagem rápida de baixa latência
s->set_framesize(s, FRAMESIZE_QVGA); // ~25 a 30 FPS estáveis
// Opção 2: Resolução VGA (640x480 pixels) - Equilíbrio ótimo entre definição e taxa de atualização
// s->set_framesize(s, FRAMESIZE_VGA); // ~15 a 20 FPS
// Opção 3: Resolução SVGA (800x600 pixels) - Alta nitidez, recomendada para inspeção estática detalhada
// s->set_framesize(s, FRAMESIZE_SVGA); // ~8 a 12 FPS
💡 Dica de engenharia: Quanto maior a resolução configurada, maior é o volume de bytes que o encoder JPEG precisa transferir pela memória PSRAM e pelo buffer do socket TCP. Em ambientes com interferência severa de outras redes Wi-Fi na faixa de 2,4 GHz, a resolução QVGA garante resposta imediata aos comandos do D-pad virtual, evitando atrasos que poderiam causar colisões do robô.
Solução de problemas
Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Kit Robô Avançado 4wd Camera Tutoriais Esp32 Wifi App RB2056 AD174 – Curso 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.