Robô de Sumô Autônomo
Robô de Sumô Autônomo
- Construir e programar um robô autônomo que detecta o oponente com sensores de distância e evita sair do ringue usando sensores de borda — desenvolvendo algoritmo, depuração e trabalho em equipe.
1× Arduino Uno 1× Ponte H (L293D) 2× Motor DC com caixa de redução 4× Sensor de distância Sharp 2× Sensor infravermelho de borda 1× Bateria/fonte (LiPo) 1× Chassi + cobertura + rodas (impressão 3D) 1× Jumpers e parafusos
Introdução / Contextualização
Apresente o desafio do Mini Sumô: um robô autônomo que detecta o oponente e não sai do ringue. Levante a pergunta: como o robô 'decide' atacar ou recuar?
Montagem do Circuito / Hardware
1) Montar o chassi 3D e fixar motores e rodas. 2) Ligar a ponte H L293D ao Arduino (motor A: D3/D4/D5 · motor B: D7/D8/D9). 3) Conectar os 4 sensores Sharp (A2–A5) e os 2 sensores de borda (A0/A1).
Programação / Codificação
Carregar o código (Sensores_SHARP.ino). Explicar a lógica: ler os sensores de borda para NÃO sair do ringue, e os Sharp para atacar o oponente. Ajustar o limiar de detecção (umbralOponente) e as velocidades.
Teste, Depuração e Ajustes
Testar no ringue: o robô deve recuar ao detectar a borda branca e avançar/girar atrás do oponente. Depurar a estratégia em equipe.
Encerramento / Socialização
Roda de conversa: o que é um algoritmo de ataque/defesa? Como melhorar a estratégia? Discutir velocidade × precisão.
// === Pines del L293D ===
// Motor A (izquierdo)
const int motorA1 = 3;
const int motorA2 = 4;
const int enableA = 5; // Control de velocidad PWM
// Motor B (derecho)
const int motorB1 = 7;
const int motorB2 = 8;
const int enableB = 9; // Control de velocidad PWM
// === Pines sensores Sharp ===
const int sharpIzq = A2; // Sensor lateral izquierdo
const int sharpFront1 = A3; // Sensor frontal izquierdo
const int sharpFront2 = A4; // Sensor frontal derecho
const int sharpDer = A5; // Sensor lateral derecho
// === Sensores de piso digitales ===
const int pisoDer = A0; // Sensor de piso derecho
const int pisoIzq = A1; // Sensor de piso izquierdo
// === Parámetros de movimiento ===
int velocidadMax = 200; // Velocidad máxima del robot
int velocidadCurva = 160; // Velocidad al girar
int umbralOponente = 400; // Valor analógico que indica proximidad (menor = más cerca)
void setup() {
// Configurar pines de motores como salida
pinMode(motorA1, OUTPUT);
pinMode(motorA2, OUTPUT);
pinMode(enableA, OUTPUT);
pinMode(motorB1, OUTPUT);
pinMode(motorB2, OUTPUT);
pinMode(enableB, OUTPUT);
// Configurar sensores de piso como entrada
pinMode(pisoDer, INPUT);
pinMode(pisoIzq, INPUT);
// No es necesario configurar los pines analógicos de los sensores Sharp
// Puedes habilitar Serial.begin(9600); si deseas monitorear sensores
}
void loop() {
// Leer sensores de piso (devuelven HIGH o LOW)
int sueloDer = digitalRead(pisoDer);
int sueloIzq = digitalRead(pisoIzq);
// Leer sensores Sharp (valores entre 0 y 1023)
int valIzq = analogRead(sharpIzq);
int valFront1 = analogRead(sharpFront1);
int valFront2 = analogRead(sharpFront2);
int valDer = analogRead(sharpDer);
// === 1. Evitar salirse del ring ===
// Si algún sensor detecta el borde (LOW = borde blanco o sin línea)
if (sueloIzq == LOW || sueloDer == LOW) {
retroceder(); // Retrocede rápidamente
delay(300); // Espera un poco
girarDerecha(); // Gira para cambiar de dirección
delay(300);
detener(); // Pausa antes de seguir
return; // Finaliza esta iteración del loop
}
// === 2. Estrategia de ataque ===
if (valFront1 < umbralOponente || valFront2 < umbralOponente) {
avanzar(); // Oponente detectado al frente
} else if (valIzq < umbralOponente) {
girarIzquierda(); // Oponente a la izquierda
} else if (valDer < umbralOponente) {
girarDerecha(); // Oponente a la derecha
} else {
buscar(); // No se detecta nada, buscar girando
}
}
// === Funciones de movimiento ===
// Avanza recto
void avanzar() {
digitalWrite(motorA1, HIGH);
digitalWrite(motorA2, LOW);
analogWrite(enableA, velocidadMax);
digitalWrite(motorB1, HIGH);
digitalWrite(motorB2, LOW);
analogWrite(enableB, velocidadMax);
}
// Retrocede
void retroceder() {
digitalWrite(motorA1, LOW);
digitalWrite(motorA2, HIGH);
analogWrite(enableA, velocidadMax);
digitalWrite(motorB1, LOW);
digitalWrite(motorB2, HIGH);
analogWrite(enableB, velocidadMax);
}
// Gira hacia la izquierda
void girarIzquierda() {
digitalWrite(motorA1, LOW);
digitalWrite(motorA2, HIGH);
analogWrite(enableA, velocidadCurva);
digitalWrite(motorB1, HIGH);
digitalWrite(motorB2, LOW);
analogWrite(enableB, velocidadCurva);
}
// Gira hacia la derecha
void girarDerecha() {
digitalWrite(motorA1, HIGH);
digitalWrite(motorA2, LOW);
analogWrite(enableA, velocidadCurva);
digitalWrite(motorB1, LOW);
digitalWrite(motorB2, HIGH);
analogWrite(enableB, velocidadCurva);
}
// Detiene los motores
void detener() {
analogWrite(enableA, 0);
analogWrite(enableB, 0);
}
// Búsqueda: gira hacia la izquierda buscando oponente
void buscar() {
girarIzquierda();
delay(400);
detener();
}
quando @greenFlag for clicado
sempre
se <borda à esquerda> ou <borda à direita> então
recuar
esperar 0.3 seg
virar à direita
esperar 0.3 seg
parar
senão
se <oponente à frente> então
avançar
senão
se <oponente à esquerda> então
virar à esquerda
senão
se <oponente à direita> então
virar à direita
senão
procurar girando
end
end
end
end
endToque para ver em 3D · gire com o dedo.
Você chegou ao fim! 🎉
O que foi mais difícil? O que você faria diferente? Conte pra turma!