Kit Robô Inteligente 4WD Completo AD118

Kit Robô Inteligente 4WD AD118 — Curso Completo com Projetos Práticos

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 (PWMPulse 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).

Kit Robô Inteligente 4WD AD118 totalmente montado e integrado com sensores e atuadores

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).

Placa de expansão Arduino Sensor Shield V5.0 Módulo Driver de Potência com Ponte H Dupla L298N

Especificações Técnicas do Microcontrolador Arduino Uno R3

Parâmetro de EngenhariaEspecificação TécnicaObservações de Operação
Microcontrolador PrincipalATmega328P (8-bit AVR RISC)Arquitetura Harvard modificada com execução de 1 ciclo por instrução
Tensão Lógica de Operação5,0 VDCNí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ógica6 canais (A0 a A5)Resolução de 10 bits (0 a 1023 passos com VREF = 5V)
Corrente Máxima por Pino de I/O20 mA (típico), 40 mA (limite absoluto)Barramento total limitado a 200 mA
Memória Flash de Programa32 KB0,5 KB ocupados pelo bootloader Optiboot
Memória SRAM de Dados Voláteis2 KBArmazenamento dinâmico de variáveis e buffers seriais
Memória EEPROM Não-Volátil1 KBArmazenamento de parâmetros de calibração
Frequência de Clock do Núcleo16 MHz (±0,5%)Oscilador a cristal externo de alta estabilidade
Interface USB-SerialConversor CH340G / ATmega16U2Comunicação UART assíncrona full-duplex com PC e módulos

Especificações dos Módulos, Atuadores e Sensores do Robô

Subsistema / MóduloCircuito Integrado / ComponenteFaixa de OperaçãoFunção no Sistema Robótico
Driver de Potência dos MotoresCircuito Integrado Ponte H Dupla L298N5V 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:483V 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/SArduino Sensor Shield V5.05V DC (com barramento de alimentação externa)Roteamento facilitado dos pinos GPIO em padrão Signal-VCC-GND (SVG)
Transceptor Bluetooth Sem FioMódulo HC-08 BLE (Chip CC2540/CC2541)3,3V a 5V / UART 9600 bpsComunicação sem fio teleoperada com smartphone / aplicativo mobile
Receptor de InfravermelhoMódulo Sensor AX-1838HS (38 kHz)2,7V a 5,5V / Filtro de luz visívelRecepção e demodulação de comandos do controle remoto NEC
Sensor de Distância UltrassônicoMó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 VarreduraMicro Servomotor Analógico SG90 de 9g4,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 + LM3933,3V a 5V / Distância focal de 1 mm a 25 mmDetecção de contraste óptico (pista preta / fundo reflexivo claro)
Fonte de Alimentação PrimáriaSuporte Duplo para Baterias de Íon de Lítio 186507,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:

Inventário de peças e componentes mecânicos e eletrônicos do Kit Robô 4WD AD118
  • 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

  1. 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.
  2. Instalação dos Discos Encoders: Encaixe os discos perfurados de encoder nos eixos traseiros dos quatro motores TT.
Passo 1: Fixação dos suportes dos motores DC no chassi inferior Passo 2: Montagem dos quatro motores TT e discos encoders
Passo 3: Fixação estrutural dos motores com parafusos M3 Passo 4: Verificação do alinhamento dos 4 motores de tração

Passos 5 a 8: Montagem do Módulo Ponte H L298N e Sensores de Linha

  1. 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.
  2. 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).
Passo 5: Fixação do módulo driver Ponte H L298N no chassi inferior Passo 6: Instalação e alinhamento dos 3 módulos seguidores de linha TCRT5000
Passo 7: Fixação dos espaçadores sextavados de latão M3 no chassi inferior Passo 8: Fiação dos motores direito e esquerdo aos bornes do L298N

Passos 9 a 14: Montagem do Suporte Pan-Tilt, Servomotor e Sensor Ultrassônico

  1. 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.
  2. 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°.
Passo 9: Encaixe do servomotor SG90 na base do suporte pan-tilt Passo 10: Acoplamento do sensor ultrassônico HC-SR04 no suporte
Passo 11: Fixação do suporte ultrassônico articulado no chassi superior Passo 12: Instalação da placa Arduino Uno R3 no chassi superior

Passos 15 a 20: União dos Chassis, Shield V5.0, Bateria e Rodas

  1. 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.
  2. 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ô.
  3. 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.
Passo 13: Encaixe da placa Sensor Shield V5.0 sobre o Arduino Uno R3 Passo 14: Fixação do suporte de baterias 18650 com chave liga/desliga
Passo 15: Conexão dos chicotes de cabos jumpers entre o shield e os atuadores Passo 16: Conexão do módulo Bluetooth BLE HC-08 na porta serial
Passo 17: Conexão do módulo receptor infravermelho AX-1838HS Passo 18: União mecânica dos chassis com espaçadores sextavados M3
Passo 19: Encaixe sob pressão das quatro rodas de borracha 65mm Passo 20: Inspeção final do conjunto robótico 4WD totalmente montado

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.

Seleção do modelo da placa Arduino Uno e porta de comunicação COM na IDE Arduino Assistente de instalação do driver USB do Arduino Uno no sistema operacional Windows

Passo a Passo para Instalação e Primeiro Upload:

  1. Conexão Física: Conecte o cabo USB tipo A/B da placa Arduino Uno R3 à porta USB do computador.
  2. Reconhecimento do Driver USB: No Windows, caso a placa apareça como dispositivo desconhecido no Gerenciador de Dispositivos, aponte a atualização de driver para a pasta drivers dentro do diretório de instalação do Arduino (C:\Program Files (x86)\Arduino\drivers).
  3. Seleção de Placa e Porta: Na IDE Arduino, acesse o menu Ferramentas \rightarrow Placa \rightarrow Arduino Uno e selecione a porta serial correspondente em Ferramentas \rightarrow Porta \rightarrow COM[X].
  4. Gravação do Firmware: Clique no botão Carregar (Upload) para compilar o código C++ e transferir os binários via bootloader Optiboot para a memória flash do ATmega328P.
Confirmação de gravação concluída com sucesso na barra de status da IDE Arduino

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:

Diagrama esquemático oficial de ligações e cabeamento do Robô 4WD AD118

Matriz Completa de Pinagem do Sistema Robótico AD118

Porta Arduino / Shield V5.0Tipo de SinalMódulo ou Atuador ConectadoPino de Destino no DispositivoFunção e Observações Técnicas
D0 (RX)Entrada Digital / UARTMódulo Bluetooth HC-08TXDRecepção serial de dados do smartphone (9600 baud)
D1 (TX)Saída Digital / UARTMódulo Bluetooth HC-08RXDTransmissão serial de telemetria para o smartphone
D2 (S2)Entrada DigitalSeguidor de Linha #3 (Esquerdo)OUT / D0Leitura digital do sensor infravermelho esquerdo
D3 (S3)Saída Digital / PWMMicro Servomotor SG90Sinal (Fio Laranja / Amarelo)Controle angular de 0° a 180° via modulação por pulsos de 50 Hz
D4 (S4)Entrada DigitalSeguidor de Linha #2 (Centro)OUT / D0Leitura digital do sensor infravermelho central de pista
D5 (S5)Saída Digital / PWMDriver Ponte H L298NENA (Enable A)Controle de velocidade PWM dos Motores Direitos (0 a 255)
D6 (S6)Saída Digital / PWMDriver Ponte H L298NENB (Enable B)Controle de velocidade PWM dos Motores Esquerdos (0 a 255)
D7 (S7)Saída DigitalDriver Ponte H L298NIN1Controle de direção do Motor Direito (Canal A)
D8 (S8)Saída DigitalDriver Ponte H L298NIN2Controle de direção do Motor Direito (Canal A)
D9 (S9)Saída DigitalDriver Ponte H L298NIN3Controle de direção do Motor Esquerdo (Canal B)
D10 (S10)Entrada DigitalSeguidor de Linha #1 (Direito)OUT / D0Leitura digital do sensor infravermelho direito
D11 (S11)Saída DigitalDriver Ponte H L298NIN4Controle de direção do Motor Esquerdo (Canal B)
D12 (S12)Entrada DigitalMódulo Receptor IR AX-1838HSDAT / S (Sinal)Recepção dos pulsos de onda portadora demodulada em 38 kHz
D13Saída DigitalLED Onboard da Placa UnoAnodo LEDIndicador de status de firmware e depuração visual
A4Entrada DigitalSensor Ultrassônico HC-SR04ECHORecepção do pulso de eco proporcional à distância
A5Saída DigitalSensor Ultrassônico HC-SR04TRIGDisparo do trem de 8 pulsos ultrassônicos de 40 kHz
5V / VCCAlimentação LógicaBarramentos VCC dos MódulosVCC / V+Linha de 5,0 V regulada para sensores e microcontrolador
GNDReferência / TerraBarramentos GND dos MódulosGND / 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.

Módulo Driver Ponte H L298N com terminais de controle e potência Pinagem dos conectores de sinal de controle IN1 a IN4 e ENA/ENB

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:

Diagrama de blocos interno e circuito equivalente da Ponte H L298N
  1. Sentido Horário (Avanço): As chaves S1S_1 e S4S_4 são saturadas (fechadas), enquanto S2S_2 e S3S_3 permanecem em corte (abertas). A corrente flui do terminal positivo para o negativo através do enrolamento do motor.
  2. Sentido Anti-Horário (Recuo): As chaves S3S_3 e S2S_2 são saturadas, enquanto S1S_1 e S4S_4 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.
  3. Frenagem Eletrodinâmica: As chaves superiores (S1S_1 e S3S_3) ou inferiores (S2S_2 e S4S_4) 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 / ENBIN1 / IN3IN2 / IN4Estado do MotorComportamento 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 ω\omega 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 (490Hz\approx 490\,\text{Hz} nos pinos D5 e D6 do Timer0) variando a razão cíclica (Duty Cycle DD). A tensão média eficaz (VMEDIOV_{\text{MEDIO}}) entregue à carga é expressa por:

D=TONTON+TOFF=TONTPERIODO×100%D = \frac{T_{ON}}{T_{ON} + T_{OFF}} = \frac{T_{ON}}{T_{PERIODO}} \times 100\%

VMEDIO=VIN(Duty255)V_{\text{MEDIO}} = V_{IN} \cdot \left( \frac{\text{Duty}}{255} \right)

Onde:

  • Duty\text{Duty} é o valor inteiro de 8 bits fornecido à função analogWrite(pino, Duty), variando no intervalo fechado de 00 (0%0\%, motor imobilizado) a 255255 (100%100\%, tensão plena de VINV_{IN}).
  • VINV_{IN} é a tensão nominal do barramento de potência suprido pelas células de íons de lítio 18650 (VIN7,4VV_{IN} \approx 7,4\,\text{V} a 8,4V8,4\,\text{V}).

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.

Diagrama cinemático de velocidades e vetores de tração do robô 4WD Modelo geométrico de coordenadas e Centro Instantâneo de Curvatura (ICC)

1. Definição dos Sistemas de Coordenadas (Frames de Referência)

Para descrever a cinemática do robô no plano bidimensional R2\mathbb{R}^2, definimos dois referenciais ortogonais:

  1. Referencial Global / Inercial {XI,YI}\{X_I, Y_I\}: Fixado no plano de navegação (estático no ambiente).
  2. Referencial Local / Robô {XR,YR}\{X_R, Y_R\}: Fixado rigidamente no centro geométrico e de massa do chassi robótico, onde o eixo +XR+X_R aponta na direção frontal de avanço e o eixo +YR+Y_R aponta lateralmente para o lado esquerdo.

O vetor de postura (estado cinemático) do robô no referencial global é definido pela tripla:

q=[xyθ]R3\mathbf{q} = \begin{bmatrix} x \\ y \\ \theta \end{bmatrix} \in \mathbb{R}^3

Onde:

  • x,yx, y: Posição cartesiana do centro do robô em metros (m\text{m}).
  • θ\theta: Ângulo de orientação (heading / yaw) em relação ao eixo +XI+X_I global, medido em radianos (rad\text{rad}).

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étricoSímboloValor no Kit AD118Descrição Construtiva
Raio Nominal das Rodasrr33mm=0,033m33\,\text{mm} = 0,033\,\text{m}Diâmetro externo do pneu emborrachado =66mm= 66\,\text{mm}
Bitola Lateral (Track Gauge)LL150mm=0,150m150\,\text{mm} = 0,150\,\text{m}Distância transversal entre os centros de contato das rodas esquerda e direita
Distância entre Eixos (Wheelbase)BB140mm=0,140m140\,\text{mm} = 0,140\,\text{m}Distância longitudinal entre os centros dos eixos dianteiro e traseiro
Relação de Redução da Caixa de EngrenagensGG1:481:48Relação de engrenamento mecânico dos motores DC amarelos
Velocidade Angular Máxima do Motorωmotor_max\omega_{\text{motor\_max}}200RPM20,94rad/s\approx 200\,\text{RPM} \approx 20,94\,\text{rad/s}Rotação do eixo de saída em 6V6\,\text{V} com caixa 1:48

3. Cinemática Direta no Referencial Local (Forward Kinematics)

Sejam ωE\omega_E e ωD\omega_D as velocidades angulares das rodas esquerdas e direitas, respectivamente (rad/s\text{rad/s}). As velocidades lineares tangenciais correspondentes de cada lado do veículo são:

vE=rωEv_E = r \cdot \omega_E

vD=rωDv_D = r \cdot \omega_D

A velocidade linear longitudinal de translação do robô (vv) e a velocidade angular de guinada (ω=θ˙\omega = \dot{\theta}) no referencial local da estrutura são obtidas pela média e pela diferença diferencial das velocidades de cada esteira/roda:

v=vD+vE2=r(ωD+ωE)2v = \frac{v_D + v_E}{2} = \frac{r (\omega_D + \omega_E)}{2}

ω=θ˙=vDvELefetivo=r(ωDωE)Lefetivo\omega = \dot{\theta} = \frac{v_D - v_E}{L_{\text{efetivo}}} = \frac{r (\omega_D - \omega_E)}{L_{\text{efetivo}}}

Em notação matricial com a Matriz Jacobiana Cinemática Direta:

[vω]=[r2r2rLefetivorLefetivo][ωEωD]\begin{bmatrix} v \\ \omega \end{bmatrix} = \begin{bmatrix} \frac{r}{2} & \frac{r}{2} \\ -\frac{r}{L_{\text{efetivo}}} & \frac{r}{L_{\text{efetivo}}} \end{bmatrix} \begin{bmatrix} \omega_E \\ \omega_D \end{bmatrix}

4. Transformação de Coordenadas para o Referencial Global Inercial

Para mapear as velocidades do referencial móvel {XR,YR}\{X_R, Y_R\} para o referencial de navegação {XI,YI}\{X_I, Y_I\}, aplica-se a matriz de rotação R(θ)R(\theta):

q˙=[x˙y˙θ˙]=[cosθ0sinθ001][vω]=[vcosθvsinθω]\dot{\mathbf{q}} = \begin{bmatrix} \dot{x} \\ \dot{y} \\ \dot{\theta} \end{bmatrix} = \begin{bmatrix} \cos\theta & 0 \\ \sin\theta & 0 \\ 0 & 1 \end{bmatrix} \begin{bmatrix} v \\ \omega \end{bmatrix} = \begin{bmatrix} v \cos\theta \\ v \sin\theta \\ \omega \end{bmatrix}

Expandindo em termos das velocidades angulares individuais das rodas (ωE,ωD\omega_E, \omega_D):

[x˙y˙θ˙]=[r2cosθr2cosθr2sinθr2sinθrLefetivorLefetivo][ωEωD]\begin{bmatrix} \dot{x} \\ \dot{y} \\ \dot{\theta} \end{bmatrix} = \begin{bmatrix} \frac{r}{2}\cos\theta & \frac{r}{2}\cos\theta \\ \frac{r}{2}\sin\theta & \frac{r}{2}\sin\theta \\ -\frac{r}{L_{\text{efetivo}}} & \frac{r}{L_{\text{efetivo}}} \end{bmatrix} \begin{bmatrix} \omega_E \\ \omega_D \end{bmatrix}

5. Cinemática Inversa (Inverse Kinematics)

A cinemática inversa calcula as velocidades lineares (vE,vDv_E, v_D) e angulares (ωE,ωD\omega_E, \omega_D) que o microcontrolador deve exigir de cada conjunto de motores para que o robô atinja uma velocidade de translação linear vv (m/s\text{m/s}) e uma taxa de giro ω\omega (rad/s\text{rad/s}) arbitrárias:

vE=vωLefetivo2    ωE=1r(vωLefetivo2)v_E = v - \frac{\omega \cdot L_{\text{efetivo}}}{2} \implies \omega_E = \frac{1}{r} \left( v - \frac{\omega \cdot L_{\text{efetivo}}}{2} \right)

vD=v+ωLefetivo2    ωD=1r(v+ωLefetivo2)v_D = v + \frac{\omega \cdot L_{\text{efetivo}}}{2} \implies \omega_D = \frac{1}{r} \left( v + \frac{\omega \cdot L_{\text{efetivo}}}{2} \right)

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 (RR), medido do centro do robô ao ICC, é dado por:

R=vω=Lefetivo2(vD+vEvDvE)R = \frac{v}{\omega} = \frac{L_{\text{efetivo}}}{2} \cdot \left( \frac{v_D + v_E}{v_D - v_E} \right)

As coordenadas globais do ponto ICC no espaço são calculadas por:

ICC=[ICCxICCy]=[xRsinθy+Rcosθ]\mathbf{ICC} = \begin{bmatrix} ICC_x \\ ICC_y \end{bmatrix} = \begin{bmatrix} x - R \sin\theta \\ y + R \cos\theta \end{bmatrix}

Analisando a equação do raio RR, identificamos três regimes cinemáticos fundamentais executados pelo Kit AD118:

  1. Translação Retilínea Pura:
    • Condição: ωE=ωD    vDvE=0\omega_E = \omega_D \implies v_D - v_E = 0
    • Resultado: RR \to \infty e ω=0\omega = 0. O robô desloca-se em linha reta com velocidade v=rωDv = r \cdot \omega_D.
  2. Giro Pivot em Torno do Eixo Central (Zero-Radius Turn):
    • Condição: ωE=ωD    vE=vD\omega_E = -\omega_D \implies v_E = -v_D
    • Resultado: R=0R = 0 e v=0v = 0. O ICC coincide perfeitamente com o centro geométrico do robô. O veículo gira no próprio local com velocidade angular máxima ω=2vDLefetivo\omega = \frac{2 v_D}{L_{\text{efetivo}}}.
  3. Curva Diferencial com Raio Finito RR:
    • Condição: ωEωD\omega_E \neq \omega_D (ambos com mesmo sinal)
    • Resultado: O robô executa trajetória curvilínea suave. O lado com maior velocidade orbita no raio externo (R+L2R + \frac{L}{2}) e o lado mais lento percorre o raio interno (RL2R - \frac{L}{2}).

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 (ωE1=ωE2=ωE\omega_{E1} = \omega_{E2} = \omega_E). Como a distância longitudinal entre eixos (B=140mmB = 140\,\text{mm}) 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 MatritoM_{\text{atrito}} proporcional ao coeficiente de atrito pneu-solo (μ\mu) e à massa total do robô (mm):

MatritoμmgB4M_{\text{atrito}} \approx \frac{\mu \cdot m \cdot g \cdot B}{4}

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 (LefetivoL_{\text{efetivo}}):

Lefetivo=χLL_{\text{efetivo}} = \chi \cdot L

Onde χ1,0\chi \ge 1,0 é o coeficiente empírico de derrapagem. Em pisos lisos como cerâmica ou madeira polida, χ1,15\chi \approx 1,15 a 1,251,25. Em carpetes de alto atrito, χ1,4\chi \approx 1,4 a 1,61,6, 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 vEv_E e vDv_D 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 PWMmin60\text{PWM}_{\text{min}} \approx 60. O algoritmo de conversão linear proporcional implementado no microcontrolador é expresso por:

PWMi={0,se vi=0constrain(PWMmin+vivmax(255PWMmin),0,255),se vi>0\text{PWM}_i = \begin{cases} 0, & \text{se } v_i = 0 \\ \text{constrain}\left( \text{PWM}_{\text{min}} + \frac{|v_i|}{v_{\text{max}}} \cdot (255 - \text{PWM}_{\text{min}}),\, 0,\, 255 \right), & \text{se } |v_i| > 0 \end{cases}

Onde i{E,D}i \in \{E, D\} e vmax=rωmax0,033m×20,94rad/s0,69m/sv_{\text{max}} = r \cdot \omega_{\text{max}} \approx 0,033\,\text{m} \times 20,94\,\text{rad/s} \approx 0,69\,\text{m/s} (2,5km/h\approx 2,5\,\text{km/h}).


Lição 1.1: Movimentação Básica e Teste Unitário dos Motores

Este primeiro programa de validação executa uma rotina contínua de movimentação, acionando o robô para frente por 2 segundos e para trás por 2 segundos.

Código-Fonte Completo Comentado: forward_back.ino

/*
 * =====================================================================================
 * 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: Rotação Diferencial e Curvas Pivot

Para efetuar curvas no local (Zero-Radius Pivot Turn), as rodas de um dos lados do chassi devem tracionar para frente enquanto as rodas do lado oposto tracionam para trás com a mesma intensidade de torque.

Execução do giro pivot pelo robô 4WD AD118 através de rotação diferencial dos motores

Código-Fonte Completo Comentado: left_wheel_rotation.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.3: Controle Gradual de Velocidade via Modulação PWM

Nesta prática, 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.

Código-Fonte Completo Comentado: speed_control.ino

/*
 * =====================================================================================
 * 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.

Módulo transceptor Bluetooth Low Energy HC-08 Pinagem de comunicação serial UART do módulo Bluetooth HC-08

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 \rightarrow Pino D0 (RX) do Arduino: Transmite dados recebidos pelo rádio Bluetooth para o buffer serial do microcontrolador.
  • Linha RXD do HC-08 \leftarrow Pino D1 (TX) do Arduino: Envia caracteres de telemetria do microcontrolador para o ar.
  • Baud Rate Padrão: 9600bps9600\,\text{bps} (8 bits de dados, sem paridade, 1 stop bit — 8-N-1).
Tela inicial de busca de dispositivos Bluetooth no aplicativo Kuongshun Interface de controle por volante virtual no aplicativo móvel

Protocolo de Comandos ASCII Transmitidos pelo Aplicativo

Caractere ASCII RecebidoCódigo HexAção Executada pelo FirmwareComportamento Cinemático
'f'0x66forward()Todos os 4 motores giram para frente na velocidade padrão
'b'0x62back()Todos os 4 motores giram para trás
'l'0x6Cleft()Giro no próprio eixo para a esquerda (Pivot Left)
'r'0x72right()Giro no próprio eixo para a direita (Pivot Right)
's'0x73stop()Motores desenergizados instantaneamente
'1'0x31Modo Seguidor de LinhaChaveia a máquina de estados para modo autônomo de pista
'2'0x32Modo Desvio de ObstáculosChaveia 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.


Código-Fonte Completo Comentado: bluetooth_car.ino

/*
 * =====================================================================================
 * 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 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.

Diagrama em blocos e pinagem do módulo receptor infravermelho AX-1838HS Mapeamento dos botões do controle remoto infravermelho multifunção de 21 teclas

Teoria da Transmissão Óptica Infravermelha e Protocolo NEC

O controle remoto emite pulsos de luz invisível no espectro infravermelho (λ940nm\lambda \approx 940\,\text{nm}) modulados em uma onda portadora de alta frequência (38kHz38\,\text{kHz}). 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):

  1. Leader Code: Pulso de rajada contínua de 9 ms seguido por uma pausa de 4,5 ms em nível alto.
  2. Endereço do Dispositivo (8 bits): Identificador exclusivo do controle remoto.
  3. Endereço Invertido (~Endereço, 8 bits): Verificação de integridade (checksum por complemento de um).
  4. Comando da Tecla (8 bits): Identificador da tecla pressionada.
  5. Comando Invertido (~Comando, 8 bits): Validação contra erros de transmissão.
  6. Bit Lógico ‘0’: Pulso de 562,5 μ\mus seguido por pausa de 562,5 μ\mus (tempo total de 1,125 ms).
  7. Bit Lógico ‘1’: Pulso de 562,5 μ\mus seguido por pausa de 1687,5 μ\mus (tempo total de 2,25 ms).
Forma de onda do protocolo NEC e temporização dos pulsos lógicos

Tabela de Códigos Hexadecimais das 21 Teclas do Controle AD118

Tecla do Controle RemotoCódigo Decodificado (Raw Hex)Ação Associada no Robô 4WD
▲ (UP / Frente)0xB946FF00Movimenta o robô para frente (forward)
▼ (DOWN / Ré)0xEA15FF00Movimenta o robô para trás (back)
◄ (LEFT / Esquerda)0xBB44FF00Giro pivot para a esquerda (left)
► (RIGHT / Direita)0xBC43FF00Giro pivot para a direita (right)
OK / STOP0xBF40FF00Parada imediata dos motores (stop)
Tecla ‘1’0xE916FF00Ativa Modo Autônomo com Desvio de Obstáculos
Tecla ‘2’0xE619FF00Ativa Modo Autônomo Seguidor de Linha
Tecla ‘3’0xF20DFF00Função auxiliar / Teste de sensores
Tecla ‘4’0xF30CFF00Incrementa velocidade (+10 PWM)
Tecla ‘5’0xE718FF00Velocidade padrão (PWM = 200)
Tecla ‘6’0xA15EFF00Decrementa velocidade (-10 PWM)
Tecla ‘0’0xAD52FF00Desativa todos os modos autônomos (IDLE)
Tecla ’*’0xBD42FF00Varredura angular rápida do servo pan-tilt
Tecla ’#’0xB54AFF00Buzzer sonoro / Indicação de status

Lição 3.1: Captura e Depuração de Teclas IR no Monitor Serial

Este sketch utiliza a biblioteca oficial IRremote para capturar os pacotes recebidos pelo pino D12 e exibir os valores hexadecimais no Monitor Serial.

Código-Fonte Completo Comentado: infrared_Blink.ino

/*
 * =====================================================================================
 * Projeto: Captura e Decodificacao de Teclas Infravermelhas (Robo 4WD AD118)
 * Autor: Engenharia RoboBuilders
 * Plataforma: Arduino Uno R3 + Sensor AX-1838HS no pino D12
 * Descricao: Le os sinais do controle remoto e exibe os codigos hexadecimais na UART
 * =====================================================================================
 */

#include <IRremote.h>

// Pino conectado ao pino Signal do receptor infravermelho
#define RECV_PIN 12

// Instancia do objeto receptor da biblioteca IRremote
IRrecv receptorIR(RECV_PIN);

// Variavel para memorizar o ultimo codigo valido recebido em caso de repeticao
uint32_t ultimoCodigoValido = 0;

void setup() {
  Serial.begin(9600);
  
  // Habilita a interrupcao por temporizador para recepcao de pulsos IR
  receptorIR.enableIRIn();
  
  Serial.println(F("Receptor Infravermelho Inicializado no Pino D12."));
  Serial.println(F("Aponte o controle remoto e pressione qualquer tecla..."));
}

void loop() {
  // Verifica se um pacote IR valido foi demodulado
  if (receptorIR.decode()) {
    
    // Tratamento de codigo de repeticao (quando o usuario segura a tecla pressionada)
    if (receptorIR.decodedIRData.flags) {
      receptorIR.decodedIRData.decodedRawData = ultimoCodigoValido;
      Serial.println(F("[IR] Tecla mantida pressionada (Codigo de Repeticao)."));
    } else {
      // Exibe o codigo bruto em notacao hexadecimal
      Serial.print(F("[IR] Codigo Recebido: 0x"));
      Serial.println(receptorIR.decodedIRData.decodedRawData, HEX);
    }

    // Identificacao nominal da tecla pressionada
    switch (receptorIR.decodedIRData.decodedRawData) {
      case 0xB946FF00: Serial.println(F(">> Tecla: UP (Avanco)")); break;
      case 0xEA15FF00: Serial.println(F(">> Tecla: DOWN (Recuo)")); break;
      case 0xBB44FF00: Serial.println(F(">> Tecla: LEFT (Esquerda)")); break;
      case 0xBC43FF00: Serial.println(F(">> Tecla: RIGHT (Direita)")); break;
      case 0xBF40FF00: Serial.println(F(">> Tecla: OK / STOP")); break;
      case 0xE916FF00: Serial.println(F(">> Tecla: 1 (Desvio Obstaculos)")); break;
      case 0xE619FF00: Serial.println(F(">> Tecla: 2 (Seguidor Linha)")); break;
      default:
        Serial.println(F(">> Outra tecla detectada."));
        break;
    }

    // Salva o codigo atual para uso na flag de repeticao
    ultimoCodigoValido = receptorIR.decodedIRData.decodedRawData;
    
    // Pequeno atraso para filtragem de repiques
    delay(100);
    
    // Prepara o buffer para receber a proxima transmissao
    receptorIR.resume();
  }
}

Lição 3.2: Controle Manual Completo do Robô via Controle Remoto IR

Código-Fonte Completo Comentado: Infrared_remote_control_car.ino

/*
 * =====================================================================================
 * Projeto: Navegacao Completa por Controle Remoto IR (Robo 4WD AD118)
 * Autor: Engenharia RoboBuilders
 * Plataforma: Arduino Uno R3 + Receptor AX-1838HS + Driver L298N
 * =====================================================================================
 */

#include <IRremote.h>

#define RECV_PIN 12
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

#define carSpeed 200

IRrecv receptorIR(RECV_PIN);
uint32_t ultimoCodigoValido = 0;

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 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);
  receptorIR.enableIRIn();

  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  stop();
}

void loop() {
  if (receptorIR.decode()) {
    if (receptorIR.decodedIRData.flags) {
      receptorIR.decodedIRData.decodedRawData = ultimoCodigoValido;
    }

    switch (receptorIR.decodedIRData.decodedRawData) {
      case 0xB946FF00: forward(); break; // Tecla UP
      case 0xEA15FF00: back();    break; // Tecla DOWN
      case 0xBB44FF00: left();    break; // Tecla LEFT
      case 0xBC43FF00: right();   break; // Tecla RIGHT
      case 0xBF40FF00: stop();    break; // Tecla OK
      default: break;
    }

    ultimoCodigoValido = receptorIR.decodedIRData.decodedRawData;
    delay(100);
    receptorIR.resume();
  }
}

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.

Transdutor ultrassônico HC-SR04 com pinos VCC, Trig, Echo e GND Mecanismo de montagem do servomotor SG90 com suporte 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 (f=40kHzf = 40\,\text{kHz}). O processo telemétrico ocorre em quatro etapas:

  1. O microcontrolador envia um pulso em nível alto (HIGH) de pelo menos 10μs10\,\mu\text{s} no pino TRIG.
  2. O módulo gera internamente um trem de 8 pulsos ultrassônicos senoidais a 40 kHz.
  3. O pino ECHO comuta para nível alto (HIGH) e permanece nesse estado até que o eco refletido seja captado pelo transdutor receptor.
  4. A largura temporal do pulso (Δt\Delta t) no pino ECHO é diretamente proporcional ao dobro da distância percorrida pela onda mecânica (ida e volta).
Diagrama de temporização dos pulsos de Trigger e Echo do sensor HC-SR04

Dedução Matemática da Distância Telemétrica

Considerando a velocidade de propagação do som no ar à temperatura ambiente (T20CT \approx 20^\circ\text{C}), dada por vsom340m/s=0,0340cm/\musv_{\text{som}} \approx 340\,\text{m/s} = 0,0340\,\text{cm/\mu s}:

d=vsomΔt2d = \frac{v_{\text{som}} \cdot \Delta t}{2}

d=0,0340cm/\musΔt2=Δt58,82Δt58cmd = \frac{0,0340\,\text{cm/\mu s} \cdot \Delta t}{2} = \frac{\Delta t}{58,82} \approx \frac{\Delta t}{58}\,\text{cm}

Onde:

  • dd é a distância calculada do obstáculo em centímetros (cm\text{cm}).
  • Δt\Delta t é a duração do pulso em microssegundos (μs\mu\text{s}) 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 50Hz50\,\text{Hz} (período T=20msT = 20\,\text{ms}):

  • Pulso de 0,5ms0,5\,\text{ms} (500μs500\,\mu\text{s}) posiciona o servo no batente de (totalmente à direita).
  • Pulso de 1,45ms1,45\,\text{ms} (1450μs1450\,\mu\text{s} a 1500μs1500\,\mu\text{s}) posiciona o servo na posição central de 90° (visão frontal).
  • Pulso de 2,4ms2,4\,\text{ms} (2400μs2400\,\mu\text{s}) posiciona o servo no batente de 180° (totalmente à esquerda).

Lição 4.1: Calibração e Centralização Angular do Servomotor

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.

Código-Fonte Completo Comentado: 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:

  1. O robô avança com o servo apontado para frente (9090^\circ).
  2. Se a distância frontal for inferior a 40 cm, o robô freia instantaneamente.
  3. O servo gira para a direita (1010^\circ) e mede a distância lateral direita (dDd_D).
  4. O servo gira para a esquerda (170170^\circ) e mede a distância lateral esquerda (dEd_E).
  5. O microcontrolador compara as distâncias:
    • Se dD>dEd_D > d_E: recua brevemente e gira à direita.
    • Se dE>dDd_E > d_D: recua brevemente e gira à esquerda.
    • Se ambos os caminhos estiverem bloqueados (dD40cmd_D \le 40\,\text{cm} e dE40cmd_E \le 40\,\text{cm}): executa manobra de ré estendida.
Varredura angular do sensor ultrassônico voltado para a direita (10 graus) Varredura angular do sensor ultrassônico voltado para a esquerda (170 graus)

Código-Fonte Completo Comentado: Obstacle_Avoidance_Car.ino

/*
 * =====================================================================================
 * Projeto: Navegacao Autonoma Anti-Colisao com Sensor Ultrassonico (Robo 4WD AD118)
 * Autor: Engenharia RoboBuilders
 * Plataforma: Arduino Uno R3 + HC-SR04 + Servo SG90 + Driver L298N
 * =====================================================================================
 */

#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 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ô.

Construção de pista de testes com fita isolante preta de alta absorção Módulo óptico reflexivo TCRT5000 com comparador LM393 e trimpot de ajuste

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:

  1. 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).
  2. 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).
Diagrama esquemático do módulo TCRT5000 com comparador analógico LM393

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 fitaAvança reto em velocidade plena (forward())
0 (Branco)1 (Linha)1 (Linha)Início de desvio para a esquerdaCorreção suave para a direita (right())
0 (Branco)0 (Branco)1 (Linha)Desvio pronunciado para a esquerdaRotação rápida à direita até centralizar
1 (Linha)1 (Linha)0 (Branco)Início de desvio para a direitaCorreção suave para a esquerda (left())
1 (Linha)0 (Branco)0 (Branco)Desvio pronunciado para a direitaRotação rápida à esquerda até centralizar
0 (Branco)0 (Branco)0 (Branco)Perda total de linha / CruzamentoMantém última ação ou freia por timeout
1 (Linha)1 (Linha)1 (Linha)Interseção perpendicular em TMantém avanço ou executa parada programada

Código-Fonte Completo Comentado: Line_tracking_car.ino

/*
 * =====================================================================================
 * Projeto: Seguidor de Linha Autonomo com 3 Sensores TCRT5000 (Robo 4WD AD118)
 * Autor: Engenharia RoboBuilders
 * Plataforma: Arduino Uno R3 + 3x Sensores TCRT5000 + Driver L298N
 * =====================================================================================
 */

#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_R\right) {
    right();
    // Permanece corrigindo enquanto o sensor direito estiver sobre a linha
    while (LineTracking_Read_R\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
    }
  }
}

Módulo 6 — Firmware Multifunção Integrado (SmartCar_Core)

O firmware integrado SmartCar_Core representa a convergência de todos os subsistemas de controle e sensoriamento desenvolvidos nas lições anteriores em uma Máquina de Estados Finitos (FSM — Finite State Machine) de nível profissional. O sistema é capaz de alternar instantaneamente entre modos de controle manual (Bluetooth e IR) e modos autônomos (Seguidor de Linha e Desvio de Obstáculos) através de comandos sem fio em tempo real, sem necessidade de regravação ou reinicialização do microcontrolador.

Estrutura arquitetural do firmware integrado unificado SmartCar_Core Controle simultâneo por aplicativo BLE e controle remoto infravermelho

Arquitetura de Software do Firmware Concorrente

O sistema é estruturado em duas enumerações de controle de alto nível:

  1. enum FUNCTIONMODE: Define o modo operacional corrente do robô (IDLE, LineTeacking, ObstaclesAvoidance, Bluetooth, IRremote).
  2. 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>
#include <Servo.h>

// 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
Servo servo;
IRrecv irrecv(Receiver);
uint32_t last_decodedRawData = 0;
decode_results results;

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
void getIRData() {
  if (irrecv.decode()) {
    if (irrecv.decodedIRData.flags) {
      irrecv.decodedIRData.decodedRawData = last_decodedRawData;
    }
    
    switch (irrecv.decodedIRData.decodedRawData) {
      case 0xB946FF00: func_mode = IRremote; mov_mode = FORWARD; break; // Tecla UP
      case 0xEA15FF00: func_mode = IRremote; mov_mode = BACK;    break; // Tecla DOWN
      case 0xBB44FF00: func_mode = IRremote; mov_mode = LEFT;    break; // Tecla LEFT
      case 0xBC43FF00: func_mode = IRremote; mov_mode = RIGHT;   break; // Tecla RIGHT
      case 0xBF40FF00: func_mode = IRremote; mov_mode = STOP;    break; // Tecla OK
      case 0xE916FF00: func_mode = ObstaclesAvoidance;           break; // Tecla 1
      case 0xE619FF00: func_mode = LineTeacking;                 break; // Tecla 2
      case 0xAD52FF00: func_mode = IDLE; mov_mode = STOP;        break; // Tecla 0
      default: break;
    }
    
    last_decodedRawData = irrecv.decodedIRData.decodedRawData;
    delay(100);
    irrecv.resume();
  }
}

// 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_R\right) {
      right();
      while (LineTeacking_Read_R\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 ObservadoCausa Mais ProvávelProcedimento 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 CH340Desconectar 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 retaPolaridade invertida na fiação dos motores DC nos bornes OUT1/OUT2 ou OUT3/OUT4Inverter 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 apagadoBaterias 18650 descarregadas ou chave geral de energia desligadaMedir 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 partemQueda 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 100μF100\,\mu\text{F} a 470μF470\,\mu\text{F} em paralelo com a linha de 5V.
O sensor ultrassônico retorna distâncias fixas em 0 cm ou 400 cmMau contato nos pinos TRIG/ECHO ou alimentação abaixo de 4,75VVerificar 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 curvasCalibração de sensibilidade dos trimpots nos módulos TCRT5000 ou altura inadequada em relação ao soloPosicionar 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 BluetoothMódulo HC-08 sem alimentação ou permissão de Localização/Bluetooth desativada no smartphoneVerificar se o LED vermelho do HC-08 está piscando (indicando busca); no Android/iOS, conceder permissões completas de Localização/Dispositivos Próximos para o aplicativo Kuongshun.
O controle remoto infravermelho não responde aos comandosPelícula plástica de proteção da bateria CR2025 não removida ou código de tecla divergenteRemover o plástico isolante da bateria do controle; carregar o sketch infrared_Blink.ino e monitorar no Monitor Serial para validar se os códigos conferem com a tabela NEC.

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.