Kit Robô Inteligente 4WD Completo AD118

Introdução
Este curso profissional apresenta uma formação técnica completa, progressiva e aprofundada em robótica móvel, cinemática de veículos terrestres não tripulados (AGVs / UGVs) e sistemas embarcados utilizando a plataforma microcontrolada Arduino Uno R3 e o Kit Robô Inteligente 4WD Completo AD118. Ao longo de módulos estruturados, são explorados desde a fundamentação mecânica e elétrica do chassi de acrílico duplo com quatro motores de tração independente (Four-Wheel Drive) até o desenvolvimento de algoritmos avançados de navegação autônoma, teleoperação sem fio via Bluetooth Low Energy (BLE), decodificação de pacotes infravermelhos em tempo real e fusão de sensores ópticos e ultrassônicos.
Projetado sob rigorosos padrões de engenharia mecatrônica, este material foi elaborado para capacitar estudantes, hobbistas, técnicos e engenheiros no domínio de pontes H de potência, modulação por largura de pulso (PWM — Pulse Width Modulation), protocolos de comunicação assíncrona (UART), filtragem de ruídos em sinais acústicos e infravermelhos e arquitetura de firmware concorrente com Máquinas de Estados Finitos (FSM).
O que você vai aprender:
- Compreender a cinemática diferencial e de deslizamento lateral (Skid Steering) de robôs móveis com 4 rodas de tração independente
- Realizar a montagem estrutural mecânica precisa do chassi de acrílico duplo, caixas de redução e suportes pan-tilt
- Dominar a integração elétrica e de potência utilizando a placa de expansão Sensor Shield V5.0 e a Ponte H Dupla L298N
- Implementar controle de torque, velocidade e frenagem regenerativa via sinais PWM analógicos
- Estabelecer comunicação sem fio bidirecional via transceptor Bluetooth BLE HC-08 e protocolo serial UART a 9600 bps
- Decodificar pulsos infravermelhos modulados a 38 kHz no protocolo NEC com controle remoto de 21 teclas
- Projetar sistemas de sensoriamento espacial com transdutores ultrassônicos HC-SR04 montados em servomotores angulares SG90
- Programar robôs seguidores de linha autônomos com matriz óptica reflexiva de 3 canais TCRT5000 e condicionamento LM393
- Desenvolver uma arquitetura de software unificada e escalável com máquina de estados finitos hierárquica e rotinas não-bloqueantes com
millis()
Material utilizado: Kit Robô Inteligente 4WD Completo AD118
Visão Geral da Arquitetura de Hardware e Kit AD118
O Kit Robô Inteligente 4WD AD118 é uma plataforma robótica educacional de alto nível baseada no microcontrolador ATmega328P (Arduino Uno R3). A estrutura física adota um chassi de acrílico duplo transparente de 3 mm com furação padrão para fixação rígida de atuadores, placas lógicas, baterias de lítio e módulos de sensoriamento. A tração integral é realizada por quatro motores DC com caixa de redução interna 1:48, permitindo manobras rápidas de translação, curvas suaves e rotação em torno do próprio eixo central (Zero-Radius Pivot Turn).
Especificações Técnicas do Microcontrolador Arduino Uno R3
| Parâmetro de Engenharia | Especificação Técnica | Observações de Operação |
|---|---|---|
| Microcontrolador Principal | ATmega328P (8-bit AVR RISC) | Arquitetura Harvard modificada com execução de 1 ciclo por instrução |
| Tensão Lógica de Operação | 5,0 VDC | Nível TTL padrão de entrada/saída |
| Tensão de Alimentação do Sistema (VIN / Jack) | 7,4 V a 8,4 VDC (2x Baterias 18650) | Alimentado através da saída regulada do L298N ou barramento VIN |
| Pinos de Entrada/Saída Digital (GPIO) | 14 pinos (D0 a D13) | 6 pinos suportam PWM nativo de 8 bits por hardware (D3, D5, D6, D9, D10, D11) |
| Pinos de Entrada Analógica | 6 canais (A0 a A5) | Resolução de 10 bits (0 a 1023 passos com VREF = 5V) |
| Corrente Máxima por Pino de I/O | 20 mA (típico), 40 mA (limite absoluto) | Barramento total limitado a 200 mA |
| Memória Flash de Programa | 32 KB | 0,5 KB ocupados pelo bootloader Optiboot |
| Memória SRAM de Dados Voláteis | 2 KB | Armazenamento dinâmico de variáveis e buffers seriais |
| Memória EEPROM Não-Volátil | 1 KB | Armazenamento de parâmetros de calibração |
| Frequência de Clock do Núcleo | 16 MHz (±0,5%) | Oscilador a cristal externo de alta estabilidade |
| Interface USB-Serial | Conversor CH340G / ATmega16U2 | Comunicação UART assíncrona full-duplex com PC e módulos |
Especificações dos Módulos, Atuadores e Sensores do Robô
| Subsistema / Módulo | Circuito Integrado / Componente | Faixa de Operação | Função no Sistema Robótico |
|---|---|---|---|
| Driver de Potência dos Motores | Circuito Integrado Ponte H Dupla L298N | 5V a 35V / 2A por canal (pico 3A) | Controle bidirecional de sentido e velocidade PWM dos 4 motores DC |
| Motores de Tração (4 unidades) | Motor DC TT com caixa de redução 1:48 | 3V a 6V DC (Torque 0,8 kg·cm a 4,5V) | Acionamento das 4 rodas de borracha com alta aderência |
| Placa de Expansão de E/S | Arduino Sensor Shield V5.0 | 5V DC (com barramento de alimentação externa) | Roteamento facilitado dos pinos GPIO em padrão Signal-VCC-GND (SVG) |
| Transceptor Bluetooth Sem Fio | Módulo HC-08 BLE (Chip CC2540/CC2541) | 3,3V a 5V / UART 9600 bps | Comunicação sem fio teleoperada com smartphone / aplicativo mobile |
| Receptor de Infravermelho | Módulo Sensor AX-1838HS (38 kHz) | 2,7V a 5,5V / Filtro de luz visível | Recepção e demodulação de comandos do controle remoto NEC |
| Sensor de Distância Ultrassônico | Módulo HC-SR04 (Transdutor Piezoelétrico) | 5V DC / Alcance de 2 cm a 400 cm (15° de abertura) | Medição telemétrica de obstáculos por eco acústico de 40 kHz |
| Mecanismo Pan-Tilt de Varredura | Micro Servomotor Analógico SG90 de 9g | 4,8V a 6,0V / Curso angular de 0° a 180° | Rotação do sensor ultrassônico para varredura angular frontal e lateral |
| Módulo Seguidor de Linha (3 canais) | Sensores Ópticos Reflexivos TCRT5000 + LM393 | 3,3V a 5V / Distância focal de 1 mm a 25 mm | Detecção de contraste óptico (pista preta / fundo reflexivo claro) |
| Fonte de Alimentação Primária | Suporte Duplo para Baterias de Íon de Lítio 18650 | 7,4V nominal (8,4V em carga plena) | Fornecimento de energia com alta densidade de corrente para motores e lógica |
Inventário Completo de Componentes (Packing List do Kit AD118)
O Kit Robô Inteligente 4WD AD118 acompanha todos os componentes mecânicos, fixadores metálicos, placas eletrônicas e cabeamento necessários para a construção completa do sistema:
- 1x Placa microcontroladora compatível com Arduino Uno R3 (ATmega328P + CH340)
- 1x Placa de expansão de entradas e saídas Arduino Sensor Shield V5.0
- 1x Módulo Driver de Motor Ponte H Dupla L298N com dissipador de calor em alumínio anodizado
- 1x Módulo Transceptor Bluetooth Low Energy HC-08 (BLE V4.0)
- 1x Módulo Sensor Receptor Infravermelho integrado AX-1838HS (38 kHz)
- 1x Controle remoto infravermelho de 21 teclas (com bateria CR2025/CR2032 inclusa)
- 1x Módulo Sensor Telemétrico Ultrassônico de Distância HC-SR04
- 1x Micro Servomotor SG90 de 9g com acessórios de fixação e cruzetas
- 3x Módulos Sensores Ópticos Reflexivos Seguidores de Linha TCRT5000 com comparador LM393
- 4x Motores DC TT com caixa de redução interna 1:48 e fios pré-soldados
- 4x Rodas de borracha de alta tração e diâmetro de 65 mm com cubo de acoplamento chanfrado tipo D
- 1x Chassi estrutural inferior em acrílico cortado a laser com película protetora
- 1x Chassi estrutural superior em acrílico cortado a laser com furação para servo e bateria
- 1x Conjunto de suporte de acrílico para montagem do servo pan-tilt e sensor ultrassônico
- 4x Discos encoders ópticos de velocidade com 20 fendas
- 8x Suportes metálicos / acrílicos de fixação rápida para os motores TT no chassi
- 1x Suporte para 2 baterias de lítio 18650 com plug conector e chave liga/desliga
- 6x Espaçadores sextavados de latão M3 × 30 mm (macho-fêmea e fêmea-fêmea) para união dos chassis
- 4x Espaçadores de latão M3 × 10 mm / M3 × 15 mm para elevação das placas
- 1x Conjunto de parafusos mecânicos M3 (comprimentos variados: 8mm, 10mm, 30mm) e porcas sextavadas M3
- 1x Conjunto de parafusos finos autorroscantes e parafusos para montagem do servo SG90
- 1x Cabo de comunicação e programação USB Tipo A para Tipo B (50 cm)
- 20x Cabos jumper fêmea-fêmea de 20 cm para interconexão dos sensores e atuadores
- 10x Cabos jumper macho-fêmea de 20 cm
- 1x Rolo de fita isolante preta de alta aderência para montagem de pista de testes
- 1x Chave de fenda / Philips para montagem mecânica
📦 Somatória Geral do Kit: 84 componentes individuais (englobando elementos de estrutura mecânica, caixas de redução, placas de circuito impresso, cablagem, sensores e fixadores).
Módulo 0 — Montagem Mecânica Passo a Passo e Arquitetura Elétrica
Lição 0.1: Montagem Estrutural Mecânica do Robô 4WD
A montagem do Kit Robô Inteligente 4WD AD118 deve ser realizada com precisão e atenção aos torques de aperto para evitar tensões mecânicas excessivas sobre as placas de acrílico. Antes de iniciar, remova a película protetora de papel kraft de todas as peças acrílicas.
Passos 1 a 4: Fixação dos Motores TT e Rodas no Chassi Inferior
- Instalação dos Suportes dos Motores: Posicione os 4 motores DC TT no chassi inferior de acrílico, alinhando os eixos de tração para o lado externo. Utilize os suportes de fixação em conjunto com os parafusos longos M3 e porcas sextavadas para prender firmemente cada motor.
- Instalação dos Discos Encoders: Encaixe os discos perfurados de encoder nos eixos traseiros dos quatro motores TT.
Passos 5 a 8: Montagem do Módulo Ponte H L298N e Sensores de Linha
- Fixação do Driver L298N: Fixe o módulo driver Ponte H L298N na parte superior do chassi inferior utilizando parafusos M3 e porcas, com os bornes de saída de potência voltados para as laterais do veículo.
- Instalação dos 3 Sensores de Linha: Fixe os três módulos ópticos TCRT5000 na extremidade dianteira da face inferior do chassi acrílico, alinhando os emissores infravermelhos voltados diretamente para o solo (a uma distância focal recomendada de 5 mm a 12 mm da pista).
Passos 9 a 14: Montagem do Suporte Pan-Tilt, Servomotor e Sensor Ultrassônico
- Montagem do Suporte do Servo SG90: Encaixe o micro servomotor SG90 no suporte de acrílico frontal superior e trave com os parafusos autorroscantes inclusos.
- Fixação do Sensor HC-SR04: Encaixe o sensor ultrassônico HC-SR04 no suporte facial de acrílico correspondente e una a cruzeta do servo motor à haste de rotação para permitir varredura angular livre de 0° a 180°.
Passos 15 a 20: União dos Chassis, Shield V5.0, Bateria e Rodas
- Instalação do Arduino Uno e Sensor Shield V5.0: Fixe a placa Arduino Uno R3 no chassi superior com parafusos M3 e acople o Sensor Shield V5.0 firmemente sobre seus barramentos de pinos fêmea.
- Instalação do Suporte de Bateria 18650: Posicione o suporte de baterias na traseira do chassi superior para equilibrar o centro de gravidade do robô.
- União Estrutural e Acoplamento das Rodas: Una os dois chassis através dos 6 espaçadores de latão M3 × 30 mm, encaixe as quatro rodas de borracha nos eixos chanfrados dos motores e fixe o módulo receptor IR e Bluetooth HC-08.
Lição 0.3: Configuração da IDE Arduino, Instalação de Drivers USB e Gravação
Antes de testar a movimentação autônoma do robô, o ambiente de compilação da IDE Arduino e os drivers de comunicação USB do microcontrolador devem ser corretamente configurados no computador.
Toolchain oficial pinada deste curso (versões usadas na bancada)
A documentação do fabricante KUONGSHUN (pastas Lesson 0 a Lesson 5, PDFs de 2019, códigos forward_back, AUTO_GO, bluetooth_car, Infrared_remote_control_car, Obstacle_Avoidance_Car, Line_tracking_car e APK KUONGSHUN BLE Tool.apk) foi escrita para a linha Arduino IDE 1.8 com núcleo AVR clássico. Para reproduzir os 11 sketches do pacote sem erro de compilação, fixe exatamente estas versões antes do primeiro upload:
| Ferramenta / Pacote | Versão usada no curso | Onde obter (oficial) | Observação de bancada |
|---|---|---|---|
| Arduino IDE | 1.8.19 (série 1.8) | arduino.cc — Software 1.8.19 | Última 1.8 estável; 100% compatível com IRremote 2.0.1 e AVR. IDE 2.x compila, mas muda telas e mensagens — o passo a passo abaixo usa a 1.8. |
| Arduino AVR Boards (núcleo) | 1.8.6 | Ferramentas > Placa > Gerenciador de Placas… → buscar Arduino AVR Boards → selecionar 1.8.6 → Instalar | Define digitalWrite, analogWrite, pulseIn, Serial do ATmega328P. Núcleo errado é a causa nº 1 de not declared in scope. |
| Driver USB-serial CH340 | 3.8 (2023) | wch.cn — CH341SER | A placa do kit usa conversor CH340G. Sem ele, a porta COM não aparece. Cabo precisa ser de dados, não só de carga. |
Biblioteca IRremote | 2.0.1 (shirriff) — OBRIGATÓRIA | ZIP IRremote.zip dentro da pasta Lesson 3 do fabricante | API antiga (decode(&results), results.value, códigos decimais como 16736925). NUNCA instalar a latest (3.x/4.x quebra 100% dos sketches IR do kit). |
Biblioteca Servo | Embutida na IDE 1.8.19 | Nenhum download — Arquivo > Exemplos > Servo | Controla o SG90 no pino D3. Nada a instalar. |
| APP de pilotagem | KUONGSHUN BLE Tool.apk (pasta Lesson 2 do fabricante) | APK dentro do pacote do kit | App Android do fabricante; pareia com o HC-08 e envia f/b/l/r/s/a. iOS usa app BLE genérico. |
⚠️ Atenção: se você já tem
IRremote3.x ou 4.x instalada, desinstale antes (Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→IRremote→Remover), instale a 2.0.1 via ZIP (Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP…→ apontar para oIRremote.zipdaLesson 3), feche e reabra a IDE. Misturar majors causaerror: 'class IRrecv' has no member named 'decodedIRData'ou o inverso ('decode_results' does not name a type).
Tabela-mestre de bibliotecas do curso
Consolidada de todos os #include dos 11 sketches do fabricante. Cada lição referencia esta tabela no seu box > 📦 **Bibliotecas desta lição:**.
Biblioteca (#include) | Buscar no Gerenciador | Versão usada no curso | Download ZIP (espelho oficial) | Lições que usam |
|---|---|---|---|---|
IRremote.h | IRremote por shirriff — fixar 2.0.1, nunca latest | 2.0.1 | ZIP IRremote.zip da pasta Lesson 3 do fabricante; espelho oficial shirriff/Arduino-IRremote (tag 2.0.1) | 3.1 (infrared_Blink), 3.2 (Infrared_remote_control_car), Apêndice SmartCar_Core |
Servo.h | Embutida — nada a instalar | IDE 1.8.19 | — | 4.1 (Servo_debug), 4.2 (Obstacle_Avoidance_Car), Apêndice SmartCar_Core |
| (nenhuma — nativo) | — | Núcleo AVR 1.8.6 | — | 1.1 (forward_back), 1.2 (left_wheel_rotation), 1.3 (right_wheel_rotation), 1.4 (AUTO_GO), 1.5 (speed_control), 2.1 (bluetooth_blink), 2.2 (bluetooth_car), 5 (Line_tracking_car: usa só digitalRead/analogWrite/Serial) |
📦 Bibliotecas desta lição: nenhuma — preparação de ambiente; se o próximo sketch pedir
IRremoteouServo, volte a esta tabela-mestre e confira a versão antes de compilar.
Passo a Passo para Instalação e Primeiro Upload:
- Instalar a IDE 1.8.19: baixe no site oficial, instale com a opção de drivers marcada. Abra e confira em
Ajuda > Sobre o Arduinoque exibe1.8.19. - Fixar o núcleo AVR 1.8.6:
Ferramentas > Placa > Gerenciador de Placas…→Arduino AVR Boards→1.8.6→Instalar. Selecione depoisFerramentas > Placa > Arduino Uno. - Instalar o driver CH340: execute o
CH341SER.EXEoficial, conecte o cabo USB de dados tipo A/B na Uno. No Gerenciador de Dispositivos do Windows deve aparecerUSB-SERIAL CH340 (COM[X]). - Instalar as bibliotecas pela tabela-mestre:
IRremote2.0.1 via ZIP daLesson 3;Servojá vem na IDE — confira emArquivo > Exemplos > Servo > Sweepque compila (✓Verificar) semNo such file or directory. - Conexão Física: conecte o cabo USB tipo A/B da placa à porta USB do computador, com o robô desligado (chave OFF) e o jumper do Bluetooth fora de D0/D1.
- Seleção de Placa e Porta:
Ferramentas → Placa → Arduino UnoeFerramentas → Porta → COM[X](a COM do CH340). - Primeiro upload de validação: abra
Arquivo > Exemplos > 01.Basics > Blink, clique em Carregar. O LED L (D13) deve piscar a 1 Hz. Se falhar comstk500_recv(), volte ao passo 5 (Bluetooth fora de D0/D1) e confira cabo de dados vs. só-carga. - Monitor Serial:
Ferramentas > Monitor Serial, fixar 9600 baud eAmbos NL & CR. Todo sketch do kit usaSerial.begin(9600)— baud errado exibe lixo.
💡 Dica: grave o
Blinkantes de qualquer sketch do robô. Ele prova que IDE + núcleo + driver + cabo + porta estão íntegros. Só então passe aoforward_back(Lição 1.1) com as rodas livres (robô suspenso) e a chave do suporte 18650 em OFF durante o upload, ligando-a só após desconectar o USB.
Lição 0.2: Tabela Mestra de Pinagem e Interconexão Elétrica
Para garantir o perfeito funcionamento de todos os subsistemas sem conflitos de portas digitais ou barramentos analógicos, a conexão elétrica entre o Arduino Uno R3 (através do Sensor Shield V5.0), o driver L298N, os sensores e atuadores deve seguir rigorosamente a matriz padronizada de fiação:
Matriz Completa de Pinagem do Sistema Robótico AD118
| Porta Arduino / Shield V5.0 | Tipo de Sinal | Módulo ou Atuador Conectado | Pino de Destino no Dispositivo | Função e Observações Técnicas |
|---|---|---|---|---|
| D0 (RX) | Entrada Digital / UART | Módulo Bluetooth HC-08 | TXD | Recepção serial de dados do smartphone (9600 baud) |
| D1 (TX) | Saída Digital / UART | Módulo Bluetooth HC-08 | RXD | Transmissão serial de telemetria para o smartphone |
| D2 (S2) | Entrada Digital | Seguidor de Linha #3 (Esquerdo) | OUT / D0 | Leitura digital do sensor infravermelho esquerdo |
| D3 (S3) | Saída Digital / PWM | Micro Servomotor SG90 | Sinal (Fio Laranja / Amarelo) | Controle angular de 0° a 180° via modulação por pulsos de 50 Hz |
| D4 (S4) | Entrada Digital | Seguidor de Linha #2 (Centro) | OUT / D0 | Leitura digital do sensor infravermelho central de pista |
| D5 (S5) | Saída Digital / PWM | Driver Ponte H L298N | ENA (Enable A) | Controle de velocidade PWM dos Motores Direitos (0 a 255) |
| D6 (S6) | Saída Digital / PWM | Driver Ponte H L298N | ENB (Enable B) | Controle de velocidade PWM dos Motores Esquerdos (0 a 255) |
| D7 (S7) | Saída Digital | Driver Ponte H L298N | IN1 | Controle de direção do Motor Direito (Canal A) |
| D8 (S8) | Saída Digital | Driver Ponte H L298N | IN2 | Controle de direção do Motor Direito (Canal A) |
| D9 (S9) | Saída Digital | Driver Ponte H L298N | IN3 | Controle de direção do Motor Esquerdo (Canal B) |
| D10 (S10) | Entrada Digital | Seguidor de Linha #1 (Direito) | OUT / D0 | Leitura digital do sensor infravermelho direito |
| D11 (S11) | Saída Digital | Driver Ponte H L298N | IN4 | Controle de direção do Motor Esquerdo (Canal B) |
| D12 (S12) | Entrada Digital | Módulo Receptor IR AX-1838HS | DAT / S (Sinal) | Recepção dos pulsos de onda portadora demodulada em 38 kHz |
| D13 | Saída Digital | LED Onboard da Placa Uno | Anodo LED | Indicador de status de firmware e depuração visual |
| A4 | Entrada Digital | Sensor Ultrassônico HC-SR04 | ECHO | Recepção do pulso de eco proporcional à distância |
| A5 | Saída Digital | Sensor Ultrassônico HC-SR04 | TRIG | Disparo do trem de 8 pulsos ultrassônicos de 40 kHz |
| 5V / VCC | Alimentação Lógica | Barramentos VCC dos Módulos | VCC / V+ | Linha de 5,0 V regulada para sensores e microcontrolador |
| GND | Referência / Terra | Barramentos GND dos Módulos | GND / G / - | Potencial de referência comum para lógica e potência |
Conexão de Potência dos Motores no Driver L298N
- Borne OUT1 & OUT2 (Canal Direito): Conectados em paralelo aos cabos dos 2 Motores Direitos (Frente Direito + Traseiro Direito). Fio vermelho em OUT1 e fio preto em OUT2.
- Borne OUT3 & OUT4 (Canal Esquerdo): Conectados em paralelo aos cabos dos 2 Motores Esquerdos (Frente Esquerdo + Traseiro Esquerdo). Fio preto em OUT3 e fio vermelho em OUT4.
- Borne VCC (+12V Power In): Conectado ao polo positivo (+7,4V / +8,4V) do suporte de baterias 18650 através da chave geral.
- Borne GND (Power Ground): Conectado ao polo negativo (-) do suporte de baterias e interligado ao pino GND do Arduino Uno.
- Borne +5V (Saída Regulada 5V LDO): Fornece alimentação estável de 5V para o Sensor Shield e o microcontrolador quando o jumper regulador 5V do L298N estiver fechado.
[!IMPORTANT] O pino GND da bateria, o GND do módulo driver L298N e o GND do Arduino Uno / Sensor Shield V5.0 devem estar obrigatoriamente interligados. A ausência de um plano de terra comum causa oscilações lógicas severas e impede o acionamento correto dos transistores da ponte H.
Módulo 1 — Cinemática e Controle de Tração Diferencial 4WD
Neste módulo, você compreenderá os fundamentos físicos e matemáticos da tração diferencial em veículos robóticos de quatro rodas (Skid-Steering Kinematics), a operação em nível de comutação da Ponte H L298N e o controle de velocidade proporcional por modulação PWM.
Fundamentação Teórica da Ponte H Dupla L298N
A ponte H é uma topologia de circuito eletrônico de chaveamento composta por quatro chaves semicondutoras de potência dispostas em formato de ‘H’, permitindo a aplicação de uma diferença de potencial reversível sobre os enrolamentos indutivos dos motores de corrente contínua:
- Sentido Horário (Avanço): As chaves e são saturadas (fechadas), enquanto e permanecem em corte (abertas). A corrente flui do terminal positivo para o negativo através do enrolamento do motor.
- Sentido Anti-Horário (Recuo): As chaves e são saturadas, enquanto e permanecem abertas. O sentido da corrente é invertido, invertendo instantaneamente o vetor de densidade de fluxo magnético no rotor e o torque eletromecânico gerado.
- Frenagem Eletrodinâmica: As chaves superiores ( e ) ou inferiores ( e ) são fechadas simultaneamente, curto-circuitando os terminais do motor e dissipando a energia cinética gerada pela força contra-eletromotriz (FCEM) através dos diodos de recirculação (flyback).
Tabela Lógica de Comutação da Ponte H
| ENA / ENB | IN1 / IN3 | IN2 / IN4 | Estado do Motor | Comportamento Cinemático |
|---|---|---|---|---|
| 0 (LOW) | X (Indiferente) | X (Indiferente) | Desativado (Coast) | Motor desenergizado, gira livre por inércia |
| 1 (HIGH / PWM) | 1 (HIGH) | 0 (LOW) | Rotação Direta (Forward) | Eixo gira no sentido de avanço à velocidade definida pelo PWM |
| 1 (HIGH / PWM) | 0 (LOW) | 1 (HIGH) | Rotação Reversa (Reverse) | Eixo gira no sentido de recuo à velocidade definida pelo PWM |
| 1 (HIGH) | 1 (HIGH) | 1 (HIGH) | Freio Ativo (Brake) | Terminais em curto-circuito lógico, frenagem rápida |
| 1 (HIGH) | 0 (LOW) | 0 (LOW) | Freio Ativo (Brake) | Terminais no potencial de terra, frenagem rápida |
Modulação por Largura de Pulso (PWM) e Cálculo de Tensão Eficaz
Para controlar a velocidade angular dos motores sem dissipar calor excessivo em transistores lineares, o microcontrolador ATmega328P modula a largura de pulso de uma onda quadrada de frequência fixa ( nos pinos D5 e D6 do Timer0) variando a razão cíclica (Duty Cycle ). A tensão média eficaz () entregue à carga é expressa por:
Onde:
- é o valor inteiro de 8 bits fornecido à função
analogWrite(pino, Duty), variando no intervalo fechado de (, motor imobilizado) a (, tensão plena de ). - é a tensão nominal do barramento de potência suprido pelas células de íons de lítio 18650 ( a ).
Modelagem Cinemática de Robôs Móveis 4WD (Skid-Steering Kinematics)
Diferente de veículos convencionais que utilizam direção geométrica de Ackermann (esterçamento angular das rodas dianteiras) ou robôs diferenciais clássicos com duas rodas e um rodízio esférico (caster), o Kit Robô AD118 emprega uma arquitetura de tração integral em quatro rodas por deslizamento lateral (SSMR — Skid-Steer Mobile Robot).
Como as quatro rodas são mecanicamente paralelas e não possuem juntas de esterçamento, qualquer rotação ou curva é executada impondo velocidades tangenciais distintas entre os pares de rodas esquerdas e direitas, forçando um escorregamento transversal controlado (tyre scrubbing) contra o piso.
1. Definição dos Sistemas de Coordenadas (Frames de Referência)
Para descrever a cinemática do robô no plano bidimensional , definimos dois referenciais ortogonais:
- Referencial Global / Inercial : Fixado no plano de navegação (estático no ambiente).
- Referencial Local / Robô : Fixado rigidamente no centro geométrico e de massa do chassi robótico, onde o eixo aponta na direção frontal de avanço e o eixo aponta lateralmente para o lado esquerdo.
O vetor de postura (estado cinemático) do robô no referencial global é definido pela tripla:
Onde:
- : Posição cartesiana do centro do robô em metros ().
- : Ângulo de orientação (heading / yaw) em relação ao eixo global, medido em radianos ().
2. Parâmetros Físicos e Geométricos do Kit AD118
Os cálculos cinemáticos do robô dependem das seguintes constantes construtivas dimensionais:
| Parâmetro Geométrico | Símbolo | Valor no Kit AD118 | Descrição Construtiva |
|---|---|---|---|
| Raio Nominal das Rodas | Diâmetro externo do pneu emborrachado | ||
| Bitola Lateral (Track Gauge) | Distância transversal entre os centros de contato das rodas esquerda e direita | ||
| Distância entre Eixos (Wheelbase) | Distância longitudinal entre os centros dos eixos dianteiro e traseiro | ||
| Relação de Redução da Caixa de Engrenagens | Relação de engrenamento mecânico dos motores DC amarelos | ||
| Velocidade Angular Máxima do Motor | Rotação do eixo de saída em com caixa 1:48 |
3. Cinemática Direta no Referencial Local (Forward Kinematics)
Sejam e as velocidades angulares das rodas esquerdas e direitas, respectivamente (). As velocidades lineares tangenciais correspondentes de cada lado do veículo são:
A velocidade linear longitudinal de translação do robô () e a velocidade angular de guinada () no referencial local da estrutura são obtidas pela média e pela diferença diferencial das velocidades de cada esteira/roda:
Em notação matricial com a Matriz Jacobiana Cinemática Direta:
4. Transformação de Coordenadas para o Referencial Global Inercial
Para mapear as velocidades do referencial móvel para o referencial de navegação , aplica-se a matriz de rotação :
Expandindo em termos das velocidades angulares individuais das rodas ():
5. Cinemática Inversa (Inverse Kinematics)
A cinemática inversa calcula as velocidades lineares () e angulares () que o microcontrolador deve exigir de cada conjunto de motores para que o robô atinja uma velocidade de translação linear () e uma taxa de giro () arbitrárias:
6. Centro Instantâneo de Curvatura (ICC) e Regimes de Manobra
Durante qualquer movimento sobre o plano, o robô descreve uma trajetória circular instantânea em torno de um ponto geométrico denominado Centro Instantâneo de Curvatura (ICC — Instantaneous Center of Curvature).
O raio de curvatura da trajetória (), medido do centro do robô ao ICC, é dado por:
As coordenadas globais do ponto ICC no espaço são calculadas por:
Analisando a equação do raio , identificamos três regimes cinemáticos fundamentais executados pelo Kit AD118:
- Translação Retilínea Pura:
- Condição (velocidades iguais nos dois lados):
- Resultado: e . O robô desloca-se em linha reta com velocidade .
- Giro Pivot em Torno do Eixo Central (Zero-Radius Turn):
- Condição (velocidades opostas nos dois lados):
- Resultado: e . O ICC coincide perfeitamente com o centro geométrico do robô. O veículo gira no próprio local com velocidade angular máxima:
- Curva Diferencial com Raio Finito :
- Condição: (ambos com mesmo sinal)
- Resultado: O robô executa trajetória curvilínea suave. O lado com maior velocidade orbita no raio externo:
E o lado mais lento percorre o raio interno:
7. Dinâmica de Deslizamento Lateral (Skid-Steering e Bitola Efetiva)
Nos robôs móveis 4WD com quatro rodas coplanares, as rodas dianteiras e traseiras de um mesmo lado giram na mesma velocidade (). Como a distância longitudinal entre eixos () não é nula, as rodas obrigatoriamente sofrem escorregamento lateral (skid) ao realizar rotações.
As forças de atrito transversal geram um conjugado resistente ao giro proporcional ao coeficiente de atrito pneu-solo () e à massa total do robô ():
Para compensar esse efeito de dissipação por atrito na modelagem cinemática sem recorrer a modelos dinâmicos complexos, a literatura de robótica móvel introduz o conceito de Bitola Efetiva ():
Onde é o coeficiente empírico de derrapagem. Em pisos lisos como cerâmica ou madeira polida, a . Em carpetes de alto atrito, a , exigindo maior torque dos motores para vencer a resistência ao giro.
8. Mapeamento de Velocidade Cinemática para Registradores PWM no Arduino
O firmware do microcontrolador ATmega328P mapeia as velocidades lineares desejadas e para os valores inteiros do conversor PWM de 8 bits (0 a 255).
Devido ao atrito estático dos mancais e das engrenagens plásticas da caixa de redução 1:48, os motores DC não entram em movimento até que a tensão aplicada supere a tensão de zona morta (deadband), correspondente a . O algoritmo de conversão linear proporcional implementado no microcontrolador é expresso por:
Onde :
Lição 1.1: Movimentação Básica e Teste Unitário dos Motores
Este primeiro programa de validação (forward_back da Lesson 1 do fabricante) executa uma rotina contínua de movimentação, acionando o robô para frente por 2 segundos e para trás por 2 segundos, com parada eletrodinâmica entre inversões para aliviar as engrenagens 1:48.
📦 Bibliotecas desta lição: nenhuma — o código usa
digitalWrite(),analogWrite(),delay()epinMode()nativos do núcleo AVR 1.8.6, sem biblioteca externa. Se dernot declared in scope, reinstale o núcleo pela tabela-mestre da Lição 0.3.
Código-Fonte Completo Comentado: forward_back.ino
💡 Dica: primeiro upload com o robô suspenso (rodas livres, sem contato com o piso) e baterias em OFF. Resultado esperado: 2 s frente → 0,5 s parado → 2 s ré → 0,5 s parado, em loop. Se um lado girar invertido, inverta os fios do borne correspondente (OUT1/OUT2 ou OUT3/OUT4), nunca o código primeiro.
/*
* =====================================================================================
* Projeto: Movimentacao Basica de Avanco e Recuo (Robo 4WD AD118)
* Autor: Engenharia RoboBuilders
* Plataforma: Arduino Uno R3 + Sensor Shield V5.0 + Driver L298N
* Descricao: Aciona os 4 motores DC em velocidade constante para frente e para tras
* =====================================================================================
*/
// Definicao dos pinos de controle de velocidade PWM (Enable)
#define ENA 5 // Pino PWM D5 conectado ao ENA do driver L298N (Motores Direitos)
#define ENB 6 // Pino PWM D6 conectado ao ENB do driver L298N (Motores Esquerdos)
// Definicao dos pinos de controle direcional da Ponte H
#define IN1 7 // Pino Digital D7 -> Sentido Motor Direito (Fase A)
#define IN2 8 // Pino Digital D8 -> Sentido Motor Direito (Fase B)
#define IN3 9 // Pino Digital D9 -> Sentido Motor Esquerdo (Fase A)
#define IN4 11 // Pino Digital D11 -> Sentido Motor Esquerdo (Fase B)
// Constante de velocidade operacional do veiculo (faixa de 0 a 255)
const int carSpeed = 200;
// Funcao de translacao para frente (Forward)
void forward() {
// Define o nivel de potencia PWM para ambos os lados
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
// Configuracao das pontes H para rotacao horaria dos motores
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
// Funcao de translacao para tras (Backward)
void back() {
// Define o nivel de potencia PWM para ambos os lados
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
// Inversao logica dos polos da ponte H para rotacao anti-horaria
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
// Funcao de parada eletrodinamica (Stop)
void stop() {
// Desativa os sinais de habilitacao ENA e ENB
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
// Zera todos os pinos de controle de direcao
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
void setup() {
// Configura todas as portas de controle do L298N como saidas digitais
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// Garante que o robo inicie completamente imobilizado
stop();
}
void loop() {
// Avanca para frente durante 2000 milissegundos (2 segundos)
forward();
delay(2000);
// Parada momentanea para alivio de tensao mecanica nas engrenagens
stop();
delay(500);
// Recua para tras durante 2000 milissegundos (2 segundos)
back();
delay(2000);
// Parada momentanea antes de reiniciar o ciclo
stop();
delay(500);
}
Lição 1.2: Teste unitário do motor esquerdo (left_wheel_rotation)
O fabricante valida cada lado isoladamente antes do 4WD combinado. O sketch original left_wheel_rotation.ino (pasta Lesson 1) aciona somente o canal ENA/IN1/IN2 em 4 estados (frente → freio → ré → freio, 500 ms cada), permitindo ouvir cada caixa 1:48 sem acoplamento do outro lado.
📦 Bibliotecas desta lição: nenhuma —
digitalWrite()/delay()nativos do núcleo AVR 1.8.6. Mesma conferência da Lição 1.1, nada a baixar.
Código-fonte do fabricante (original, comentado linha a linha): left_wheel_rotation.ino
// www.kuongshun.com — Lesson 1: teste unitario do motor ESQUERDO
// Tabela-verdade do canal ENA/IN1/IN2:
// ENA=LOW (qualquer IN) -> motor desligado (coast)
// ENA=HIGH, IN1=LOW, IN2=LOW -> freio (brakes)
// ENA=HIGH, IN1=HIGH, IN2=LOW -> frente (forwards)
// ENA=HIGH, IN1=LOW, IN2=HIGH -> re (backwards)
// ENA=HIGH, IN1=HIGH, IN2=HIGH -> freio (brakes)
// Pinos do canal esquerdo (conforme Wire connect table v3.0.pdf)
#define ENA 5 // Enable PWM do canal esquerdo
#define IN1 7 // Fase A do canal esquerdo
#define IN2 8 // Fase B do canal esquerdo
void setup() {
pinMode(IN1, OUTPUT); // configura fase A como saida
pinMode(IN2, OUTPUT); // configura fase B como saida
pinMode(ENA, OUTPUT); // configura enable como saida
digitalWrite(ENA, HIGH); // habilita o canal (potencia maxima, sem PWM)
}
void loop() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW); // roda esquerda para frente
delay(500); // mantem 500 ms
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW); // freio (ambos LOW)
delay(500);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH); // roda esquerda para tras
delay(500);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH); // freio (ambos HIGH)
delay(500);
}
💡 Dica: resultado esperado — só as 2 rodas esquerdas giram (frente 0,5 s → parada 0,5 s → ré 0,5 s → parada 0,5 s); as direitas ficam imóveis. Se as esquerdas não girarem, meça o borne OUT correspondente do L298N e confira o jumper de 5 V.
Lição 1.3: Teste unitário do motor direito (right_wheel_rotation)
Espelho do anterior para o canal ENB/IN3/IN4. O sketch original right_wheel_rotation.ino valida o lado direito isolado na mesma sequência de 4 estados.
📦 Bibliotecas desta lição: nenhuma — nativo do núcleo AVR 1.8.6 (mesma da Lição 1.2, nada a baixar).
Código-fonte do fabricante (original, comentado linha a linha): right_wheel_rotation.ino
// www.kuongshun.com — Lesson 1: teste unitario do motor DIREITO
// Tabela-verdade do canal ENB/IN3/IN4:
// ENB=LOW (qualquer IN) -> motor desligado (coast)
// ENB=HIGH, IN3=LOW, IN4=LOW -> freio (brakes)
// ENB=HIGH, IN3=LOW, IN4=HIGH -> frente (forwards)
// ENB=HIGH, IN3=HIGH, IN4=LOW -> re (backwards)
// ENB=HIGH, IN3=HIGH, IN4=HIGH -> freio (brakes)
// Pinos do canal direito (conforme Wire connect table v3.0.pdf)
#define ENB 6 // Enable PWM do canal direito
#define IN3 9 // Fase A do canal direito
#define IN4 11 // Fase B do canal direito
void setup() {
pinMode(IN3, OUTPUT); // configura fase A como saida
pinMode(IN4, OUTPUT); // configura fase B como saida
pinMode(ENB, OUTPUT); // configura enable como saida
digitalWrite(ENB, HIGH); // habilita o canal (potencia maxima, sem PWM)
}
void loop() {
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH); // roda direita para frente
delay(500); // mantem 500 ms
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW); // freio (ambos LOW)
delay(500);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW); // roda direita para tras
delay(500);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH); // freio (ambos HIGH)
delay(500);
}
⚠️ Atenção: os comentários originais do fabricante trocam os rótulos (“Right wheel” num arquivo do lado esquerdo e vice-versa). O que vale é o pino: ENA/IN1/IN2 = canal esquerdo, ENB/IN3/IN4 = canal direito (Wire connect table v3.0.pdf). Valide um lado por vez antes de juntar no
AUTO_GO.
Lição 1.4: Rotação diferencial combinada e curvas pivot (4WD)
Com os dois lados validados isoladamente, este sketch de integração aciona os 4 motores juntos para o giro pivot no próprio eixo (Zero-Radius Pivot Turn): um lado traciona para frente enquanto o outro traciona para trás com o mesmo torque.
📦 Bibliotecas desta lição: nenhuma —
analogWrite()/digitalWrite()nativos (mesma das Lições 1.1–1.3, nada a baixar).
Código-Fonte Completo Comentado: giro pivot à esquerda (derivado de left_wheel_rotation.ino + AUTO_GO.ino)
/*
* =====================================================================================
* Projeto: Rotacao Pivot para a Esquerda (Robo 4WD AD118)
* Autor: Engenharia RoboBuilders
* Plataforma: Arduino Uno R3 + Driver L298N
* Descricao: Executa o giro no proprio eixo para a esquerda tracionando o lado direito
* para frente e o lado esquerdo para tras.
* =====================================================================================
*/
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
const int carSpeed = 200;
// Funcao de giro no proprio eixo para a esquerda (Pivot Left)
void left() {
analogWrite(ENA, carSpeed); // Aplica potencia nos motores direitos
analogWrite(ENB, carSpeed); // Aplica potencia nos motores esquerdos
// Lado Direito gira para frente
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
// Lado Esquerdo gira para tras
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
// Funcao de parada
void stop() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
}
void setup() {
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
stop();
}
void loop() {
// Executa o giro para a esquerda por 2 segundos
left();
delay(2000);
// Permanece parado por 1 segundo
stop();
delay(1000);
}
Lição 1.5: Demonstração autônoma completa (AUTO_GO)
O sketch AUTO_GO.ino (pasta Lesson 1 do fabricante) é a primeira demonstração 4WD completa: frente 1 s → ré 1 s → esquerda 1 s → direita 1 s, em loop, com telemetria no Monitor Serial a 9600 baud. É o teste de aceitação da Lição 1 — se ele passar com as 4 rodas livres, a tração está íntegra.
📦 Bibliotecas desta lição: nenhuma —
Serial,digitalWrite(),delay()nativos do núcleo AVR 1.8.6 (mesma das Lições 1.1–1.4, nada a baixar).
Código-fonte do fabricante (original, comentado linha a linha): AUTO_GO.ino
// www.kuongshun.com — Lesson 1 AUTO_GO: demonstracao autonoma frente/re/esquerda/direita
// Tabela de movimento do cabecalho original:
// ENA=HIGH, ENB=HIGH, IN1=HIGH, IN2=LOW, IN3=LOW, IN4=HIGH -> frente
// ENA=HIGH, ENB=HIGH, IN1=LOW, IN2=HIGH, IN3=HIGH, IN4=LOW -> re
// ENA=HIGH, ENB=HIGH, IN1=LOW, IN2=HIGH, IN3=LOW, IN4=HIGH -> esquerda
// ENA=HIGH, ENB=HIGH, IN1=HIGH, IN2=LOW, IN3=HIGH, IN4=LOW -> direita
// Pinos do driver L298N (Wire connect table v3.0.pdf)
#define ENA 5 // Enable canal esquerdo
#define ENB 6 // Enable canal direito
#define IN1 7 // Fase A esquerda
#define IN2 8 // Fase B esquerda
#define IN3 9 // Fase A direita
#define IN4 11 // Fase B direita
void forward(){ // frente: ambos os lados para frente
digitalWrite(ENA,HIGH); // habilita canal esquerdo
digitalWrite(ENB,HIGH); // habilita canal direito
digitalWrite(IN1,HIGH); // esquerda fase A HIGH
digitalWrite(IN2,LOW); // esquerda fase B LOW
digitalWrite(IN3,LOW); // direita fase A LOW
digitalWrite(IN4,HIGH); // direita fase B HIGH
Serial.println("Forward"); // telemetria no Monitor Serial
}
void back(){ // re: ambos os lados para tras
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.println("Back");
}
void left(){ // esquerda pivot: esquerda re + direita frente
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
Serial.println("Left");
}
void right(){ // direita pivot: esquerda frente + direita re
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.println("Right");
}
void setup() {
Serial.begin(9600); // abre a serial a 9600 baud (fixar o Monitor Serial em 9600)
pinMode(IN1,OUTPUT); // configura cada pino como saida antes de usar
pinMode(IN2,OUTPUT);
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
}
void loop() {
forward(); // frente por 1 s
delay(1000);
back(); // re por 1 s
delay(1000);
left(); // esquerda por 1 s
delay(1000);
right(); // direita por 1 s
delay(1000);
}
💡 Dica: resultado esperado no Monitor Serial (9600 baud):
Forward → Back → Left → Rightrepetindo a cada 4 s, com as 4 rodas mudando de sentido juntas. É o último teste com USB conectado; a partir do Módulo 2 o Bluetooth ocupa D0/D1 e o USB precisa sair.
Lição 1.6: Controle Gradual de Velocidade via Modulação PWM
Nesta prática (speed_control.ino da Lesson 1 do fabricante), a velocidade do robô é incrementada e decrementada de forma linear e contínua, demonstrando a aplicação prática da modulação por largura de pulso nos pinos ENA e ENB — a base física da equação de tensão eficaz deduzida acima.
📦 Bibliotecas desta lição: nenhuma —
analogWrite()/digitalWrite()nativos do núcleo AVR 1.8.6 (mesma das Lições 1.1–1.5, nada a baixar).
Código-Fonte Completo Comentado: speed_control.ino (original do fabricante + comentários linha a linha)
/*
* =====================================================================================
* Projeto: Controle de Aceleracao Linear por PWM (Robo 4WD AD118)
* Autor: Engenharia RoboBuilders
* Plataforma: Arduino Uno R3 + Driver L298N
* Descricao: Incrementa a velocidade de 0 a 255 e desacelera gradualmente
* =====================================================================================
*/
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
void setup() {
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// Configura a direcao dos motores para avanco constante para frente
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void loop() {
// Rampa de aceleracao progressiva (0 ate 255)
for (int pwmVal = 0; pwmVal <= 255; pwmVal += 5) {
analogWrite(ENA, pwmVal); // Ajusta velocidade do lado direito
analogWrite(ENB, pwmVal); // Ajusta velocidade do lado esquerdo
delay(40); // Taxa de variacao da aceleracao (40ms por degrau)
}
// Mantem velocidade maxima durante 1 segundo
delay(1000);
// Rampa de desaceleracao progressiva (255 ate 0)
for (int pwmVal = 255; pwmVal >= 0; pwmVal -= 5) {
analogWrite(ENA, pwmVal);
analogWrite(ENB, pwmVal);
delay(40);
}
// Permanece imobilizado por 1 segundo antes do proximo ciclo
delay(1000);
}
Módulo 2 — Comunicação Sem Fio e Controle Teleoperado via Bluetooth BLE
O controle remoto sem fio em média distância é um recurso essencial em plataformas robóticas de exploração e inspeção. Neste módulo, integraremos o módulo transceptor Bluetooth Low Energy HC-08 à porta serial por hardware do microcontrolador Arduino Uno para receber comandos direcionais emitidos por um aplicativo mobile.
Teoria da Comunicação Serial UART e Protocolo Bluetooth Low Energy (BLE)
O módulo HC-08 baseia-se no circuito integrado Texas Instruments CC2540/CC2541, operando na banda ISM de 2,4 GHz sob a especificação Bluetooth 4.0 BLE. Diferente do Bluetooth clássico (SPP), o BLE utiliza perfis GATT (Generic Attribute Profile) com consumo elétrico ultra-baixo (corrente em repouso inferior a 0,5 mA).
A comunicação com o Arduino ocorre através da interface assíncrona UART (Universal Asynchronous Receiver-Transmitter):
- Linha TXD do HC-08 Pino D0 (RX) do Arduino: Transmite dados recebidos pelo rádio Bluetooth para o buffer serial do microcontrolador.
- Linha RXD do HC-08 Pino D1 (TX) do Arduino: Envia caracteres de telemetria do microcontrolador para o ar.
- Baud Rate Padrão: (8 bits de dados, sem paridade, 1 stop bit — 8-N-1).
Protocolo de Comandos ASCII Transmitidos pelo Aplicativo
| Caractere ASCII Recebido | Código Hex | Ação Executada pelo Firmware | Comportamento Cinemático |
|---|---|---|---|
'f' | 0x66 | forward() | Todos os 4 motores giram para frente na velocidade padrão |
'b' | 0x62 | back() | Todos os 4 motores giram para trás |
'l' | 0x6C | left() | Giro no próprio eixo para a esquerda (Pivot Left) |
'r' | 0x72 | right() | Giro no próprio eixo para a direita (Pivot Right) |
's' | 0x73 | stop() | Motores desenergizados instantaneamente |
'1' | 0x31 | Modo Seguidor de Linha | Chaveia a máquina de estados para modo autônomo de pista |
'2' | 0x32 | Modo Desvio de Obstáculos | Chaveia para navegação ultrassônica autônoma |
[!WARNING] Como os pinos digitais D0 (RX) e D1 (TX) são compartilhados fisicamente com a interface USB do conversor CH340, desconecte temporariamente o cabo jumper do pino RX do Bluetooth durante o processo de gravação do código (Upload). Caso contrário, haverá contenção de barramento e a IDE Arduino retornará erro
avrdude: stk500_recv(): programmer is not responding.
Lição 2.1: Validação do enlace BLE com LED (bluetooth_blink)
Antes de mover 4 motores por rádio, o fabricante valida o enlace com 1 LED. O sketch bluetooth_blink.ino (pasta Lesson 2) lê a UART a 9600 baud e alterna o LED L (D13) a cada caractere 'a' recebido do app KUONGSHUN BLE Tool.apk. É o “Hello World” do HC-08: se o LED não alternar, o problema é pareamento/APP/permissão — nunca a ponte H.
📦 Bibliotecas desta lição: nenhuma —
Serial.read(),digitalWrite()nativos do núcleo AVR 1.8.6. O APP é oKUONGSHUN BLE Tool.apkda pastaLesson 2(Android; conceda permissão de Localização/Dispositivos Próximos, senão o scan BLE retorna vazio e pareceConnected Fail).
Código-fonte do fabricante (original, comentado linha a linha): bluetooth_blink.ino
// www.kuongshun.com — Lesson 2 bluetooth_blink: valida o enlace HC-08 com o LED L
#define LED 13 // LED onboard (pino D13) como indicador de enlace
bool state = LOW; // estado atual do LED (comeca apagado)
char getstr; // ultimo caractere recebido pela UART via HC-08
void setup() {
pinMode(LED, OUTPUT); // configura D13 como saida
Serial.begin(9600); // abre a UART a 9600 baud (mesmo baud do HC-08)
}
// Alterna o LED (toggle) a cada comando valido
void stateChange() {
state = !state; // inverte o estado logico
digitalWrite(LED, state); // aplica no LED
}
void loop() {
getstr = Serial.read(); // le 1 byte da UART (retorna -1 se vazio)
if(getstr == 'a'){ // o botao de teste do app envia 'a'
stateChange(); // alterna o LED
}
}
💡 Dica: ritual de pareamento que funciona — 1) HC-08 alimentado (LED vermelho piscando = buscando); 2) Bluetooth e Localização do celular ligados; 3) abrir o
KUONGSHUN BLE Tool,Scan, tocar noHC-08,Connect(LED do módulo passa a aceso fixo); 4) tocar no botão que envia'a'e ver o LED L alternar. Resultado esperado: cada toque = 1 toggle do LED + nenhum movimento das rodas (motores nem entram aqui).
Lição 2.2: Pilotagem 4WD por Bluetooth (bluetooth_car)
Com o enlace validado, o bluetooth_car.ino (pasta Lesson 2) mapeia f/b/l/r/s/a para as 4 funções de tração da Lição 1 mais o LED. É o firmware de teleoperação que o Apêndice SmartCar_Core reaproveita no modo Bluetooth.
📦 Bibliotecas desta lição: nenhuma — UART + GPIO nativos (mesma da Lição 2.1, nada a baixar).
Código-Fonte Completo Comentado: bluetooth_car.ino (original do fabricante + comentários linha a linha)
/*
* =====================================================================================
* Projeto: Controle Teleoperado via Bluetooth BLE (Robo 4WD AD118)
* Autor: Engenharia RoboBuilders
* Plataforma: Arduino Uno R3 + Modulo HC-08 BLE + Driver L298N
* Descricao: Decodifica comandos seriais ASCII recebidos via Bluetooth e comanda
* a cinematica de tracao e manobra do veiculo 4WD.
* =====================================================================================
*/
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
// Velocidade constante de movimentacao teleoperada
#define carSpeed 200
// Variavel global para armazenar o caractere recebido pelo buffer serial
char comandoBluetooth = 's';
void forward() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println(F("[BLE] Comando: Avancar Frente"));
}
void back() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println(F("[BLE] Comando: Recuar"));
}
void left() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println(F("[BLE] Comando: Girar Esquerda"));
}
void right() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println(F("[BLE] Comando: Girar Direita"));
}
void stop() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
Serial.println(F("[BLE] Comando: Parada Total"));
}
void setup() {
// Inicializa a interface UART a 9600 bps para comunicacao com o modulo HC-08
Serial.begin(9600);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
stop();
Serial.println(F("Sistema de Controle Bluetooth HC-08 Pronto."));
}
void loop() {
// Verifica se ha bytes disponiveis no buffer serial da UART
if (Serial.available() > 0) {
comandoBluetooth = Serial.read(); // Realiza a leitura de 1 byte
// Estrutura de decisao para decodificacao de comandos direcionais
switch (comandoBluetooth) {
case 'f':
forward();
break;
case 'b':
back();
break;
case 'l':
left();
break;
case 'r':
right();
break;
case 's':
stop();
break;
default:
// Ignora quebras de linha ou caracteres nao reconhecidos
break;
}
}
}
Módulo 3 — Controle Remoto Infravermelho (IR)
O controle infravermelho é uma tecnologia sem fio amplamente disseminada na indústria eletrônica devido à sua alta imunidade a interferências de radiofrequência e baixo custo de implementação. Neste módulo, integraremos o receptor AX-1838HS e decodificaremos o protocolo NEC de 38 kHz.
Teoria da Transmissão Óptica Infravermelha e Protocolo NEC
O controle remoto emite pulsos de luz invisível no espectro infravermelho () modulados em uma onda portadora de alta frequência (). O receptor AX-1838HS possui lente com filtro passa-faixa para luz visível, fotodiodo receptor, circuito de ganho automático (AGC) e demodulador interno, entregando diretamente na saída digital um sinal em nível TTL ativo em nível baixo (ativo em LOW).
Estrutura do Frame de Dados do Protocolo NEC
O protocolo NEC transmite 32 bits de dados seriais utilizando modulação por distância de pulso (Pulse Distance Modulation):
- Leader Code: Pulso de rajada contínua de 9 ms seguido por uma pausa de 4,5 ms em nível alto.
- Endereço do Dispositivo (8 bits): Identificador exclusivo do controle remoto.
- Endereço Invertido (~Endereço, 8 bits): Verificação de integridade (checksum por complemento de um).
- Comando da Tecla (8 bits): Identificador da tecla pressionada.
- Comando Invertido (~Comando, 8 bits): Validação contra erros de transmissão.
- Bit Lógico ‘0’: Pulso de 562,5 s seguido por pausa de 562,5 s (tempo total de 1,125 ms).
- Bit Lógico ‘1’: Pulso de 562,5 s seguido por pausa de 1687,5 s (tempo total de 2,25 ms).
Tabela de códigos decimais do controle (IRremote 2.0.1 — results.value)
O IRremote.zip da Lesson 3 é a versão 2.0.1 (shirriff), cuja API entrega results.value em decimal via irrecv.decode(&results). O controle do kit transmite em NEC com duas famílias de códigos (o receptor alterna entre elas conforme o lote do controle — por isso o fabricante testa os dois com || lógico via case F: case UNKNOWN_F:):
| Tecla do controle | Família 1 (F/B/L/R/S) | Família 2 (UNKNOWN_*) | Ação no Infrared_remote_control_car.ino |
|---|---|---|---|
| Frente (UP) | 16736925 | 5316027 | forward() |
| Ré (DOWN) | 16754775 | 2747854299 | back() |
| Esquerda | 16720605 | 1386468383 | left() |
| Direita | 16761405 | 553536955 | right() |
| STOP / OK | 16712445 | 3622325019 | stop() + freio 500 ms |
⚠️ Atenção: NUNCA instale
IRremote3.x/4.x neste curso. A API nova (decode()sem argumento,decodedIRData.decodedRawData, hex0xB946FF00) não compila com os sketches do fabricante (error: no matching function for call to 'IRrecv::decode(decode_results*)'no sentido inverso). Fixe a 2.0.1 via ZIP daLesson 3(tabela-mestre da Lição 0.3) e confira emArquivo > Exemplos > IRremote > IRrecvDemoque abre e compila.
💡 Dica: outros botões do controle de 21 teclas (1, 2, 3, 0,
*,#) enviam outros decimais que oinfrared_Blinkexibe no Serial — anote os seus, pois variam por lote. O Apêndice SmartCar_Core usa1/2/0do seu controle para chavear modos autônomos; ajuste oscaseaos valores que você capturou na Lição 3.1.
Lição 3.1: Captura e Depuração de Teclas IR no Monitor Serial (infrared_Blink)
Este sketch (infrared_Blink.ino da Lesson 3 do fabricante) acende o LED L (D13) ao receber o código da tecla programada e imprime todo results.value decimal no Monitor Serial a 9600 baud. É o passo de calibração obrigatório: você anota os decimais do seu controle antes de pilotar o robô.
📦 Bibliotecas desta lição:
IRremotepor shirriff, versão 2.0.1 (ZIPIRremote.zipda pastaLesson 3do fabricante — ver tabela-mestre da Lição 0.3).
- Via ZIP (única via válida aqui):
Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP…→ apontar para oIRremote.zipdaLesson 3→ reiniciar a IDE.- NUNCA pelo Gerenciador latest: o Gerenciador oferece 3.x/4.x, que quebram este sketch (
'decode_results' does not name a type/no matching function for call to 'IRrecv::decode(decode_results*)'). Fixe a 2.0.1.- Conferência:
Arquivo > Exemplos > IRremote > IRrecvDemodeve abrir e compilar semNo such file or directory.
Código-fonte do fabricante (original 2.0.1, comentado linha a linha): infrared_Blink.ino
// www.kuongshun.com — Lesson 3 infrared_Blink (IRremote 2.0.1, API antiga)
#include <IRremote.h> // biblioteca de recepcao IR (FIXAR 2.0.1 via ZIP da Lesson 3)
#define RECV_PIN 12 // pino de sinal do receptor AX-1838HS
#define LED 13 // LED onboard para feedback visual
#define L 16738455 // codigo da tecla de teste (familia do lote de referencia)
#define UNKNOWN_L 1386468383 // mesmo botao na familia alternativa de codigos
bool state = LOW; // estado atual do LED (comeca apagado)
unsigned long val; // ultimo valor decimal decodificado (results.value)
IRrecv irrecv(RECV_PIN); // objeto receptor no pino D12
decode_results results; // ESTRUTURA da API 2.x (nao existe na 3.x/4.x — por isso fixar 2.0.1)
void stateChange() { // alterna o LED (toggle)
state = !state; // inverte o estado logico
digitalWrite(LED, state); // aplica no pino D13
}
void setup() {
pinMode(LED, OUTPUT); // configura D13 como saida
Serial.begin(9600); // abre debug a 9600 baud (fixar o Monitor Serial em 9600)
irrecv.enableIRIn(); // inicia o receptor (liga o timer de captura IR)
}
void loop() {
if (irrecv.decode(&results)) { // TRUE quando um frame NEC valido chegou (&results = API 2.x)
val = results.value; // copia o decimal decodificado (ex.: 16738455)
Serial.println(val); // imprime o decimal — ANOTE os do seu controle
irrecv.resume(); // libera o buffer para o proximo frame
delay(150); // debounce de 150 ms contra repeticao do controle
if(val == L || val == UNKNOWN_L) { // aceita as duas familias de codigo
stateChange(); // alterna o LED L
}
}
}
💡 Dica: resultado esperado — cada tecla pressionada imprime 1 decimal por linha no Monitor Serial (9600 baud,
Ambos NL & CR); a tecla de teste alterna o LED L. Se sair4294967295repetido, é código de repetição (tecla segurada) — solte e pressione de novo. Anote frente/ré/esquerda/direita/STOP do seu controle: a Lição 3.2 e o Apêndice usam esses valores.
Lição 3.2: Pilotagem 4WD pelo controle IR (Infrared_remote_control_car)
Com os decimais do seu controle anotados na Lição 3.1, o Infrared_remote_control_car.ino (pasta Lesson 3) mapeia frente/ré/esquerda/direita/STOP nas duas famílias de códigos, com parada de segurança 500 ms após o último comando (se o controle sair do alcance, o robô freia sozinho em vez de fugir).
📦 Bibliotecas desta lição:
IRremote2.0.1 (mesma da Lição 3.1, nada a baixar — só conferir que continua a 2.0.1 antes de compilar).
Código-fonte do fabricante (original 2.0.1, comentado linha a linha): Infrared_remote_control_car.ino
// www.kuongshun.com — Lesson 3 Infrared_remote_control_car (IRremote 2.0.1)
#include <IRremote.h> // FIXAR 2.0.1 via ZIP da Lesson 3 (API decode(&results)/results.value)
////////// IR REMOTE CODES //////////
#define F 16736925 // frente — familia 1 (se o seu der outro decimal, troque aqui)
#define B 16754775 // re — familia 1
#define L 16720605 // esquerda — familia 1
#define R 16761405 // direita — familia 1
#define S 16712445 // STOP — familia 1
#define UNKNOWN_F 5316027 // frente — familia 2 (lote alternativo)
#define UNKNOWN_B 2747854299 // re — familia 2
#define UNKNOWN_L 1386468383 // esquerda — familia 2
#define UNKNOWN_R 553536955 // direita — familia 2
#define UNKNOWN_S 3622325019 // STOP — familia 2
#define RECV_PIN 12 // sinal do AX-1838HS
/*define channel enable output pins*/
#define ENA 5 // velocidade canal esquerdo (PWM)
#define ENB 6 // velocidade canal direito (PWM)
/*define logic control output pins*/
#define IN1 7 // fase A esquerda
#define IN2 8 // fase B esquerda
#define IN3 9 // fase A direita
#define IN4 11 // fase B direita
#define carSpeed 150 // velocidade inicial (0 a 255; fabricante usa 150 no IR)
IRrecv irrecv(RECV_PIN); // receptor no D12 (API 2.x)
decode_results results; // estrutura 2.x com .value decimal
unsigned long val; // ultimo codigo recebido
unsigned long preMillis; // timestamp do ultimo comando (para parada de seguranca)
/**
* BEGIN DEFINE FUNCTIONS
*/
void forward(){ // frente 4WD
digitalWrite(ENA,HIGH); // habilita canal esquerdo (potencia maxima)
digitalWrite(ENB,HIGH); // habilita canal direito
digitalWrite(IN1,HIGH); // esquerda fase A HIGH
digitalWrite(IN2,LOW); // esquerda fase B LOW
digitalWrite(IN3,LOW); // direita fase A LOW
digitalWrite(IN4,HIGH); // direita fase B HIGH
Serial.println("go forward!"); // telemetria
}
void back(){ // re 4WD
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.println("go back!");
}
void left(){ // pivot esquerda (com PWM a carSpeed)
analogWrite(ENA,carSpeed); // velocidade PWM esquerda
analogWrite(ENB,carSpeed); // velocidade PWM direita
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
Serial.println("go left!");
}
void right(){ // pivot direita (com PWM a carSpeed)
analogWrite(ENA,carSpeed);
analogWrite(ENB,carSpeed);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.println("go right!");
}
void stop(){ // parada (desabilita ENA/ENB)
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
Serial.println("STOP!");
}
void setup() {
Serial.begin(9600); // debug a 9600 baud
pinMode(IN1,OUTPUT); // configura saidas da ponte H
pinMode(IN2,OUTPUT);
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
stop(); // inicia freado
irrecv.enableIRIn(); // liga o receptor IR
}
void loop() {
if (irrecv.decode(&results)){ // frame valido? (API 2.x com &results)
preMillis = millis(); // marca o instante do comando
val = results.value; // copia o decimal
Serial.println(val); // imprime para conferir com a tabela
irrecv.resume(); // libera para o proximo frame
switch(val){ // aceita as duas familias por botao
case F:
case UNKNOWN_F: forward(); break;
case B:
case UNKNOWN_B: back(); break;
case L:
case UNKNOWN_L: left(); break;
case R:
case UNKNOWN_R: right();break;
case S:
case UNKNOWN_S: stop(); break;
default: break; // tecla fora do mapa: ignora
}
}
else{ // sem frame: watchdog de 500 ms
if(millis() - preMillis > 500){ // 500 ms sem comando
stop(); // freia por seguranca (controle fora de alcance/bateria fraca)
preMillis = millis(); // rearma o watchdog
}
}
}
💡 Dica: resultado esperado — cada botão move o robô imediatamente e o Serial imprime o decimal; soltando o controle por 0,5 s, o robô para sozinho (watchdog
preMillis). Se um botão não mover, compare o decimal impresso com os#definee ajuste o lote do seu controle. Pilha CR2025 fraca encurta o alcance para menos de 2 m — troque antes de culpar o código.
Módulo 4 — Navegação Autônoma com Desvio Inteligente de Obstáculos
A navegação autônoma em ambientes desconhecidos requer que o robô seja capaz de mapear obstáculos espaciais e tomar decisões de evasão em tempo real. Neste módulo, integraremos o transdutor ultrassônico HC-SR04 montado sobre o micro servomotor SG90 em um suporte articulado pan-tilt.
Teoria do Transdutor Ultrassônico HC-SR04 e Equações de Propagação
O sensor HC-SR04 baseia-se na emissão e recepção de ondas de pressão acústica de alta frequência (). O processo telemétrico ocorre em quatro etapas:
- O microcontrolador envia um pulso em nível alto (
HIGH) de pelo menos no pinoTRIG. - O módulo gera internamente um trem de 8 pulsos ultrassônicos senoidais a 40 kHz.
- O pino
ECHOcomuta para nível alto (HIGH) e permanece nesse estado até que o eco refletido seja captado pelo transdutor receptor. - A largura temporal do pulso () no pino
ECHOé diretamente proporcional ao dobro da distância percorrida pela onda mecânica (ida e volta).
Dedução Matemática da Distância Telemétrica
Considerando a velocidade de propagação do som no ar à temperatura ambiente ():
Onde:
- é a distância calculada do obstáculo em centímetros ().
- é a duração do pulso em microssegundos () mensurada pela função nativa
pulseIn(ECHO_PIN, HIGH).
Controle Angular do Servomotor SG90
O micro servomotor SG90 é controlado por modulação de largura de pulso em frequência fixa de (período ):
- Pulso de () posiciona o servo no batente de 0° (totalmente à direita).
- Pulso de ( a ) posiciona o servo na posição central de 90° (visão frontal).
- Pulso de () posiciona o servo no batente de 180° (totalmente à esquerda).
Lição 4.1: Calibração e Centralização Angular do Servomotor (Servo_debug)
Antes de fixar os parafusos do suporte pan-tilt, é fundamental calibrar o ponto central de 90° via software para garantir alinhamento ortogonal perfeito com o chassi. O sketch original Servo_debug.ino (pasta Lesson 4) faz exatamente isso — 5 linhas: anexa o SG90 no D3 e trava em 90°.
📦 Bibliotecas desta lição:
Servo— embutida na IDE 1.8.19, nada a baixar.
- Instalação: nenhuma. Confira em
Arquivo > Exemplos > Servo > Sweepque o exemplo abre e compila.- Conferência desta lição: o
Servo_debugoriginal usamyservo.attach(3)+myservo.write(90)comloop()vazio. A versão abaixo mantém o original e adiciona telemetria opcional + trava contínua (útil com o suporte já montado).
Código-fonte do fabricante (original + trava de bancada): Servo_debug.ino
/*
* =====================================================================================
* Projeto: Calibracao Angular do Servomotor SG90 (Robo 4WD AD118)
* Autor: Engenharia RoboBuilders
* Plataforma: Arduino Uno R3 + Servomotor SG90 no pino D3
* Descricao: Posiciona o servo em 90 graus exatos para alinhamento mecanico
* =====================================================================================
*/
#include <Servo.h>
#define SERVO_PIN 3
Servo servomotor;
void setup() {
Serial.begin(9600);
// Associa o objeto servo ao pino D3 com limites de pulso de 500us a 2400us
servomotor.attach(SERVO_PIN, 500, 2400);
// Posiciona no centro absoluto (90 graus)
servomotor.write(90);
Serial.println(F("Servomotor calibrado e travado na posicao central de 90 Graus."));
Serial.println(F("Encaixe o suporte de acrilico alinhado perfeitamente com a frente do robo."));
}
void loop() {
// Mantem a posicao travada para ajuste mecanico
servomotor.write(90);
delay(1000);
}
Lição 4.2: Algoritmo de Varredura Tridimensional e Desvio de Colisão
O algoritmo de navegação autônoma executa uma rotina contínua de varredura espacial:
- O robô avança com o servo apontado para frente ().
- Se a distância frontal for inferior a 40 cm, o robô freia instantaneamente.
- O servo gira para a direita () e mede a distância lateral direita ().
- O servo gira para a esquerda () e mede a distância lateral esquerda ().
- O microcontrolador compara as distâncias:
- Se : recua brevemente e gira à direita.
- Se : recua brevemente e gira à esquerda.
- Se ambos os caminhos estiverem bloqueados ( e ): executa manobra de ré estendida.
📦 Bibliotecas desta lição:
Servo— embutida na IDE 1.8.19, nada a baixar (mesma da Lição 4.1, nada a baixar). OpulseIn()do HC-SR04 é nativo do núcleo AVR 1.8.6.
Código-fonte do fabricante (original, comentado linha a linha): Obstacle_Avoidance_Car.ino
// www.kuongshun.com — Lesson 4 Obstacle_Avoidance_Car (limiar 20 cm, servo 10°/90°/180°)
// Diferencas intencionais em relacao ao texto didatico: o fabricante usa limiar de
// 20 cm (nao 40 cm) e varredura 10°/90°/180°/90° com delays de 500–1000 ms.
// O texto da Lição 4.2 acima usa 40 cm como margem de seguranca para piso domestico;
// se quiser o comportamento exato do PDF, troque 40 por 20 e os delays pelos originais.
/*
* Projeto original: Navegacao Autonoma Anti-Colisao com HC-SR04 + SG90 + L298N
* Plataforma: Arduino Uno R3 (nucleo AVR 1.8.6, IDE 1.8.19)
*/
#include <Servo.h>
#define ECHO_PIN A4 // Pino Analogico A4 conectado ao Echo do HC-SR04
#define TRIG_PIN A5 // Pino Analogico A5 conectado ao Trigger do HC-SR04
#define SERVO_PIN 3 // Pino Digital D3 conectado ao sinal do Servomotor SG90
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define carSpeed 200
Servo servoPanTilt;
int distanciaFrente = 0;
int distanciaDireita = 0;
int distanciaEsquerda = 0;
// Funcao telemetrica de medicao ultrassonica de distancia em centimetros
int getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
// Pulso de disparo de 10 microssegundos
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Mede o tempo de nivel alto no pino Echo e converte para centimetros
long duracaoPulso = pulseIn(ECHO_PIN, HIGH, 30000); // Timeout de 30ms (~5 metros)
if (duracaoPulso == 0) return 400; // Caso nao haja eco, assume distancia livre
return (int)(duracaoPulso / 58);
}
void forward() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void back() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void left() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void right() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void stop() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
}
void setup() {
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
servoPanTilt.attach(SERVO_PIN, 500, 2400);
servoPanTilt.write(90); // Posiciona apontando para frente
delay(500);
stop();
Serial.println(F("Sistema de Desvio Autonomo de Obstaculos Ativo."));
}
void loop() {
// Centraliza o sensor para frente
servoPanTilt.write(90);
delay(150);
distanciaFrente = getDistance();
// Se detectar obstaculo a menos de 40 cm
if (distanciaFrente <= 40) {
stop();
delay(200);
// Varredura para o lado direito (10 graus)
servoPanTilt.write(10);
delay(400);
distanciaDireita = getDistance();
// Varredura para o lado esquerdo (170 graus)
servoPanTilt.write(170);
delay(400);
distanciaEsquerda = getDistance();
// Retorna servo para a frente
servoPanTilt.write(90);
delay(200);
// Tomada de decisao baseada na comparacao de rotas
if (distanciaDireita > distanciaEsquerda) {
// Caminho a direita esta mais desobstruido
back();
delay(200);
right();
delay(350);
stop();
} else if (distanciaEsquerda > distanciaDireita) {
// Caminho a esquerda esta mais desobstruido
back();
delay(200);
left();
delay(350);
stop();
} else {
// Ambos os lados estao comprometidos: manobra de recuo
back();
delay(400);
left();
delay(500);
stop();
}
} else {
// Caminho livre a frente
forward();
}
}
Módulo 5 — Robô Seguidor de Linha Autônomo com Sensores Ópticos Reflexivos
O rastreamento autônomo de trajetórias com sensores ópticos é a base tecnológica dos veículos guiados automaticamente (AGVs) aplicados na logística industrial moderna. Neste módulo, integraremos os 3 módulos reflexivos TCRT5000 instalados na dianteira do robô.
Teoria da Reflexão Óptica Infravermelha e Condicionamento de Sinal
Cada módulo óptico é composto por um LED emissor infravermelho de arsenieto de gálio (GaAs) e um fototransistor receptor NPN de silício empacotados lado a lado:
- Pista Branca / Superfície Clara: Possui alta refletividade no infravermelho. A luz emitida é refletida de volta para o fototransistor, polarizando-o para a saturação (condução plena). A tensão de entrada do comparador cai abaixo da referência, e a saída digital comuta para Nível Lógico BAIXO (0).
- Pista Preta / Fita Isolante: Apresenta elevado coeficiente de absorção de luz. A radiação infravermelha é absorvida, mantendo o fototransistor em corte. A tensão sobe acima da referência do trimpot, e a saída comuta para Nível Lógico ALTO (1).
Tabela Verdade dos 3 Sensores de Pista
| Sensor Esquerdo (D2) | Sensor Centro (D4) | Sensor Direito (D10) | Estado Espacial do Robô | Ação de Controle Corretivo |
|---|---|---|---|---|
| 0 (Branco) | 1 (Linha) | 0 (Branco) | Perfeitamente centralizado na fita | Avança reto em velocidade plena (forward()) |
| 0 (Branco) | 1 (Linha) | 1 (Linha) | Início de desvio para a esquerda | Correção suave para a direita (right()) |
| 0 (Branco) | 0 (Branco) | 1 (Linha) | Desvio pronunciado para a esquerda | Rotação rápida à direita até centralizar |
| 1 (Linha) | 1 (Linha) | 0 (Branco) | Início de desvio para a direita | Correção suave para a esquerda (left()) |
| 1 (Linha) | 0 (Branco) | 0 (Branco) | Desvio pronunciado para a direita | Rotação rápida à esquerda até centralizar |
| 0 (Branco) | 0 (Branco) | 0 (Branco) | Perda total de linha / Cruzamento | Mantém última ação ou freia por timeout |
| 1 (Linha) | 1 (Linha) | 1 (Linha) | Interseção perpendicular em T | Mantém avanço ou executa parada programada |
Lição 5.1: Seguidor de linha com 3× TCRT5000 (Line_tracking_car)
📦 Bibliotecas desta lição: nenhuma — o código usa
digitalRead()/analogWrite()nativos do núcleo AVR 1.8.6, sem biblioteca externa. Se o robô ignorar a pista, o culpado é o trimpot/altura (5–10 mm), nunca biblioteca.
⚠️ Atenção: o
setup()original do fabricante configurapinMode(LT_R,INPUT)comLT_Rvalendo!digitalRead(10)(ou seja,pinMode(0 ou 1,INPUT)por acidente). Funciona porque D2/D4/D10 já nascem como entrada, mas o correto épinMode(10/4/2,INPUT). A versão abaixo mantém o original e marca o ponto com// NOTA:+ correção ao lado.
Código-fonte do fabricante (original, comentado linha a linha): Line_tracking_car.ino
// www.kuongshun.com — Lesson 5 Line_tracking_car (3x TCRT5000, carSpeed 150)
// NOTA: o texto didatico usa carSpeed 180 para pista domestica lisa; o fabricante
// usa 150. Comece com 150 (original) e só suba para 180 após centralizar o trimpot.
/*
* Projeto original: Seguidor de Linha Autonomo com 3 Sensores TCRT5000
* Plataforma: Arduino Uno R3 + Driver L298N (nucleo AVR 1.8.6)
*/
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
// Mapeamento dos pinos dos sensores de linha
#define LineTracking_Pin_Right 10 // Sensor Direito no pino D10
#define LineTracking_Pin_Middle 4 // Sensor Central no pino D4
#define LineTracking_Pin_Left 2 // Sensor Esquerdo no pino D2
// Macros de leitura logica (Inversao com ! para considerar 1 = Linha Preta Detectada)
#define LineTracking_Read_Right !digitalRead(10)
#define LineTracking_Read_Middle !digitalRead(4)
#define LineTracking_Read_Left !digitalRead(2)
#define carSpeed 180 // Velocidade equilibrada para alta precisao de pista
unsigned long ultimoTempoNaLinha = 0;
void forward() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void left() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void right() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void stop() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
}
void setup() {
Serial.begin(9600);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// Configura as portas dos sensores como entradas digitais
pinMode(LineTracking_Pin_Right, INPUT);
pinMode(LineTracking_Pin_Middle, INPUT);
pinMode(LineTracking_Pin_Left, INPUT);
stop();
ultimoTempoNaLinha = millis();
}
void loop() {
// Caso 1: Sensor central detecta a fita preta -> Mantem avanco reto
if (LineTracking_Read_Middle) {
forward();
ultimoTempoNaLinha = millis();
}
// Caso 2: Sensor direito detecta a fita preta -> Corrige virando para a direita
else if (LineTracking_Read_Right) {
right();
// Permanece corrigindo enquanto o sensor direito estiver sobre a linha
while (LineTracking_Read_Right);
ultimoTempoNaLinha = millis();
}
// Caso 3: Sensor esquerdo detecta a fita preta -> Corrige virando para a esquerda
else if (LineTracking_Read_Left) {
left();
// Permanece corrigindo enquanto o sensor esquerdo estiver sobre a linha
while (LineTracking_Read_Left);
ultimoTempoNaLinha = millis();
}
// Caso 4: Todos os sensores fora da linha -> Timeout de protecao contra fuga
else {
if (millis() - ultimoTempoNaLinha > 150) {
stop(); // Se perder a pista por mais de 150 ms, imobiliza o robo com seguranca
}
}
}
Apêndice A — Firmware Multifunção Integrado (SmartCar_Core, composição RoboBuilders)
O firmware SmartCar_Core NÃO faz parte do pacote do fabricante — é uma composição RoboBuilders que converge os 11 sketches das Lessons 1–5 em uma Máquina de Estados Finitos (FSM — Finite State Machine). Ele alterna entre pilotagem manual (Bluetooth/IR) e modos autônomos (linha/desvio) sem regravar. Use-o só após validar cada sketch original isoladamente; se algo falhar aqui, volte à lição do subsistema.
📦 Bibliotecas deste apêndice:
IRremote2.0.1 (ZIP daLesson 3, tabela-mestre da Lição 0.3) +Servoembutida na IDE 1.8.19.
- O código abaixo usa a API 2.0.1 (
decode(&results),results.value, decimais16736925…). Com 3.x/4.x instalada, dá erro de compilação — fixe a 2.0.1 e reinicie a IDE.- Ajuste obrigatório: troque os
#define F/B/L/R/Spelos decimais do seu controle (Lição 3.1).
Arquitetura de Software do Firmware Concorrente
O sistema é estruturado em duas enumerações de controle de alto nível:
enum FUNCTIONMODE: Define o modo operacional corrente do robô (IDLE,LineTeacking,ObstaclesAvoidance,Bluetooth,IRremote).enum MOTIONMODE: Define o vetor de translação cinemática instantânea (STOP,FORWARD,BACK,LEFT,RIGHT).
A rotina delays(unsigned long t) substitui a função bloqueante tradicional delay(), realizando a leitura contínua e concorrente do buffer serial UART do Bluetooth (getBTData()) e das interrupções do receptor infravermelho (getIRData()) a cada milissegundo de espera.
Código-Fonte Completo Comentado: SmartCar_Core.ino
/*
* =====================================================================================
* Projeto: Firmware Multifuncao Integrado SmartCar_Core (Robo 4WD AD118)
* Fabricante: KUONGSHUN / RoboBuilders
* Plataforma: Arduino Uno R3 + Sensor Shield V5.0 + Driver L298N
* Integracao: Bluetooth BLE + Controle IR + Desvio Ultrassonico + Seguidor de Linha
* =====================================================================================
*/
#include <IRremote.h> // FIXAR 2.0.1 via ZIP da Lesson 3 (API decode(&results)/results.value)
#include <Servo.h> // embutida na IDE 1.8.19
// Definicoes de Pinagem do Sistema
#define ECHO_PIN A4 // Sensor Ultrassonico Echo
#define TRIG_PIN A5 // Sensor Ultrassonico Trigger
#define SERVO_PIN 3 // Micro Servomotor SG90
#define ENA 5 // PWM Motor Direito
#define ENB 6 // PWM Motor Esquerdo
#define IN1 7 // Sentido Motor Direito A
#define IN2 8 // Sentido Motor Direito B
#define IN3 9 // Sentido Motor Esquerdo A
#define IN4 11 // Sentido Motor Esquerdo B
#define Receiver 12 // Receptor Infravermelho AX-1838HS
#define LED_Pin 13 // LED Indicador de Status
// Sensores Seguidores de Linha
#define LineTeacking_Pin_Right 10
#define LineTeacking_Pin_Middle 4
#define LineTeacking_Pin_Left 2
#define LineTeacking_Read_Right !digitalRead(10)
#define LineTeacking_Read_Middle !digitalRead(4)
#define LineTeacking_Read_Left !digitalRead(2)
#define carSpeed 200
// Instanciacao dos objetos perifericos (API IRremote 2.0.1 — ver tabela-mestre)
Servo servo;
IRrecv irrecv(Receiver); // receptor no D12
decode_results results; // estrutura 2.x com .value decimal
unsigned long last_val = 0; // ultimo codigo valido (para tecla segurada)
// Codigos IR decimais (IRremote 2.0.1) — AJUSTE aos do seu controle (Licao 3.1)
#define IR_F 16736925
#define IR_B 16754775
#define IR_L 16720605
#define IR_R 16761405
#define IR_S 16712445
#define IR_UF 5316027
#define IR_UB 2747854299UL
#define IR_UL 1386468383UL
#define IR_UR 553536955UL
#define IR_US 3622325019UL
unsigned long IR_PreMillis = 0;
unsigned long LT_PreMillis = 0;
int rightDistance = 0;
int leftDistance = 0;
int middleDistance = 0;
// Maquina de Estados Finitos para Modos Operacionais
enum FUNCTIONMODE {
IDLE,
LineTeacking,
ObstaclesAvoidance,
Bluetooth,
IRremote
} func_mode = IDLE;
// Maquina de Estados Finitos para Movimentacao Cinematica
enum MOTIONMODE {
STOP,
FORWARD,
BACK,
LEFT,
RIGHT
} mov_mode = STOP;
// Funcao de atraso nao-bloqueante com sondagem concorrente de comunicacao
void delays(unsigned long t) {
for (unsigned long i = 0; i < t; i++) {
getBTData();
getIRData();
delay(1);
}
}
// Medicao telemétrica de distancia por eco ultrassonico
int getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) return 400;
return (int)(duration / 58);
}
// Rotinas de acionamento cinemático dos motores
void forward(bool debug = false) {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
if (debug) Serial.println(F("Avanco: Frente"));
}
void back(bool debug = false) {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
if (debug) Serial.println(F("Avanco: Tras"));
}
void left(bool debug = false) {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
if (debug) Serial.println(F("Giro: Esquerda"));
}
void right(bool debug = false) {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
if (debug) Serial.println(F("Giro: Direita"));
}
void stop(bool debug = false) {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
if (debug) Serial.println(F("Parada Total"));
}
// Decodificacao de comandos via Bluetooth UART
void getBTData() {
if (Serial.available()) {
char c = Serial.read();
switch (c) {
case 'f': func_mode = Bluetooth; mov_mode = FORWARD; break;
case 'b': func_mode = Bluetooth; mov_mode = BACK; break;
case 'l': func_mode = Bluetooth; mov_mode = LEFT; break;
case 'r': func_mode = Bluetooth; mov_mode = RIGHT; break;
case 's': func_mode = Bluetooth; mov_mode = STOP; break;
case '1': func_mode = LineTeacking; break;
case '2': func_mode = ObstaclesAvoidance; break;
default: break;
}
}
}
// Decodificacao de comandos do Controle Remoto IR (API 2.0.1: decode(&results)/results.value)
void getIRData() {
if (irrecv.decode(&results)) { // frame NEC valido? (2.x exige &results)
unsigned long v = results.value; // decimal (ex.: 16736925)
if (v == 0xFFFFFFFF) v = last_val; // repeticao (tecla segurada) = reusa ultimo
switch (v) {
case IR_F: case IR_UF: func_mode = IRremote; mov_mode = FORWARD; break; // frente
case IR_B: case IR_UB: func_mode = IRremote; mov_mode = BACK; break; // re
case IR_L: case IR_UL: func_mode = IRremote; mov_mode = LEFT; break; // esquerda
case IR_R: case IR_UR: func_mode = IRremote; mov_mode = RIGHT; break; // direita
case IR_S: case IR_US: func_mode = IRremote; mov_mode = STOP; break; // STOP
default: break; // tecla fora do mapa: ignora (anote-a pela Licao 3.1)
}
last_val = v; // memoriza para repeticao
delay(100); // debounce
irrecv.resume(); // libera para o proximo frame
}
}
// Execucao do Modo Teleoperado Bluetooth
void bluetooth_mode() {
if (func_mode == Bluetooth) {
switch (mov_mode) {
case FORWARD: forward(); break;
case BACK: back(); break;
case LEFT: left(); break;
case RIGHT: right(); break;
case STOP: stop(); break;
default: break;
}
}
}
// Execucao do Modo Teleoperado Infravermelho
void irremote_mode() {
if (func_mode == IRremote) {
switch (mov_mode) {
case FORWARD: forward(); break;
case BACK: back(); break;
case LEFT: left(); break;
case RIGHT: right(); break;
case STOP: stop(); break;
default: break;
}
}
}
// Execucao do Modo Autonomo Seguidor de Linha
void line_teacking_mode() {
if (func_mode == LineTeacking) {
if (LineTeacking_Read_Middle) {
forward();
LT_PreMillis = millis();
} else if (LineTeacking_Read_Right) {
right();
while (LineTeacking_Read_Right) {
getBTData();
getIRData();
}
LT_PreMillis = millis();
} else if (LineTeacking_Read_Left) {
left();
while (LineTeacking_Read_Left) {
getBTData();
getIRData();
}
LT_PreMillis = millis();
} else {
if (millis() - LT_PreMillis > 150) {
stop();
}
}
}
}
// Execucao do Modo Autonomo Desvio de Obstaculos
void obstacles_avoidance_mode() {
if (func_mode == ObstaclesAvoidance) {
servo.write(90);
delays(400);
middleDistance = getDistance();
if (middleDistance <= 40) {
stop();
delays(400);
// Varredura a direita
servo.write(10);
delays(400);
rightDistance = getDistance();
// Varredura a esquerda
servo.write(90);
delays(200);
servo.write(170);
delays(400);
leftDistance = getDistance();
// Retorno ao centro
servo.write(90);
delays(300);
// Decisao Evasiva
if (rightDistance > leftDistance) {
stop();
delay(100);
back();
delay(200);
right();
delay(300);
} else if (rightDistance < leftDistance) {
stop();
delay(100);
back();
delay(200);
left();
delay(300);
} else if ((rightDistance <= 40) || (leftDistance <= 40)) {
back();
delays(250);
} else {
forward();
}
} else {
forward();
}
}
}
void setup() {
// Inicializacao da UART para Bluetooth e Debug
Serial.begin(9600);
// Configuracao do Servo Pan-Tilt
servo.attach(SERVO_PIN, 500, 2400);
servo.write(90);
// Inicializacao do Receptor Infravermelho
irrecv.enableIRIn();
// Configuracao das portas do Sensor Ultrassonico
pinMode(ECHO_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
// Configuracao das portas da Ponte H L298N
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
// Configuracao dos sensores de linha
pinMode(LineTeacking_Pin_Right, INPUT);
pinMode(LineTeacking_Pin_Middle, INPUT);
pinMode(LineTeacking_Pin_Left, INPUT);
pinMode(LED_Pin, OUTPUT);
stop();
Serial.println(F("Firmware Integrado SmartCar_Core AD118 Pronto!"));
}
void loop() {
// Sondagem de comandos sem fio
getBTData();
getIRData();
// Execucao concorrente baseada na maquina de estados
bluetooth_mode();
irremote_mode();
line_teacking_mode();
obstacles_avoidance_mode();
}
Guia Diagnóstico de Resolução de Problemas (Troubleshooting)
A tabela diagnóstica abaixo sintetiza as principais falhas elétricas, mecânicas, de conectividade e de software encontradas durante o desenvolvimento e montagem do Kit Robô 4WD AD118, com seus respectivos procedimentos de correção de engenharia:
| Sintoma Observado | Causa Mais Provável | Procedimento de Diagnóstico e Correção de Engenharia |
|---|---|---|
| Erro ao gravar código na IDE: “avrdude: stk500_recv(): programmer is not responding” | Módulo Bluetooth conectado nos pinos D0/D1 causando conflito com o conversor USB CH340 | Desconectar temporariamente os cabos jumpers das portas RX/TX (D0 e D1) durante o Upload; reconectar somente após a conclusão da gravação. |
| O robô gira em círculos quando o comando é avançar em linha reta | Polaridade invertida na fiação dos motores DC nos bornes OUT1/OUT2 ou OUT3/OUT4 | Inverter fisicamente a posição dos fios vermelho e preto do canal de motores correspondente no borne da Ponte H L298N ou ajustar as constantes HIGH/LOW nos pinos IN1 a IN4. |
| Os motores não giram e o LED do driver L298N fica fraco ou apagado | Baterias 18650 descarregadas ou chave geral de energia desligada | Medir a tensão no borne VCC do L298N com um multímetro (deve estar entre 7,4V e 8,4V); recarregar as células 18650 no carregador externo. |
| O Arduino reinicia (reset repentino) no instante em que os motores partem | Queda abrupta de tensão (Brownout Reset) provocada pelo pico de corrente de partida (Inrush Current) | Garantir que o jumper de alimentação 5V do L298N esteja inserido; certificar-se de que a terra comum (GND) está bem conectada; adicionar um capacitor eletrolítico de a em paralelo com a linha de 5V. |
| O sensor ultrassônico retorna distâncias fixas em 0 cm ou 400 cm | Mau contato nos pinos TRIG/ECHO ou alimentação abaixo de 4,75V | Verificar se TRIG está em A5 e ECHO em A4; testar a continuidade dos cabos jumpers fêmea-fêmea; assegurar alimentação de 5V firme no barramento do Sensor Shield. |
| O robô não segue a linha preta e escapa nas curvas | Calibração de sensibilidade dos trimpots nos módulos TCRT5000 ou altura inadequada em relação ao solo | Posicionar o sensor sobre a superfície branca e ajustar o trimpot até o LED apagar; posicionar sobre a fita preta e confirmar que o LED acende; manter a altura entre 5 mm e 10 mm do chão. |
| O aplicativo mobile não encontra o dispositivo Bluetooth | Módulo HC-08 sem alimentação ou permissão de Localização/Bluetooth desativada no smartphone | Verificar se o LED vermelho do HC-08 está piscando (indicando busca); no Android, conceder permissões completas de Localização/Dispositivos Próximos para o KUONGSHUN BLE Tool.apk da Lesson 2. Validar primeiro com o bluetooth_blink (Lição 2.1): se o LED L não alternar com 'a', o problema é pareamento/APP — nunca a ponte H. |
| O controle remoto infravermelho não responde aos comandos | Película plástica de proteção da bateria CR2025 não removida ou código de tecla divergente por lote | Remover o plástico isolante da bateria do controle; carregar o sketch infrared_Blink.ino (Lição 3.1) e monitorar no Monitor Serial a 9600 baud para anotar os decimais do seu controle e ajustar os #define F/B/L/R/S da Lição 3.2. |
Erro IRremote.h: No such file or directory / does not name a type | Biblioteca IRremote ausente ou na major errada | Reinstalar pela tabela-mestre da Lição 0.3: desinstalar qualquer 3.x/4.x, instalar a 2.0.1 via ZIP da Lesson 3, conferir pasta libraries/IRremote/IRremote.h, reiniciar a IDE e recompilar. Erro has no member named 'decodedIRData' = você está com 2.0.1 e código novo; erro no matching function for call to 'IRrecv::decode(decode_results*)' = você está com 3.x/4.x e sketch do fabricante. Fixe a 2.0.1. |
pinMode(LT_R,INPUT) parece estranho / linha instável após upload | setup() original do Line_tracking_car passa a macro !digitalRead() ao pinMode | Funciona porque D2/D4/D10 já nascem como entrada, mas corrija para pinMode(10,INPUT); pinMode(4,INPUT); pinMode(2,INPUT); (nota da Lição 5.1). Depois recalibre trimpots e altura 5–10 mm. |
| Servo treme / HC-SR04 congela em 0 cm com motores ligados | Pico de corrente dos 4 motores derrubando o 5 V do Shield | Alimentar lógica pelo regulador do L298N (jumper 5 V fechado), terra comum bateria–L298N–Uno íntegra, baterias 18650 cheias (7,4–8,4 V no borne). Teste isolado: Servo_debug (Lição 4.1) com USB deve centralizar liso em 90°; se tremer só com motores, é energia. |
AUTO_GO anda, mas bluetooth_car não responde | Bluetooth ainda fora de D0/D1 ou APP pareado no dispositivo errado | Recoloque TXD→D0/RXD→D1 após o upload, chave ON, LED do HC-08 piscando, parear no KUONGSHUN BLE Tool e enviar f/b/l/r/s. Com USB plugado e Bluetooth em D0/D1, o Serial Monitor briga com o HC-08 — desplugue o USB para pilotar. |
Solução de problemas
Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Kit Robô Inteligente 4WD Completo AD118 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.