sexta-feira, 12 de julho de 2019

Robô Carrinho Jabutino


//---------------  Programa JABUTINO ATUALIZADO – EU-  20140519  20:40 -----------
#include <Servo.h>
#include <AFMotor.h> 

//Instancia o objeto referente aos motores DC
AF_DCMotor motorEsquerdo(1); //Motor esquerdo na conexão "M1"
AF_DCMotor motorDireito(2); //Motor direito na conexão "M2"

//Definições de velocidade em PWM de 0 a 255
const char VEL_MAX = 255;
const char VEL_MIN = 0;
const char VEL_MED = 200;

//Pinos para controle do Ultrassom HC-SR04
//usar as portas analógicas A0 e A1 como digitais
const int pinoTrigger = 14; // A0 = 14
const int pinoEcho = 15; // A1 = 15

//Servo Motor
Servo meuServo;
const int pinoSinalServo = 10; //o pino 10 é o pino de sinal da conexão "SERVO_2"

//Define as posições de calibragem do servo
//Valores para conseguir um melhor alinhamento do servo, cada motor responde de forma diferente.
//Os valores devem variar de 0 a 180 graus, ajuste de acordo com seu motor na tentativa e erro.

const int OLHA_ESQ = 180;
const int OLHA_DIR = 0;
const int OLHA_FRT = 90;

//Método obrigatório
//Realiza as definições dos pinos e faz a inicialização da biblioteca de servo.

void setup(void)
{
  // Inicializa os motores com velocidade máxima
motorEsquerdo.setSpeed(VEL_MAX);
motorDireito.setSpeed(VEL_MAX);
 
  //atribui os pinos do ultrassom
pinMode(pinoTrigger, OUTPUT);
pinMode(pinoEcho, INPUT);

  //inicia o Servo
meuServo.attach(pinoSinalServo);

  //Coloca o servo virado para posicao frontal
meuServo.write(OLHA_FRT);
}

//Corpo principal do programa, repete infinitamente
void loop(void)
{
  // Inicia andando para frente
 //    andarpFrente(VEL_MAX);
//Enquanto não encontrar um obstáculo a menos de 10 centímetros
//     while(calcularDistancia() > 10)
  //    {

// Inicia andando para frente
//andarpFrente(VEL_MAX);
//int lerChaveE = LOW; // Garante que a chave Esq estará em LOW.
//int lerChaveD = LOW; // Garante que a chave Dir estará em LOW.
//Enquanto não encontrar um obstáculo a menos de 10cm
while(medeDistancia() > 10)
{
andarpFrente(VEL_MAX);
// Lê a Chave Esquerda:
//int lerChaveE = digitalRead(ChaveE);
//int lerChaveD = digitalRead(ChaveD);
//if (lerChaveE == HIGH)
if (digitalRead(ChaveE) == HIGH)
{
Serial.println("Esquerda");
tone(pinoBuzzer, 840); //envia um sinal de 740Hz para o pino 9
delay(100); //aguarda 0,1 segundo
noTone(pinoBuzzer); //interrompe o som no pino 9
girarpDireita(VEL_MED);
delay(500); //aguarda 0,5 segundo
}
else // Lê chave Direita:
//if (lerChaveD == HIGH)
if (digitalRead(ChaveD) == HIGH)
{
Serial.println("Direita");
tone(pinoBuzzer, 840); //envia um sinal de 840Hz para o pino 9
delay(100); //aguarda 0,1 segundo
noTone(pinoBuzzer); //interrompe o som no pino 9
girarpEsquerda(VEL_MED);
delay(500); //aguarda 0,5 segundo
}
delay(100); //Faz uma leitura da distancia a cada 0,1 segundo
}
//Se encontrou um obstáculo recua por 1 segundo e pára ... (continua)
  •  
Parte superior do formulário

     andarpTras(VEL_MED);
        delay(1000);
     pararMotores();
     
     //Verifica qual lado tem maior distância até um obstáculo
        int esquerda = 0, direita = 0;
        meuServo.write(OLHA_ESQ); //vira o servo para a esquerda
           delay(500); //aguarda o servo completar o movimento
        esquerda = calcularDistancia(); //mede a distancia na esquerda
        meuServo.write(OLHA_DIR); //vira o servo para a direita
           delay(500); //aguarda o servo completar o movimento

        direita = calcularDistancia(); //mede a distancia na direita
        meuServo.write(OLHA_FRT); //olha pra frente novamente
            delay(500); //aguarda o servo completar o movimento

        if(esquerda > direita)
          { //se a distancia do obstáculo na esquerda for maior que na direita
              //vira para esquerda
     girarpEsquerda(VEL_MAX);
           }
        else
           { // se a distancia do obstaculo na direita for maior ou igual que na esquerda
       //vira para a direita
     girarpDireita(VEL_MAX);
           }
            //Aguarda alguns instantes para o robô virar
            delay(500); //<< modifique esse tempo se desejar que ele vire por mais ou menos tempo
           }
     //Utiliza o sensor de Ultrassom HC-SR04 para medir a distancia em centímetros
        int calcularDistancia()
          {
          //Garante que o pino de Trigger está LOW
           digitalWrite(pinoTrigger, LOW);
           delayMicroseconds(2);
            //cria um pulso de 5 microssegundos no Trigger
             digitalWrite(pinoTrigger, HIGH);
                delayMicroseconds(5);
             digitalWrite(pinoTrigger, LOW);

          //aguarda o echo
          long microssegundos = pulseIn(pinoEcho, HIGH);
  // A velocidade do som é 340 m/s ou aproximadamente 29 microssegundos por centimetro.
  // O pulso faz uma viagem de ida e volta do sensor até o obstáculo
  // assim, para calcular a distancia temos que dividir esse tempo pela metade
  // desta forma...
          return int(microssegundos / 29 / 2

} // Fim do LOOP-void-

     //Gira as duas rodas para frente
     //Como os motores estão virados para lados opostos eles devem
     //girar em sentidos opostos para que as rodas girem na mesma direção
   
void andarpFrente(char velocidade)
  {
  motorEsquerdo.setSpeed(velocidade);
  motorDireito.setSpeed(velocidade);
  motorEsquerdo.run(FORWARD);
  motorDireito.run(BACKWARD);
   }

     //Gira as duas rodas para trás
     //Como os motores estão virados para lados opostos eles devem
     //girar em sentidos opostos para que as rodas girem na mesma direção
     void andarpTras(char velocidade)
   {
  motorEsquerdo.setSpeed(velocidade);
  motorDireito.setSpeed(velocidade);
  motorEsquerdo.run(BACKWARD);
  motorDireito.run(FORWARD);
   }

     //Gira as duas rodas em sentido inverso, girando no próprio eixo
     void girarpEsquerda (char velocidade)
    {
  motorEsquerdo.setSpeed(velocidade);
  motorDireito.setSpeed(velocidade);
  motorEsquerdo.run(BACKWARD);
  motorDireito.run(BACKWARD);
    }

     //Gira as duas rodas em sentido inverso, girando no próprio eixo
     void girarpDireita(char velocidade)
    {
  motorEsquerdo.setSpeed(velocidade);
  motorDireito.setSpeed(velocidade);
  motorEsquerdo.run(FORWARD);
  motorDireito.run(FORWARD);
    }

//Pára os motores definindo os dois pinos Enable em estado Low
     void pararMotores()
     {
  motorEsquerdo.run(RELEASE);
  motorDireito.run(RELEASE);
     }
// =================================================================
/* Preciso entrar com a parte das chaves / colisão, para evitar que o robô se agarre nas laterais, como já ocorreu aqui.
    Com base na rotina de teste para um só sensor, tentei criar uma rotina para os DOIS sensores, um de cada lado, à frente:*/
      { // Inicio rotina das CHAVES:
   
        // Faz a leitura dos sensores de CHAVES = colisão:
         int lerChaveE = digitalRead(pinoChaveE);
         int lerChaveD = digitalRead(pinoChaveD);

     // Verifica se a leitura é diferente da leitura anterior
      // para DESVIAR apenas quando mudar
     // if (lerChaveE != lidoAntE)

           {   //imprime o valor chave Esq:
            if (lerChaveE == HIGH)
              { Serial.println("Esquerda");
              tone(pinoBuzzer, 740); //envia um sinal de 740Hz para o pino 9
              delay(100);            //aguarda 0,1 segundo
              noTone(pinoBuzzer);    //interrompe o som no pino 9
              girarpDireita(VEL_MED);
              delay(500);           //aguarda 1 segundo
              }
            else
           // if (lerChaveD != lidoAntD)
          {  // imprime o valor da chave Direita:
            if (lerChaveD == HIGH)
              { Serial.println("Direita");
               tone(pinoBuzzer, 840); //envia um sinal de 840Hz para o pino 9
               delay(100);            //aguarda 0,1 segundo
               noTone(pinoBuzzer);    //interrompe o som no pino 9
               girarpEsquerda(VEL_MED);
               delay(500);           //aguarda 0,5 segundo
              }
           }
      
             // armazena o valor lido para monitorar as próximas mudanças:
               // lidoAntE = lerChaveE;
               // lidoAntD = lerChaveD;
  
        // aguarda minimamente para eliminar ruidos:
         delay(5);
    } // final da rotina das CHAVES

==> questionamento no blog do Clube Hardware 

// inicialmente coloquei-a no inicio, logo após o robô começar a andar pra frente... mas não funcionou!
//  Fiz o teste das chaves, funcionou, com as duas, normal (depois de muito pelejar).
// Daí para frente nada das coisas funcionarem. Na primeira vez/ versão o robô funcionou, mas sem funcionar as chaves.
// PERGUNTO: 1) Como concatenar as duas rotinas? è preciso ainda adicionar o LDR e os LED brancos / faróis.
                          2) Onde fica a chave que fecha o void loop() ?


Fotos: