O protótipo apresentado é o resultado inicial de uma pesquisa iniciada em julho de 2014. Trata-se de um veículo capaz de transportar cargar e, futuramente, detectar e resgatar objetos devidamente identificados, de maneira autônoma, fazendo o percurso de ida e volta. Atualmente é possível seu controle através de interface local ou por acesso remoto via VNC. Maiores detalhes podem ser encontrados na documentação disponível em: http://www.robolivre.org/conteudo/mutante/download/idDoc/231 e mais vídeos pode ser vistos em: https://www.youtube.com/channel/UCyS23h7x0n6kIXetl8ss7Rg.


Código do arduino:

#include 
#include 
#include 
#include 

/******** DECLARAÇÃO DE VARIÁVEIS E CONSTANTES **********************/

LiquidCrystal 
    lcd(43, 45, 47,49,51,53),
    lcd2(42, 44, 46, 48, 50, 52);

Servo 
    Sv1, 
    Sv2, 
    Sv3, 
    Sv4, 
    Sv5;
    
DistanceSRF04 
    usF, 
    usL, 
    usR;

 int  
    B = 37,
    B2 = 38,
    B3 = 39,
    B4 = 40,
    B5 = 41,
    S1 = 2, 
    S2 = 3, 
    S3 = 4,   
    S4 = 5, 
    S5 = 6,
    motRf = 8,
    motRb = 9,
    motLf = 10,
    motLb = 11,
    AcX, 
    AcY, 
    AcZ, 
    Tmp, 
    GyX, 
    GyY, 
    GyZ,
    base = 10,
    cotovelo = 70,
    pulso = 90;

char 
    d;
    
const 
      int 
         v1 = 255,
         v3 = 255,
         MPU = 0x68;  // I2C address of the MPU-6050
/*********************************************************************/
 

/************ FUNÇÃO BANNER ******************************************/

void Banner(){//Mensagem Inicial
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("M.U.T.A.N.T.E.");
  Serial.print("M.U.T.A.N.T.E.");
  lcd.setCursor(1, 1);
  lcd.print("R 4.0 - LCD 1");
  Serial.print("\tR 4.0 - LCD 1");
  lcd2.clear();
  lcd2.setCursor(1,0);
  lcd2.print("M.U.T.A.N.T.E.");
  lcd2.setCursor(5, 1);
  lcd2.print("LCD 2");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print("A. Oliveira 2015");
  lcd2.setCursor(0, 1);
  lcd2.print("#CPBR8 2015");
  Serial.print("\rA. Oliveira 2014\n#CPBR8 2015\n");
  delay(1000);
}
/*********************************************************************/

/************ INICIALIZADOR ACELERÔMETRO *****************************/

void ini_ace(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}
/*********************************************************************/

/*********** LEITURA DO ACELERÔMETRO *********************************/

void le_ace(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)  
}
/*********************************************************************/

/********** TESTE DA BOTOEIRA ****************************************/

void botoes(){
lcd.clear();
lcd.setCursor(0, 0); 
lcd.print("Estado Botoes:");
lcd2.clear();
lcd2.setCursor(0,0);
lcd2.print(" B1+B4 para sair ");
do{
  if (digitalRead(B) == HIGH){
    lcd.setCursor(0, 1); 
    lcd.print("Bot 1 Pressd");
  }
  if (digitalRead(B2) == HIGH){
    lcd.setCursor(0, 1); 
    lcd.print("Bot 2 Pressd");
  }
  if (digitalRead(B3) == HIGH){
    lcd.setCursor(0, 1); 
    lcd.print("Bot 3 Pressd");
  }
  if (digitalRead(B4) == HIGH){
    lcd.setCursor(0, 1); 
    lcd.print("Bot 4 Pressd");
  }
  if (digitalRead(B5) == HIGH){
    lcd.setCursor(0, 1); 
    lcd.print("Bot 5 Pressd");
  }
}while((digitalRead(B) != HIGH) || (digitalRead(B4) != HIGH));
lcd2.setCursor(0, 1); 
lcd2.print("Botoes OK!!!!");
delay(1000);
}
/*********************************************************************/

/******** TESTE DE SENSORES ULTRASSÔNICOS ****************************/

void ultrassom(){
  int b;
lcd.clear();
lcd2.clear();
lcd.setCursor(0,0); 
lcd.print("  Ultrassonicos ");
lcd.setCursor(0,1);
lcd.print(" B4 para sair ");
delay(2000);
do{
  b = digitalRead(B4);
  lcd.setCursor(0,1);
  lcd.print("Frente: ");
  lcd.print(usF.getDistanceCentimeter());
  lcd.print("            ");
  lcd2.setCursor(0,0);
  lcd2.print("Esquerda: ");
  lcd2.print(usL.getDistanceCentimeter());
  lcd2.print("           ");
  lcd2.setCursor(0,1);
  lcd2.print("Direita: ");
  lcd2.print(usR.getDistanceCentimeter());
  lcd2.print("           ");
  delay(50);
}while(b != HIGH );
lcd2.setCursor(0, 1); 
lcd2.print("Ultrassoncos OK!");
delay(1000);

}

/********************************************************************/

/***** TESTE DE BOTÕES DO ANALOGPAD (R) ******************************/

void testaAngl(){
lcd.clear();
lcd.setCursor(0, 0); 
lcd.print(" AnalogPad (R) ");
lcd.setCursor(0,1);
lcd.print(" B4 para sair ");
  do{
      lcd2.setCursor(0,2);
      lcd2.clear();
      lcd2.print("Valor: ");
      lcd2.print(analogRead(A0));
      delay(100);
  }while(digitalRead(B4) != HIGH);
lcd2.setCursor(0, 1); 
lcd2.print("AnalogPad(R) OK!");
delay(1000); 
}
/*********************************************************************/

/********* TESTE DO ACELERÔMETRO *************************************/

void testeAce(){
 char bot, 
      p1;

 int x,
     y,
     z;
lcd.clear();
lcd2.clear();
lcd.setCursor(0, 0); 
lcd.print(" Acelerometro ");
lcd.setCursor(0,1);
lcd.print(" B1+B4 para sair ");
delay(2000);

  do{
      le_ace();
      x = map(AcX, -16000, 16000, 0, 255);
      y = map(AcY, -16000, 16000, 0, 255);
      z = map(AcZ, -16000, 16000, 0, 255);
      lcd.setCursor(0,1);
      lcd.print("Base: ");
      lcd.print(x);
      lcd.print("            ");
      lcd2.setCursor(0,0);
      lcd2.print("Cotovelo: ");
      lcd2.print(y);
      lcd2.print("           ");
      lcd2.setCursor(0,1);
      lcd2.print("Pulso: ");
      lcd2.print(z);
      lcd2.print("           ");
      delay(50);
  }while((digitalRead(B) != HIGH) || (digitalRead(B4) != HIGH) );
lcd2.setCursor(0, 1); 
lcd2.print("Acelerometro OK!");
delay(1000); 


}
/*********************************************************************/


/****** FUNÇÕES DE COMANDO DOS MOTORES *******************************/

/******** FRENTE *****************************************************/

void frente(){
analogWrite(motRf, v1);
analogWrite(motRb, 0);
analogWrite(motLf, v1);
analogWrite(motLb, 0);
}

/******** GIRA PARA ESQUERDA *****************************************/

void giraE(){
analogWrite(motRf, v1);
analogWrite(motRb, 0);
analogWrite(motLf, 0);
analogWrite(motLb, v1);
}

/********** GIRA PARA DIREITA ****************************************/

void giraD(){
analogWrite(motRf, 0);
analogWrite(motRb, v1);
analogWrite(motLf, v1);
analogWrite(motLb, 0);
}

/********** MARCHA À RÉ **********************************************/

void tras(){
analogWrite(motRf, 0);
analogWrite(motRb, v1);
analogWrite(motLf, 0);
analogWrite(motLb, v1);
}

/********* CARRO PARADO *********************************************/

void para(){
analogWrite(motRf, 0);
analogWrite(motRb, 0);
analogWrite(motLf, 0);
analogWrite(motLb, 0);
}
/*********************************************************************/


/********* MOVIMENTAÇÃO DO BRAÇO COM ACELERÔMETRO ********************/
void moveBraco(){
 char bot, 
      p1;

 int x,
     y,
     z;

     le_ace();

     x = map(AcX, -15000, 15000, 0, 115);
     y = map(AcY, -15000, 15000, 128, 0);
     z = map(AcZ, -15000, 15000, 45, 165);
     Sv5.write(x);
     Sv4.write(y);
     Sv3.write(z);
}
/*********************************************************************/

/********* MOVIMENTAÇÃO DO BRAÇO Serial *******************************/

void moveBracoSerial(char port){

/*controla pulso*/

       if (port == 'u')
         
           if (pulso >= 35){
               pulso++;
             
             if (pulso >= 180)
                 pulso = 180;
             
             Sv3.write(pulso);
             lcd2.setCursor(0,1);
             lcd2.print("Levantando...   ");
             Serial.println("Levanta pulso");
         }
         
        if (port == 'D')

             if (pulso <= 180){
               pulso--;

               if (pulso <= 35)
                 pulso = 35;

               Sv3.write(pulso);
               lcd2.setCursor(0,1);
               lcd2.print("Abaixando...    ");
               Serial.println("Abaixa pulso");
          }

/* controla cotovelo */

       if (port == 'b')
         
           if (cotovelo >= 0){
               cotovelo++;
             
             if (cotovelo >= 128)
                 pulso = 128;
             
             Sv4.write(cotovelo);
             lcd2.setCursor(0,1);
             lcd2.print("Sobe cotovelo...");
             Serial.println("Subindo Cotovelo...");
         }
         
        if (port == 't')

             if (cotovelo <= 128){
               cotovelo--;

               if (cotovelo <= 35)
                 cotovelo = 0;

               Sv4.write(cotovelo);
               lcd2.setCursor(0,1);
               lcd2.print("Abaixa cotovelo ");
               Serial.println("Abaixando cotovelo...");
          }

/* controla base */

       if (port == 'h')
         
           if (base >= 0){
               base++;
             
             if (base >= 110)
                 base = 110;
             
             Sv5.write(base);
             lcd2.setCursor(0,1);
             lcd2.print("Girando direita ");
             Serial.println("Girando base...");
         }
         
        if (port == 'n')

             if (base <= 110){
               base--;

               if (base <= 0)
                 base = 0;

               Sv5.write(base);
               lcd2.setCursor(0,1);
               lcd2.print("Girando esquerda");
               Serial.println("Girando base...");

      }

/*controla pulso modo rápido*/

       if (port == 'j')
         
           if (pulso >= 35){
               pulso = pulso + 10;
             
             if (pulso >= 180)
                 pulso = 180;
             
             Sv3.write(pulso);
             lcd2.setCursor(0,1);
             lcd2.print("Levantando...   ");
             Serial.println("Levanta pulso");
         }
         
        if (port == 'k')

             if (pulso <= 180){
               pulso = pulso - 10;

               if (pulso <= 35)
                 pulso = 35;

               Sv3.write(pulso);
               lcd2.setCursor(0,1);
               lcd2.print("Abaixando...    ");
               Serial.println("Abaixa pulso");
          }

/* controla cotovelo modo rápido*/

       if (port == 'l')
         
           if (cotovelo >= 20){
               cotovelo = cotovelo + 5;
             
             if (cotovelo >= 130)
                 cotovelo = 130;
             
             Sv4.write(cotovelo);
             lcd2.setCursor(0,1);
             lcd2.print("Sobe cotovelo...");
             Serial.println("Subindo Cotovelo...");
         }
         
        if (port == 'm')

             if (cotovelo <= 130){
               cotovelo = cotovelo - 5;

               if (cotovelo <= 20)
                 cotovelo = 20;

               Sv4.write(cotovelo);
               lcd2.setCursor(0,1);
               lcd2.print("Abaixa cotovelo ");
               Serial.println("Abaixando cotovelo...");
          }

/* controla base modo rápido*/

       if (port == 'p')
         
           if (base >= 0){
               base = base + 10;
             
             if (base >= 120)
                 base = 120;
             
             Sv5.write(base);
             lcd2.setCursor(0,1);
             lcd2.print("Girando direita ");
             Serial.println("Girando base...");
         }
         
        if (port == 'q')

             if (base <= 120){
               base = base - 10;

               if (base <= 0)
                 base = 0;

               Sv5.write(base);
               lcd2.setCursor(0,1);
               lcd2.print("Girando esquerda");
               Serial.println("Girando base...");

      }



    }
/*********************************************************************/

/******* MONITORAMENTO DE OBSTÁCULOS À FRENTE ************************/

void verFrente(){
  if (usF.getDistanceCentimeter() < 20)
        if (usL.getDistanceCentimeter() < 
          usR.getDistanceCentimeter())
        {
          do{
            tras();
          }while(usF.getDistanceCentimeter() < 50);
          giraE(); 
          delay(2000);      
        }
        else{
          do{
            tras();
            moveBraco();
          }while(usF.getDistanceCentimeter() < 50);
          giraD();
          delay(2000);      
        }
         delay(50); 
}

/*********************************************************************************************/

/******* OPERAÇÃO EM MODO LOCAL PELO PAINEL LATERAL ******************/

void modoLocal(){
  lcd.clear();
  lcd2.clear();
  lcd.print(" M.U.T.A.N.T.E.    ");
  lcd.setCursor(0,1);
  lcd.print("Modo Local");
  lcd2.print("B5 para sair ");
  lcd2.setCursor(0,1);
  lcd2.print("Aguardando comando...");
delay(1000);
do{
    para();
    lcd2.setCursor(0,1);
    lcd2.print("Carro Parado... ");
    moveBraco();

if (digitalRead(B) == HIGH){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Seguindo frente ");
      Serial.println("Seguindo a frente");
      frente();
      //moveBraco();
      //verFrente();
      delay(50);
  }while(digitalRead(B) == HIGH);
}

if (digitalRead(B2) == HIGH){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Dando Re... ");
      Serial.println("Dando Re");
      tras();
      moveBraco();
      delay(50);
  }while(digitalRead(B2) == HIGH);
}

if (digitalRead(B3) == HIGH){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Girando  direita");
      Serial.println("Girando a direira");
      giraD();
      delay(50);
  }while(digitalRead(B3) == HIGH);
}

if (digitalRead(B4) == HIGH){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Girando esquerda");
      Serial.println("Girando a esquerda");
      giraE();
      delay(50);
  }while(digitalRead(B4) == HIGH);
}

delay(50);
}while(digitalRead(B5) != HIGH);
lcd2.clear();
lcd2.print("Saindo do");
lcd2.setCursor(0,1);
lcd2.print("Modo Local");
delay(2000);
}
/*********************************************************************/

/****** OPERAÇÃO PELO ANALOGPAD (R) DA LUVA ******************************/

void analogPad(){
  lcd.clear();
  lcd2.clear();
lcd.print(" M.U.T.A.N.T.E.    ");
lcd.setCursor(0,1);
lcd.print("AnalogPac (R)");
lcd2.print("B4 para sair ");
lcd2.setCursor(0,1);
lcd2.print("Aguardando comando...");

do{
para();
      lcd2.setCursor(0,1);
      lcd2.print("Carro Parado... ");

moveBraco();
if (analogRead(A0) == 0){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Seguindo frente ");
      Serial.println("Seguindo a frente");
      frente();
      
      moveBraco();
      //verFrente();

  }while(analogRead(A0) == 0);
}

if (analogRead(A0) >= 420 && analogRead(A0) <=   470){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Dando Re...     ");
      Serial.println("Dando Re");
      tras();
      moveBraco();
      delay(50);
  }while(analogRead(A0) != 0);
}

if (analogRead(A0) >= 270 && analogRead(A0) <=   290){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Girando  direita");
      Serial.println("Girando a direira");
      giraD();
      delay(50);
  }while(analogRead(A0) != 0);
}

if (analogRead(A0) >= 120 && analogRead(A0) <=   140){
  do{
      lcd2.setCursor(0,1);
      lcd2.print("Girando esquerda");
      Serial.println("Girando a esquerda");
      giraE();
      delay(50);
  }while(analogRead(A0) != 0);
}
delay(50);
}while(digitalRead(B4) != HIGH);
lcd2.clear();
lcd2.print("Saindo do modo");
lcd2.setCursor(0,1);
lcd2.print(" AnalogPad (R) ");
delay(2000);
}
/*********************************************************************/


/****** OPERAÇÃO PELO MODO SERIAL ************************************/

void opSerial(){
char d;
lcd.print("M.U.T.A.N.T.E.    ");
lcd2.print("MODO DE OPERACAO");
lcd2.setCursor(0,1);
lcd2.print(" Comando Serial ");

do{
lcd.print("M.U.T.A.N.T.E.    ");
d = Serial.read();
para();
Serial.println("Aguardando comando...");
moveBracoSerial(d);
if (d == 'f'){
  do{
      Serial.println("Indo em frente...");
      d = Serial.read();
      frente();

      moveBracoSerial(d);
      //verFrente();
  }while(d != 'x');
}

if (d == 'B'){
  do{
      Serial.println("Dando Re...");
      d = Serial.read();
      tras();
      moveBracoSerial(d);
  }while(d != 'x');
}

if (d == 'd'){
  do{
      Serial.println("Girando a direira");
      giraD();
  }while(Serial.read() != 'x');
}

if (d == 'e'){
  do{
      Serial.println("Girando a esquerda");
      giraE();
  }while(Serial.read() != 'x');
}
delay(50);
}while(d != 'F');
lcd2.clear();
lcd2.print("Saindo do");
lcd2.setCursor(0,1);
lcd2.print("Modo Serial");
Serial.println("\nSaindo do Modo Local\n");
delay(2000);

}
/*********************************************************************/

/***** MENU INICIAL **************************************************/

void menu(){
    lcd.clear();
    lcd2.clear();
    lcd.setCursor(0,0);
    lcd.print("B1: Modo Local  ");
    lcd.setCursor(0,1);
    lcd.print("B2: AnalogPad(R)");
    lcd2.setCursor(0,0);
    lcd2.print("B3: Modo Serial ");
    lcd2.setCursor(0,1);
    lcd2.print("B4: Testes");   
}
/*********************************************************************/

/***** SEQUÊNCIA DE TESTE *******************************************/

void sequenciaTeste(){
  char d;
  do{
      menuTeste();
      d = Serial.read();
  
      if ((digitalRead(B) == HIGH) || (d == 'B'))
        botoes();
      
      if ((digitalRead(B2) == HIGH) || (d == 'z'))
        testaAngl();
      
      if ((digitalRead(B3) == HIGH) || (d == 'U'))
        ultrassom();

      if ((digitalRead(B5) == HIGH) || (d == 'Z'))
        testeAce();      

      delay(50);
  }while((digitalRead(B4) != HIGH));
  
}




/*********************************************************************/

/***** MENU DE TESTE *************************************************/

void menuTeste(){
    lcd.clear();
    lcd2.clear();
    lcd.setCursor(0,0);
    lcd.print("B1: Botoeira    ");
    lcd.setCursor(0,1);
    lcd.print("B2: AnalogPad(R)");
    lcd2.setCursor(0,0);
    lcd2.print("B3: Ultrassonicos");
    lcd2.setCursor(0,1);
    lcd2.print("B4: Menu Principl");
    //sequenciaTeste();    
}
/*********************************************************************/

/****** SETUP ********************************************************/

void setup(){
lcd.begin(16, 2); //inicializa o lcd
lcd2.begin(16, 2); //inicializa o lcd
ini_ace();
Serial.begin(9600);
Banner();
usF.begin(27,25);
usR.begin(31,29);
usL.begin(35,33);
pinMode(B, INPUT);
pinMode(B2, INPUT);
pinMode(B3, INPUT);
pinMode(B4, INPUT);
pinMode(B5, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(S4, OUTPUT);
pinMode(S5, OUTPUT);
Sv1.attach(S1);
Sv2.attach(S2);
Sv3.attach(S3);
Sv4.attach(S4);
Sv5.attach(S5);
}

/*********************************************************************/

/****** FUNÇÃO PRINCIPAL *********************************************/

void loop(){

  menu();
  d = Serial.read();  
  
  if ((digitalRead(B) == HIGH) || (d == 'L'))
      modoLocal();

  if ((digitalRead(B2) == HIGH) || (d == 'A'))
      analogPad();

  if ((digitalRead(B3) == HIGH) || (d == 'S'))
      opSerial();

  if ((digitalRead(B4) == HIGH) || (d == 'T'))
      sequenciaTeste();
//moveBracoSerial();
  delay(50);

}  



Atividades recentes