Início›Projetos›Robô com LCD
⬤ Projeto Integrado · LCD + 2 Motores DC

🤖 Robô com Telemetria no LCD

⏱️ 60–75 min 🧩 2× Motor DC · LCD 20×4 · Sensor de obstáculos · Chassis diferencial

Nesta página

🎯 Objetivo e Resultado

Chassis diferencial com dois motores DC que navega de forma autónoma evitando obstáculos. O LCD exibe em tempo real: velocidade de cada roda (esq/dir), modo de operação (AUTO ou MANUAL via Serial), estado do sensor de obstáculos, direção atual e contador de obstáculos evitados.

Esq:200 Dir:200 FRENTE Livre Modo:AUTO Obst: 7 PR.FT9_5 Robô

🔌 Ligações

ComponentePino ArduinoNota
LCD 20×4 (I2C)A4 (SDA) / A5 (SCL)Endereço 0x27
Motor esquerdo (M1)Terminais M1+/M1−Canal 1 — D3(PWM), D4, D8
Motor direito (M2)Terminais M2+/M2−Canal 2 — D11(PWM), D7, D2
Sensor obstáculos IRD5 (INPUT)LOW = obstáculo detectado
Botão MODOD6 (INPUT_PULLUP)Alterna AUTO / MANUAL
⚠️
Dois motores DC em simultâneo consomem bastante corrente. Se o Arduino reiniciar ou o LCD flickejar ao ligar os motores, alimenta os motores por fonte externa (5–6V DC) ligada ao terminal VM da placa, com GND comum ao Arduino.

🔨 Fases de Montagem

Fase 1 — Chassis e testes individuais

Monta os dois motores no chassis. Liga cada um separadamente e testa FORWARD/BACKWARD com AF_DCMotor. Confirma qual é o motor esquerdo e direito.

Fase 2 — LCD com telemetria básica

Exibe velocidade esq/dir nas linhas 0 e 1. Confirma sem flickering. Usa a função mover() que actualiza o LCD internamente.

Fase 3 — Sensor de obstáculos

Liga o sensor (D5). Testa com Serial Monitor: digitalRead(5) deve ser LOW ao tapar o sensor. Implementa paragem + desvio.

Fase 4 — Modo MANUAL por Serial

Aceita comandos 'F' 'B' 'L' 'R' 'S' via Monitor Série. O botão D6 alterna entre AUTO e MANUAL. Ambos mostram estado no LCD.

Fase 5 — Dashboard completo

Integra contador de obstáculos e modos de operação nas 4 linhas. Usa millis() para actualizar o display independentemente dos motores.

💻 Código Completo

proj_robo_display.ino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AFMotor.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);
AF_DCMotor mE(1), mD(2);   // esquerdo M1, direito M2

#define SENSOR_PIN 5
#define BTN_MODO   6

bool          modoAuto  = true;
int           velE=0, velD=0;
int           nObst     = 0;
unsigned long tModo=0, tLCD=0;

// ── Movimento com actualização automática de velocidade ──────────
void mover(int ve, int vd, uint8_t de, uint8_t dd) {
  velE=ve; velD=vd;
  mE.setSpeed(ve); mE.run(de);
  mD.setSpeed(vd); mD.run(dd);
}

// ── Movimentos base ───────────────────────────────────────────────
void frente()   { mover(200,200,FORWARD, FORWARD ); }
void re()       { mover(180,180,BACKWARD,BACKWARD); }
void esquerda() { mover(180,180,BACKWARD,FORWARD ); }
void direita()  { mover(180,180,FORWARD, BACKWARD); }
void parar()    { mE.run(RELEASE); mD.run(RELEASE); velE=velD=0; }

// ── Dashboard LCD ─────────────────────────────────────────────────
void dashboard(const char* dirLabel, const char* sensorLabel) {
  lcd.setCursor(0,0);
  lcd.print("Esq:");lcd.print(velE);lcd.print("   Dir:");lcd.print(velD);lcd.print("   ");

  lcd.setCursor(0,1);
  lcd.print(dirLabel);lcd.print("  ");lcd.print(sensorLabel);lcd.print("   ");

  lcd.setCursor(0,2);
  lcd.print("Modo:");lcd.print(modoAuto?"AUTO ":"MAN  ");
  lcd.print(" Obst:");lcd.print(nObst);lcd.print("  ");

  lcd.setCursor(0,3);
  lcd.print("PR.FT9_5  t:");lcd.print(millis()/1000);lcd.print("s   ");
}

void setup() {
  lcd.init(); lcd.backlight();
  pinMode(SENSOR_PIN, INPUT);
  pinMode(BTN_MODO,   INPUT_PULLUP);
  Serial.begin(9600);
  lcd.setCursor(2,1); lcd.print("Robo LCD Pronto");
  delay(1500);
  lcd.clear();
}

void loop() {
  // Botão MODO — alterna AUTO/MANUAL
  if(digitalRead(BTN_MODO)==LOW && millis()-tModo>400) {
    modoAuto=!modoAuto; parar(); tModo=millis();
  }

  bool obst = (digitalRead(SENSOR_PIN) == LOW);

  if (modoAuto) {
    // ── MODO AUTÓNOMO ───────────────────────────────────────────
    if (obst) {
      nObst++;
      parar();   dashboard("BRAKE    ","OBST! "); delay(200);
      re();      dashboard("RE       ","OBST! "); delay(500);
      direita(); dashboard("VIRAR DIR","OBST! "); delay(600);
    } else {
      frente(); dashboard("FRENTE   ","Livre ");
    }
  } else {
    // ── MODO MANUAL via Serial ──────────────────────────────────
    if(Serial.available()) {
      char c = Serial.read();
      const char* dir = "PARADO   ";
      switch(c) {
        case 'F': frente();    dir="FRENTE   "; break;
        case 'B': re();         dir="RE       "; break;
        case 'L': esquerda(); dir="ESQUERDA "; break;
        case 'R': direita();   dir="DIREITA  "; break;
        case 'S': parar();     dir="PARADO   "; break;
      }
      dashboard(dir, obst?"OBST! ":"Livre ");
    }
  }

  delay(50);
}

📊 Dashboard de Telemetria — Resultado Final

Esq:200 Dir:200 FRENTE Livre Modo:AUTO Obst: 7 PR.FT9_5 t:142s

Em modo MANUAL, envia comandos pelo Monitor Série (9600 baud):

TeclaMovimentoEfeito nos motores
FFrenteM1 FWD 200 · M2 FWD 200
BRéM1 BWD 180 · M2 BWD 180
LEsquerda (rotação)M1 BWD 180 · M2 FWD 180
RDireita (rotação)M1 FWD 180 · M2 BWD 180
SStopM1 RELEASE · M2 RELEASE

🚀 Como Expandir

🏆 Para ir mais longe

PR.FT9_5 · LCD 20×4 · L293D Motor Driver · Arduino UNO Rev3 · Início · led.dge.medu.pt