Contatos

e-mail: daniloxc@msn.com

Skype: Daniloxc1

Pages

segunda-feira, 20 de maio de 2013

Programa de Controle - Sumô de Robô | Medusa Software

Segue explicações e regras para a confecção de um robô de sumô
http://www.area1.edu.br/_media/textos/2832013164658.pdf

Para 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ô





4 comentários: