⬤ Motor DC · Avançado
📡 Motor Controlado por Sensor
⏱️ 35 min
🧩 Sensor → Motor · Realimentação · Paragem de emergência · LCD
🚧 Sensor de Obstáculos → Motor
ℹ️A combinação sensor→motor cria um sistema de malha fechada: o sensor mede o estado real do ambiente e o motor actua para o alterar. É a base de robótica autónoma e automação industrial.
ex_motor_sensor.ino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AFMotor.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
AF_DCMotor motor(1);
#define SENSOR_PIN 5 // Sensor IR — LOW = obstáculo
#define VEL_NORMAL 180
void setup() {
lcd.init(); lcd.backlight();
pinMode(SENSOR_PIN, INPUT);
motor.setSpeed(VEL_NORMAL);
motor.run(FORWARD);
lcd.setCursor(0,0); lcd.print("Motor + Sensor IR ");
}
void loop() {
bool obst = (digitalRead(SENSOR_PIN) == LOW);
if (obst) {
// Obstáculo: para, recua 0.5s, vira direita 0.5s
motor.run(BRAKE);
lcd.setCursor(0,1); lcd.print("OBSTACULO! BRAKE ");
lcd.setCursor(0,2); lcd.print("A desviar... ");
lcd.noBacklight(); delay(150);
lcd.backlight(); delay(150); // pisca como alerta
motor.run(BACKWARD); delay(500);
motor.run(RELEASE);
delay(300);
} else {
motor.setSpeed(VEL_NORMAL);
motor.run(FORWARD);
lcd.setCursor(0,1); lcd.print("A CORRER FORWARD ");
lcd.setCursor(0,2); lcd.print("Vel: 180 Livre ");
}
}
📏 Controlo Proporcional — Velocidade por Distância
💡Controlo proporcional: a velocidade do motor é proporcional ao erro (diferença entre valor desejado e valor medido). Quanto maior o erro, maior a velocidade de correcção. É o 'P' do controlador PID.
ex_motor_prop.ino
// Controlo proporcional com LDR — simula sensor de distância
// Setpoint: LDR a 500. Motor ajusta velocidade para manter esse valor.
#define LDR_PIN A0
#define SETPOINT 500 // Valor-alvo de luminosidade
#define KP 0.4 // Ganho proporcional
#define VEL_MIN 40
#define VEL_MAX 220
void loop() {
int ldr = analogRead(LDR_PIN);
int erro = SETPOINT - ldr; // positivo: muito escuro
int vel = (int)(KP * abs(erro));
vel = constrain(vel, VEL_MIN, VEL_MAX);
if(abs(erro) < 20) { // zona morta — não actua
motor.run(RELEASE);
lcd.setCursor(0,1); lcd.print("Zona morta — OK ");
} else if(erro > 0) {
motor.setSpeed(vel); motor.run(FORWARD);
lcd.setCursor(0,1); lcd.print("FORWARD vel:");lcd.print(vel);lcd.print(" ");
} else {
motor.setSpeed(vel); motor.run(BACKWARD);
lcd.setCursor(0,1); lcd.print("BACKWARD vel:");lcd.print(vel);lcd.print(" ");
}
lcd.setCursor(0,2); lcd.print("LDR:");lcd.print(ldr);
lcd.print(" Err:");lcd.print(erro);lcd.print(" ");
delay(80);
}
🔴 Sistema de Paragem de Emergência
ex_emergencia.ino
#define BTN_EMG 6 // INPUT_PULLUP — pressionar = emergência
bool emergencia = false;
void verificarEmergencia() {
if(digitalRead(BTN_EMG) == LOW || emergencia) {
motor.run(BRAKE);
emergencia = true;
lcd.setCursor(0,3); lcd.print("** EMERGENCIA!! ** ");
lcd.noBacklight(); delay(200);
lcd.backlight(); delay(200);
// Loop infinito — só reset do Arduino liberta
}
}
void loop() {
verificarEmergencia(); // SEMPRE a primeira instrução do loop
// ... código normal do motor ...
}
📊 Introdução ao Controlo PID
| Componente | Sigla | O que faz | Efeito |
| Proporcional | P | Actua proporcional ao erro actual | Correcção rápida mas pode oscilar |
| Integral | I | Actua sobre o erro acumulado ao longo do tempo | Elimina erro estacionário |
| Derivativo | D | Actua sobre a taxa de variação do erro | Amorte as oscilações |
pid_basico.ino
// PID simples — exemplo educativo
float Kp=0.4, Ki=0.05, Kd=0.1;
float erroAnt=0, integral=0;
int pid(int setpoint, int medicao) {
float erro = setpoint - medicao;
integral += erro;
float derivada = erro - erroAnt;
erroAnt = erro;
float saida = Kp*erro + Ki*integral + Kd*derivada;
return constrain((int)saida, -255, 255);
}
void loop() {
int ldr = analogRead(A0);
int u = pid(500, ldr); // saída: negativo=BWD, positivo=FWD
motor.setSpeed(abs(u));
motor.run(u > 0 ? FORWARD : BACKWARD);
lcd.setCursor(0,1); lcd.print("LDR:");lcd.print(ldr);lcd.print(" u:");lcd.print(u);lcd.print(" ");
delay(50);
}
🏆 Para ir mais longe
- Testa o controlo proporcional: o que acontece se aumentas KP para 1.0? O sistema oscila?
- Implementa dois sensores de obstáculos (frente e trás) — o motor nunca avança se há obstáculo à frente e nunca recua se há atrás
- Adiciona o LED RGB ao sistema: verde = livre, amarelo = zona morta, vermelho = emergência
- Pesquisa a biblioteca PID_v1 de Brett Beauregard — como simplifica a implementação do PID no Arduino?