Ola, boa noite. Estou "desenvolvendo" um robozinho, a partir de um comprado já pronto e com um programa-base agindo em 2 motores DC, 1 servo-motor, 1 ultrassom. Só que ele assim costuma se agarrar lateralmente em paredes, etc. Preciso incluir uma rotina para ler 2 sensores-chaves (micro-swiches) tipo bigode-de-gato, para que o robô saia desse "encosto".
Produzí e tentei várias rotinas (uma já veio com o kit do robô, mas usando apenas uma chave), sem sucesso: Ou funcionam os motores+ultrassom, ou as chaves. Testei colocar a minha rotina em vários pontos do sketch. Atualmente dividi essa rotina para ver se funcionavam os dois sensores (2 chaves e o ultrassom). Não deu certo.
Abaixo cópia do sketch mais atual. Este tem 4 páginas em A4, sem espaços entre linhas. Vou copiar aqui é o sketch mesmo, tirado da IDE, ok?

//--------------- Programa JABUTINO sketch 20140510 -----------
#include 
#include

//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 pinoServo = 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;

// Pino em que o BUZZER está conectado: 
const int pinoBuzzer = 9;

// PINOS que vão conectar as 2 CHAVES (sensores de colisão):
const int ChaveE = 18;
const int ChaveD = 19;

//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);

Serial.begin(9600); /* função provisória, para controle da rotina das chaves.*/
/* define os pinos como entrada ligando um resistor pullup a eles */
pinMode(ChaveE, INPUT_PULLUP); // MUITO IMPORTANTE
pinMode(ChaveD, INPUT_PULLUP);

//inicia o Servo
meuServo.attach(pinoServo);
//Coloca o servo virado para posicao frontal
meuServo.write(OLHA_FRT);

} // fim do setup
//================================================
//Corpo principal do programa, repete infinitamente
void loop()
{
// Inicia andando para frente
   andarpFrente(VEL_MAX);

    // Faz a leitura dos sensores de CHAVES = colisão:
    int lerChaveE = digitalRead(ChaveE);
    int lerChaveD = digitalRead(ChaveD);

        //Enquanto não encontrar um obstáculo a menos de 10cm
          while(medeDistancia() > 10)
          {  delay(100); //Faz uma leitura da distancia a cada 0,1 segundo 
          }

             { // chave Esq:
               if (lerChaveE == 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 1 segundo
                  }
                else 
                  { // 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
                     }
                   } 
          //Se encontrou um obstáculo recua por 1 segundo e pára
             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 = medeDistancia(); //mede a distância na esquerda
                 meuServo.write(OLHA_DIR); //vira o servo para a direita
                 delay(500); //aguarda o servo completar o movimento

              direita = medeDistancia(); //mede a distância 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 distância do obstáculo 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              // Fim da rotina de obstáculos

             // Inicio da rotina das CHAVES / colisão: // ==> tirado daqui e dividido, para tentar o funcionamento.

              // aguarda minimamente para eliminar ruidos:

                 delay(5);
                    int lerChaveE = LOW; // Garante que a chave Esq estará em LOW.
                     int lerChaveD = LOW; // Garante que a chave Dir estará em LOW.
                 }
             // final da rotina das CHAVES

} // Fim do LOOP

//Utiliza o sensor de Ultrassom HC-SR04 para medir a distância em centímetros
int medeDistancia()
{
//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 CalcularDistancia

// ======== void's dos motores: =============

//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);
}

Exibições: 3316

Anexos

Responder esta

Respostas a este tópico

O sketch que usei aqui para a simulação é o que conversamos anteriormente Maurílio, só modifiquei o que relatei porque não tenho o driver que você utiliza aí.

Mais testes... e te respondendo:

O problema está no buzzer e não no println. Isolei cada um, testei. Qdo tirei print e puz o buzzer ele parou ao acionar as chaves. Ao isolar o buzzer e acionar o print funcionou normal. Ah, voltei com os pinos para os originais. Coloquei o ultrassom um pouco mais alto - servo em pé em vez de encaixado. Continua a escolher errado (depois de eu desinverter no gira-gira, rs...

Passei a alimentá-lo com 9V através de pilhas AA. Ganhou velocidade e força. Mas a esteira, de plástico, não serve para andar em tapete (de chuveiro, baixo). Pensando em trocar as esteiras por rodas, mais aderentes. Mas os motores...um atrás (roda pra frente) e outro na frente (roda pra trás)... é testar e testar, né?

E como esse bichinho gosta de enroscar em cantos e pés de móveis, sô! 

Gozado,

Eu não consegui compilar os exemplos que acompanham da biblioteca Tone disponíveis no site da Arduino, quando comecei a utilizá-lo. Depois acabei esquecendo o Tone e uso funções minhas para diferenciar diferentes "toques" para feedback.

Quando fiz as modificações no seu sketch para simular aqui, meio instintivamente comentei as linhas que a chamavam. Quando não achei problema na lógica, dei um reolhada geral e acabei por descomentar tais linhas. Funcionou e eu não parei para pensar nisso.

Agora que você fala que o problema eram nelas ... vai saber né....

Isso foi a minha saída. Não sei se a única, rs...

Inverti as duas linhas de direção dos void's: da esquerda pus pra direita, e vice-versa. Resolveu.

Testei várias ligações elétricas dos motores, sem sucesso. Aí fui no sketch e inverti. Pronto.

Agora vamos ao LDR e LEDs, rs...

É Maurílio,

Eu escolhí um robô para aprendizado de Arduino porque tenho certa afinidade com Mecânica, mas depois de um tempo passei a perceber quanta coisa dá para pensar (e fazer...) com a lógica de um robô autônomo.

Eu ando modificando tudo que fiz até então, daí em termos práticos não progredí muito ultimamente na lógica do programa ou mesmo no acráscimo de outros hardware´s.

Com o seu probleminha com os "bigodes" lembrei do dia em que decidí construir um (na verdade dois, frontal e traseiro) para o meu robô. O motivo foi que percebí que não conseguia ajustar o ultrasom frontal (também instalado em um servo) para detectar objetos muito esbeltos e o robô atropelava eles, normalmente pés finos de cadeiras. Eu acabei interligando os dois micros com um perfil de plástico cortado daquelas canaletas da Pial para esconder fios externos (não lembro o nome daquilo agora). O que quero dizer com isso é que tem realmente MUITA coisa a se resolver em um robô autônomo e só os testes para perceber as necessidades.

Boa sorte e progresso com seu robô.

Qualquer outra dúvida posta aqui que tentamos ajudar.

Um abraço,

Wilmar

Pois é Wilmar... vivendo e tendo a coragem de aprender e testar até mesmo "pelos cocos", rs... E eu nem entendo muito de programação, "C", etc. Começando mesmo. Entrando no mundo dos robôs e arduinos, meio sem jeito... Mas gosto de mecânica tb (sem ser entendido em nada, rs). Mexo em tudo: mecânica, eletrônica, fotografia, informática, gerador de energia (brigando com um aqui, rs...) - comecei como sendo eólico mas a parte mecânica está muito pesada, e nada de ventos, rs... então estou bolando uma outra forma, coisa de doido mesmo: Inicialmente é alimentar um motorzinho para girar o rotor do gerador. Mas... o motor que melhor se deu à tarefa tem um eixo muito curto, com rosca e uma parte chata. Tá difícil de firmar a roldana. Mas vou testar tb em realimentar o motor. Ou seja: uma(s) placa de celular solar alimenta uma bateria menor, de 45AH, que alimenta o motor (ventoinha de radiador de carro), que gira o rotor, que produz 5 ou 6x o que gasta com o motor, que carrega 4 baterias de 80AH, que alimenta um inversor 12V  120V. Vou testar ligar a saída das 4 baterias à bateria do motorzinho (obviamente com um diodo pra evitar retorno) e um controlador de carga na 1ª bateria e outro nas 4 baterias. Doido? se não tentar não se vai saber. Teorias de engenharia elétrica? quase nada, rs... Mas cuidados, sim, que não sou super-homem, né?

Tenho outro projeto tb de fazer um carrinho tipo grua, com controle remoto, com uma câmera de vídeo na ponta da grua/guindaste. A grua gira na base do carrinho. O "braço" da grua é elástico, com duas ou três seções, tudo no CR. Transmissão direta para o meu monitor de TV portátil. Já tenho a placa, motores e rodas, alguns servos, braços de servos em alumínio, a câmera e seu transmissor, receptor digital e/ou não-digital, eixos, e peças de engrenagem, inclusive barras dentadas. Vamos ver. Não desenhei nem montei nada ainda, tudo na cabeça ainda, rs... Tenho tb um carrinho de corrida, tamanho 1/10. Não sei se o desmonto e uso peças (motor, engrenagens, bateria, ESC, etc)... mas isso será última opção. Por ora, a câmera está nesse carrinho de corrida. Gambiarra? claro, ele não foi feito pra isso, rs... mas o comprei já com essa idéia, rs...

Mas vamos aos nossos robôs, rs... talvez eu troque o shield de 4 motores por uma ponte H dupla (já tenho, rs).

Pois é Maurílio,

O mundo dos microcontroladores é muito interessante e bastante vasta sua aplicação.

Quando conhecí o Arduino tomei coragem para iniciar. Isso foi a um ano.

A escolha do robô foi porque pensei em ter somente um foco, em profundidade e aprender linguagem C e um pouco mais de hardware digital, pois já tinha um mínimo conhecimento.

Quando se começa e tentar entrar nos detalhes mais cavernosos, aparecem os problemas e aí a gente aprende muito. Eu já apanhei bastante com meu robô também, principalmente com os motores, hehe. Comecei com os de passo, fui para os DC, voltei para os de passo, voltei de novo para os DC tentando fazer funcionar um encoder que eu mesmo fiz e agora voltei não definitivamente, mas por um bom tempo para os de passo. Ufa... Com isso aprendí bastante, mas ainda sou um iniciante também.

Pelo estágio do seu sketch, com certeza dá para usar um módulo de duas Ponte H. É muito fácil a programação dele, mas também dá para ficar no que já está funcionando. Ví que ele tem outros recursos, precisa analisar os outros hardware que planeja instalar.

Wilmar

Ok. Mas agora vou mais devagar. Eu não gostava dessa tal eletrônica digital. Me causava arrepios. Só via PICs e PICs, etc, difícil de mexer. Fiquei mais de 20 anos  sem mexer objetivamente com eletrônica (analógica). Tenho coleção de revistas. Estava a fim de cataloga-las (até cheguei a começar). Não era catalogar as revistas em sí, mas os assuntos, os projetos, né? Esse afastamento foi por causa do meu trabalho - auditor-fiscal, e depois o casamento. Tenho estoques de coisas novas e velhas, rs... Qdo quis retornar (2006-2007) não havia mais as minhas revistas nas bancas, ou as que restavam só falava em mecatrônica e eletrônica digital ("aquela coisa"). Aí veio o Arduino. Esperei pra ver, nem olhava direito, rs... até que vi a coisa aparecer mais frequente... e resolvi ver o que era, rs... Quase ao mesmo tempo comprei o robozinho e um kit de arduino: O kit veio numa caixa com um Funduino e mais 2 CD's. Depois comprei Mega R3 mais cabos, servos, motores, tudo aos poucos, tanto no mercado nacional (Mercado LIvre) qto importados (AlyExpress).

Olá. Voltando à nossa discussão:

Acrescentei os LEDs de sinalização (setas) mas não funcionou. Só pisca o da direita e só gira à esquerda. E está cada vez mais lento (processamento). Pensando em trocar o Uno por um Mega, mas o clock é o mesmo... sei não... mas tentar não custa, né?

Veja o sketch como ficou com os LEDs doidões:

//--JABUTINO sobre TANQUE 20140606 pinos invertidos OK -
#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 = 150;

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

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

const int ledEsq = 16; // LED Esquerdo conectado ao pino digital 16
const int ledDir = 17; // LED Direito conectado ao pino digital 17

/*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 = 10;
const int OLHA_FRT = 85;

const int pinoBuzzer = 9;

const int pinoChaveEsq = 14;
const int pinoChaveDir = 15;

/*Método obrigatório: Define tipos dos pinos e inicializa a 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);

Serial.begin(9600); /* função provisória, para controle da rotina das chaves.*/
/* define os pinos como entrada ligando um resistor pullup a eles */
pinMode(pinoChaveEsq, INPUT_PULLUP); // MUITO IMPORTANTE
pinMode(pinoChaveDir, INPUT_PULLUP);

pinMode(ledEsq, OUTPUT);
pinMode(ledDir, OUTPUT);

//inicia o Servo
meuServo.attach(pinoServo);
//Coloca o servo virado para posicao frontal:
meuServo.write(OLHA_FRT);
}
// =============
//Corpo principal, repete infinitamente:
void loop()
{
// Inicia andando para frente
  andarpFrente(VEL_MAX);

//Enquanto não encontrar um obstáculo a menos de 10cm:
    while (medeDistancia()>10)
    { // Lê a Chave Esquerda:
      if (digitalRead(pinoChaveEsq) == HIGH)
       { // Serial.println("Esquerda");
       //tone(pinoBuzzer, 740); //envia 740Hz para o pino 9
       //delay(100); //aguarda 0,1 segundo
       //noTone(pinoBuzzer); //interrompe o som.
       girarpDireita(VEL_MED);
       delay(800); //aguarda 0,8 segundo
      andarpFrente(VEL_MAX);
     }
    else
     // Lê chave Direita:
     if (digitalRead(pinoChaveDir)== HIGH)
        { //Serial.println("Direita");
          //tone(pinoBuzzer, 840); //envia 840Hz para o pino 9
          //delay(100); //aguarda 0,1 segundo
          //noTone(pinoBuzzer); //interrompe o som.
        girarpEsquerda(VEL_MED);
          delay(800); //aguarda 0,8 segundo p/ virar
        andarpFrente(VEL_MAX);
        }
       else
        delay(100); //Faz uma leitura da distância a cada 0,1 segundo
       }
       // aguarda minimamente para eliminar ruidos das chaves:
        delay(5);

   //Se encontrou um obstáculo recua por 1 segundo e pára:
    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 = medeDistancia(); //mede a distância na esquerda
   meuServo.write(OLHA_DIR); //vira o servo para a direita
   delay(500); //aguarda o servo completar o movimento

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

     if(esquerda > direita) /*se dist do obst esquerda for maior que direita vira para esquerda */
        { pisca_LED_Esq();
          girarpEsquerda(VEL_MAX);
        }
     else /* se dist do obst direita for maior ou igual que esquerda
     vira para a direita */
       { pisca_LED_Dir();
         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
  // Fim da rotina de obstáculos
} // Fim do LOOP

//Utiliza o sensor de Ultrassom HC-SR04 para medir a distância em centímetros
int medeDistancia()
  {
   digitalWrite(pinoTrigger, LOW); //Garante que o pino de Trigger está 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 distância temos que dividir esse tempo pela metade.
  Então...*/
  return int(microssegundos/29/2);
   } // Fim do medeDistancia

// = void's dos motores e dos LED: ====

/*Gira as 2 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 2 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 2 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 2 pinos Enable em estado LOW.
void pararMotores()
{ motorEsquerdo.run(RELEASE);
motorDireito.run(RELEASE); }

void pisca_LED_Esq()
{ for (int x=0; x<3; x++)
   {digitalWrite(ledEsq, HIGH); // liga o LED
   delay(300); // Espera 0,3 segundo
   digitalWrite(ledEsq, LOW); // Desliga o LED
   delay(300);
   }
}
void pisca_LED_Dir()
{ for (int y=0; y<3; y++)
   {digitalWrite(ledDir, HIGH); // liga o LED
    delay(300); // Espera 0,3 segundo
    digitalWrite(ledDir, LOW); // Desliga o LED
    delay(300);
   }
}

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço