Segue explicações e regras para a confecção de um robô de sumô
http://www.area1.edu.br/_media/textos/2832013164658.pdfPara a construção da parte física do Robô Medusa utilizamos placas de zinco, a estrutura física foi concebida por meu colega Leandro Leal.
* Motores de vidro elétrico da Bosch.
* Baterias de lítio de 12V, 2200mAH.
* Placa microcontroladora Arduino Uno, baseada no Microcontrolador ATmega328
http://arduino.cc/en/Main/arduinoBoardUno
* Sensores Infravermelhos (Utilizados para 'enxergar' a borda)
* Sensor Ultrassônico para enxergar o oponente.
Segue o programa de controle do robô.
Note que, quando o programa está em funcionamento, só utilizamos a função delay() quando ele encontra a borda. Isto é feito como medida de sobrevivência.
Porém, não é recomendável utilizar a função de delay() quando necessitamos que um equipamento realize diversas tarefas simultaneamente. Desta forma, utilizamos um conceito conhecido como Multitarefa (Multithread) para que fosse possível que 'ao mesmo tempo' o robô procurasse o oponente e verificasse se teria encontrado a borda.
/*Este programa foi elaborado para controlar um robô de sumô*/
#define borda 2 //definimos que no pino 2 será conectado o sensor de borda
#define trigger 13 //definimos que o pino 13 funcionará como trigger do sensor ultrasônico
#define echo 7 //definimos o pino 7 como echo do sensor ultrasônico
#define motorDir01 6 //definimos que a porta 5 será o bit 1 da ponte H do motor direito (0x)
#define motorDir02 5 //definimos que a porta 6 será o bit 2 da ponte H do motor direito (x0)
#define motorEsq01 4 //definimos que a porta 3 será o bit 1 da ponte H do motor esquerdo(0x)
#define motorEsq02 3 //definimos que a porta 4 será o bit 1 da ponte H do motor esquerdo(x0)
//a ponte H funciona da seguinte maneira: (motorDir01,motorDir02,motorEsq01,motorEsq02)
// (0,1,0,1) Anda pra frente
// (1,0,1,0) Anda pra trás
// (0,0,0,0) Parado
// (1,1,1,1) Parado, condição não recomendada
/*********************Estrutura utilizada para realizar multitarefa ***************************/
typedef struct Timer
{
unsigned long start;//Armazena o tempo de quando foi iniciado o timer
unsigned long timeout;//Tempo após o start para o estouro
};
unsigned long Now ( void )
{
return millis ( );//Retorna os milisegundos depois do reset
}
boolean TimerEstorou (struct Timer * timer)
{
//Verifica se o timer estourou
if ( Now () > timer->start + timer->timeout) {
return true;
}
return false;
}
//após o tempo estourar temos que iniciar o timer com o tempo atual
void timerStart(struct Timer * timer){
timer->start = Now();
}
void timerDesloc(struct Timer * timer, unsigned long tempo){
timer->start = Now()+tempo;
}
Timer timerBorda = {0, 10}; //Verifica se achou a borda a cada 10 milisegundos
Timer timerAchou = {0, 100}; //verifica se achou o oponente a cada 100 milisegundos
Timer timerFrente = {0, 800}; //tempo que o robô passa indo pra frente
Timer timerGira = {0, 3243}; //tempo que o robô passa girando
Timer timerfinal = {0, 85000};// tempo de 1:30 minutos, final do round
boolean sentidoGiro=true; //variável criada para o robô girar hora pra direita, hora pra esquerda
/********** Função preparatória ****************/
void setup(){
// pinos definidos como saída
pinMode(motorDir01, OUTPUT);
pinMode(motorDir02, OUTPUT);
pinMode(motorEsq01, OUTPUT);
pinMode(motorEsq02, OUTPUT);
pinMode(trigger, OUTPUT);
// pinos definidos como entrada
pinMode(borda, INPUT);
pinMode(echo, INPUT);
//chama a função parado e espera 3 segundos antes de começar a luta.
parado();
delay(5000); //espera de 5 segundos antes do início da partida. Este parâmetro foi alterado para 3000 pois //quando testamos com o delay(5000) o robô ficava 7 segundos parado.
timerFrente.start= Now() - timerFrente.timeout; // atrasamos o Start do tempo de ir pra frente de modo ao robô começar a luta indo pra frente.
timerGira.start= Now();
timerAchou.start= Now();
}
int i=0;
void loop(){
if(TimerEstorou(&timerfinal)){
while(1)
parado();// função a ser chamada no final de cada round. Se o robô continuar andando isso caracteriza punição
}
if(i=0)
{
timerStart(&timerBorda);
timerStart(&timerGira);
timerStart(&timerAchou);
i+=1;
}
if(TimerEstorou(& timerFrente)){
andaFrente();
timerStart(& timerFrente);
//timerStart(& timerGira);
}
if(TimerEstorou(& timerBorda)){
if(!digitalRead(borda)){// verifica se achou a borda -- ver pino nomeado como borda
andaTras();
delay(1000);//delay de sobrevivência
timerStart(& timerFrente);//colocar o timer frente no início de seu ciclo
timerDesloc(& timerGira, -timerGira.timeout);// faz com que o robô gire
timerStart(& timerAchou);
}
timerStart(& timerBorda);
}
//dentro da função achou tem um delay,porém é na casa dos Microssegundos e isso o torna desprezível
if(TimerEstorou(& timerAchou)){
if(achou()){
andaFrente();
timerStart(& timerGira);
}
timerStart(& timerAchou);
}
if(TimerEstorou(& timerGira)){
if(sentidoGiro){
giraDireita();
sentidoGiro=!sentidoGiro;
}
else
{
giraEsquerda();
sentidoGiro=!sentidoGiro;
}
timerStart(& timerGira);
}
}
/********** Funções de movimento ****************/
void andaFrente(){
digitalWrite(motorDir01, HIGH);
digitalWrite(motorDir02, LOW);
digitalWrite(motorEsq01, HIGH);
digitalWrite(motorEsq02, LOW);
}
void andaTras(){
digitalWrite(motorDir01, LOW);
digitalWrite(motorDir02, HIGH);
digitalWrite(motorEsq01, LOW);
digitalWrite(motorEsq02, HIGH);
}
void parado(){
digitalWrite(motorDir01, LOW);
digitalWrite(motorDir02, LOW);
digitalWrite(motorEsq01, LOW);
digitalWrite(motorEsq02, LOW);
}
void giraDireita(){
digitalWrite(motorDir01, HIGH);
digitalWrite(motorDir02, LOW);
digitalWrite(motorEsq01, LOW);
digitalWrite(motorEsq02, HIGH);
}
void giraEsquerda(){
digitalWrite(motorDir01, LOW);
digitalWrite(motorDir02, HIGH);
digitalWrite(motorEsq01, HIGH);
digitalWrite(motorEsq02, LOW);
}
/********** Função de busca ****************/
float distancia() {
float tempo, dist;
digitalWrite(trigger, LOW);
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
tempo = pulseIn(echo, HIGH);
dist = (((tempo/2) * 350)/1000000);
dist *= 100;
return dist;
}
boolean achou(){
/*if(giro)
giraHorario();
else
giraAnti();*/
if (distancia()<55)
return true;
else
return false;
}
Fotos do robô