LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: andrique em 02 de Setembro de 2009, 16:00
-
Olá. Estou iniciando a construção de um robô de sumô. O robô usa dois motores, três sensores de luz e um sensor ultrasom. O robô usa os sensores de luz para não sair da arena (branca com a borda preta) e o sensor ultrasom para localizar o oponente ou buscá-lo.
Porém, acontece algum conflito pois apesar das funções de lerSensorLuz e de lerSensorultrasom estarem no loop, o robô em determinados momentos parece ignorar uma das funções. Testei as funções de forma independente e elas funcionam perfeitamente. Quando colocadas juntas no Loop, o robô às vezes não percebe os sensores de luz e sai da arena. (usando somente a função lerSensorLuz ele nunca sai da arena).
Peço ajuda pois pode ser algum erro de programação ou a forma lógica como estou construindo o meu código.
Abaixo o código.
//// declaração das variáveis do robô
long pulso, cm;
const int ultrasom = 3;
int sensorLuzFrontalE = 4;
int sensorLuzFrontalD = 6;
int sensorLuzTraseiro = 5;
int motorEsquerda = 9;
int motorDireita = 10;
int botaoA = 11;
int botaoB = 12;
int led13 = 13;
/// valores iniciais das variáveis
int valorBotaoA = 0;
int valorBotaoB = 0;
int valorSensorLuzFrontalE = 1;
int valorSensorLuzFrontalD = 1;
int valorSensorLuzTraseiro = 1;
int distancia = 0;
int ligado = 0;
void setup() {
pinMode(ultrasom, INPUT);
pinMode(sensorLuzFrontalE,INPUT);
pinMode(sensorLuzFrontalD,INPUT);
pinMode(sensorLuzTraseiro,INPUT);
pinMode(botaoA,INPUT);
pinMode(botaoB,INPUT);
pinMode(led13,OUTPUT);
pinMode(motorEsquerda,OUTPUT);
pinMode(motorDireita,OUTPUT);
};
void loop() {
if (ligado == 0)
{
parar();
lerBotoes();
}
else
{
lerSensoresLuz();
lerUltrasom();
}
} // Fim loop
/////////////////////////////////////////
void lerBotoes() {
valorBotaoA = digitalRead(botaoA);
if (valorBotaoA == 1)
{
girar('h');
delay(200);
paraFrente();
ligado = 1;
}
valorBotaoB = digitalRead(botaoB);
if (valorBotaoB == 1)
{
girar('a');
delay(200);
paraFrente();
ligado = 1;
}
}
/////////////////////////////////////////
//// FUNÇÕES DO ROBÔ
/////////////////////////////////////////
void parar() {
analogWrite(motorEsquerda,127);
analogWrite(motorDireita,127);
}
void paraFrente() {
analogWrite(motorEsquerda,80);
analogWrite(motorDireita,80);
}
void atacar() {
analogWrite(motorEsquerda,50);
analogWrite(motorDireita,50);
}
void paraTras() {
analogWrite(motorEsquerda,180);
analogWrite(motorDireita,180);
}
void girar(char sentido) {
if ( (sentido == 'h') || (sentido == 'H') )
{
analogWrite(motorEsquerda,0);
analogWrite(motorDireita,255);
}
if ( (sentido == 'a') || (sentido == 'A') )
{
analogWrite(motorEsquerda,255);
analogWrite(motorDireita,0);
}
}
void buscar(){
girar('h');
delay(100);
paraFrente();
girar('a');
delay(300);
paraFrente();
delay(200);
}
int distanciaUltrasom() {
pulso = pulseIn(ultrasom, HIGH);
cm = (pulso/147)* 2.54;
delay(50);
return cm;
}
void lerUltrasom() {
distancia = distanciaUltrasom();
if (distancia < 15)
{atacar();}
else
{
buscar();
}
}
void lerSensoresLuz() {
valorSensorLuzFrontalE = digitalRead(sensorLuzFrontalE);
valorSensorLuzFrontalD = digitalRead(sensorLuzFrontalD);
if ( (valorSensorLuzFrontalE == 0) || (valorSensorLuzFrontalD == 0) )
{
digitalWrite(led13,HIGH);
paraTras();
}
else
{digitalWrite(led13,LOW);}
valorSensorLuzTraseiro = digitalRead(sensorLuzTraseiro);
if (valorSensorLuzFrontalD == 0)
{
digitalWrite(led13,HIGH);
paraFrente();
}
else
{digitalWrite(led13,LOW);}
}
//////////////////////////////////////
-
li na diagonal e nada de estranho me saltou à vista, apenas queria dizer que, pessoalmente, tentaria usar os sensores de luz com um pino de interrupção do arduino
-
Andrique,
Estive a ler rapidamente o teu código e vi algumas coisas mal para além do problema que tens agora. Após resolveres este, podemos ajudar-te com os outros!
Relativamente a este problema:
Na função "loop" mandas o robot avaliar os sensores de luz e de seguida avaliar os sensores de ultrasons. Ora bem, tu mandas ele recuar (paraTras) caso encontre uma linha preta nos sensores de luz da frente, a função "lerSensoresLuz" faz uma avalição rápida aos sensores traseiros e termina. De seguida vais ler os sensores de ultraSons e aqui vais mandar o robot andar noutro sentido que encontres algo quer não, tens aqui uma fonte de problemas (provável).
Outra situação que te pode estar a criar este problema é:
A leitura dos sensores de ultrasons é bastante mais demorada que a dos sensores de luz, o que pode estar a acontecer é que o robot avalia os sensores de luz e ainda está dentro da arena, vai ler os sensores de ultrasons e durante este tempo (relativamente longo) vai passar a linha delimitadora da arena. Quando for avaliar novamente os sensores de luz poderá: estar com o sensor traseiro sobre a linha e então avança para a frente; já ter passado completamente a linha e então continuar a pensar que está dentro da arena.
Eu sugeria a que fizesses uma abordagem diferente neste projecto (máquina de estados por exemplo) mas como me parece que ja o tens bastante avançado fazeres um refactoring completo era um enorme passo atrás!
Assim sendo, experimenta avaliar menos vezes os sensores de ultrasons, isto é, não avalies os sensores de ultrasons a cada loop, avalia apenas de segundo a segundo por exemplo, ou ate mais, de 3 em 3 segundos.
;)
-
É um problema muito estranho pois o micro-controlador executa centenas de instruções por segundo, e na nossa lógica de programação, era de se esperar que o robô respondesse de forma precisa.
Vou fazer essa avaliação de ativar o ultrasom como sugeriu e reparar o erro que até então não tinha percebido.
Eu fiz um teste substituindo o sensor ultrasom por um infra-vermelho (SHARP), que detecta distância também. O robô respondeu perfeitamente.
Pretendo usar o infraRed pois não tenho muito tempo pra um refactoring.
Agradeço a ajuda e pretendo contribuir com o crescimento do forum e com a disseminação da robótica.
Aguardo outras sugestões. Agradecido.
-
Pois é, o microcontrolador consegue executar centenas de instruções por segundo mas a leitura do sensor de Ultrasons é muito mais demorada que a leitura dos sensores de luz (o som propaga-se muito mais devagar que a luz! :D). Se vires bem o principio é o mesmo em ambos, lanças algo e esperas o seu retorno. Com a luz esse retorno é quase instantâneo mas com o som ainda demora uns bons décimos de segundo (este valor é uma eternidade para o microcontrolador)!
A título de exemplo avalia quanto tempo demora a leitura dos sensores de ultrasons e quanto tempo demora a leitura dos sensores de luz ;)
unsigned long time, aTime;
void loop() {
if (ligado == 0)
{
parar();
lerBotoes();
}
else
{
time = millis();
lerSensoresLuz();
aTime = millis();
Serial.print("Sensores de luz demora (ms): ");
Serial.println(aTime-time);
time = millis();
lerUltrasom();
aTime = millis();
Serial.print("Sensor de som demora (ms): ");
Serial.println(aTime-time);
}
} // Fim loop
Não testei o código mas acho que é isto (fiz agora à pressa e portanto pode precisar de alterações), mas dá para perceber o que é para fazer.
Não te esqueças de iniciar a comunicação serial na função setup ;).
Ah se fizeres este teste partilha os resultados connosco :D:D:D