• Welcome to LusoRobótica - Robótica em Português.
 

The Starter

Started by LoneWolf, 03 de February de 2011, 01:13

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LoneWolf

Boas, deixei um vídeo do que tinha feito ate aquela data, já se desviava de obstáculos usando um sensor IR home made, depois disso tenho tentado com 3 sensores, fazer o código para 1  sensor e meter a funcionar já não foi muito fácil, agora para 3 sensores pior tenho estado as "cabeçadas" a isto mas não esta fácil, já tentei encontrar código que usem 3 sensores para eu me guiar e construir o meu mas foi umas pesquisas sem sucesso. O código que fiz para usar 3 sensores não esta a funcionar, a verdade tem de ser dita eu ainda não pesco nada ou quase nada disto  ;D ;D ;D alguém de vós fez algo deste tipo que possa fornecer o código para eu tentar perceber como se faz e construir assim o meu? ou algum link que explique isso fico agradecido.

Abraços e obrigado  ;)           
Blog: A Visão do Lobo

Nick antigo: kilobyte

LoneWolf

Boas, ninguém da ai umas luzes sff?

obrigado e abraços  ;)
Blog: A Visão do Lobo

Nick antigo: kilobyte

LoneWolf

#32
Boas noites,

....bem já vi que assim não vem luz nenhuma  ;D ;D ;D não sei o porque mas ya....continuando, a ver se isto vai de outra maneira, como já tinha dito anteriormente eu "fiz" um código para um sensor IR, alias é partes de códigos de outros projectos daqui do fórum, outros achados na net o resto inventado por mim mas funcionou, pode não estar bem construído( estruturado ) que deve ser o mais certo  ;D mas com calma e mais disponibilidade para ler, isto vai la, então o código que fiz para 1 sensor IR é:
// Continuous rotation servo class.
// By Njay in 2009 (EmbeddedDreams.com)
// Licensed under CC BY NC SA ([url=http://creativecommons.org/licenses/by-nc-sa/2.5/pt/]http://creativecommons.org/licenses/by-nc-sa/2.5/pt/[/url]
#include <Servo.h>
#include <MsTimer2.h>
#define irx 2   // Sensor IR no pin digital 2
static boolean output = HIGH;
/**
* Wraps a MegaServo object to control a continuous rotation servo.
* The servo should be calibrated to be stopped when Megaservo::write()
* is set to 90.
* When speed is set to 0 to stop the servo, the servo is detached to
* make sure it will be completly stopped.
*/
class ContinuousRotationServo
{
  public:
    ContinuousRotationServo (unsigned char pin)  {
        mSpeed = 0;
        SetPin(pin);
    }

    ContinuousRotationServo (void)  {
        mSpeed = 0;
    }

    inline void SetPin (unsigned char pin)  {
        mPin = pin;
    }

    // Set the speed. 0 to be stopped, > 0 to rotate in one direction
    // and < 0 to rotate on the other.
    void SetSpeed (signed char speed)  {
        if (speed == 0)  {
            if (mSpeed != 0)  {
                //Serial.println("dettach");
                mServo.detach();
            }
        }
        else  {
            if (mSpeed == 0)  {
                //Serial.println("attach");
                mServo.attach(mPin);
            }
            //Serial.println("set speed");
            mServo.write(90 + speed);
        }
        mSpeed = speed;
    }

    inline void Detach (void)  {
        mServo.detach();
    }

  private:
    Servo          mServo;
    unsigned char  mPin;
    signed char    mSpeed;    // current speed
};
ContinuousRotationServo  servoDir(10);    // servo no pino 10
ContinuousRotationServo  servoEsq(9);    // outro servo, no pino 11

void setup () {
  pinMode(irx, INPUT);     // Pin onde está o LED infravermelhos é pin output
   MsTimer2::set(5, flash); // Defenir intrrupções de 5 em 5 ms e durante a interrupção é chamada a função flash
  MsTimer2::start();       // Iniciar interrupções   
}
void loop()
{
  (digitalRead(irx));
  delay(100);
  servoEsq.SetSpeed(-45);   
  servoDir.SetSpeed(45);
while(digitalRead(irx));
  servoEsq.SetSpeed(0);   
  servoDir.SetSpeed(0);
  delay(500); 
  servoEsq.SetSpeed(45);   
  servoDir.SetSpeed(45);
  delay(1500);
  servoEsq.SetSpeed(0);   
  servoDir.SetSpeed(0);
  delay(500); 

}
void flash() {               // Função chamda durante a interrupção
  digitalWrite(12, output);  // Anceder ou apagar o LED IR
  output = !output;          // Alterar o output...
}

   
....pois dá para rir  ;D ;D ;D mas deu para o que eu queria.
          Agora para os 3 sensores já tentei aplicar o que tenho aprendido ou melhor, tentado aprender  ;D e deu no seguinte:
#include <Servo.h>
#include <MsTimer2.h>
#define ir1 7   // Sensor IR no pin digital 7
#define ir2 2   // Sensor IR no pin digital 2
#define ir3 4   // Sensor IR no pin digital 4
static boolean output = HIGH;
/**
* Continuous rotation servo class.
* By Njay in 2009 (EmbeddedDreams.com)
* Licensed under CC BY NC SA ([url=http://creativecommons.org/licenses/by-nc-sa/2.5/pt/]http://creativecommons.org/licenses/by-nc-sa/2.5/pt/[/url]
* Wraps a MegaServo object to control a continuous rotation servo.
* The servo should be calibrated to be stopped when Megaservo::write()
* is set to 90.
* When speed is set to 0 to stop the servo, the servo is detached to
* make sure it will be completly stopped.
*/
class ContinuousRotationServo
{
  public:
    ContinuousRotationServo (unsigned char pin)  {
        mSpeed = 0;
        SetPin(pin);
    }

    ContinuousRotationServo (void)  {
        mSpeed = 0;
    }

    inline void SetPin (unsigned char pin)  {
        mPin = pin;
    }

    // Set the speed. 0 to be stopped, > 0 to rotate in one direction
    // and < 0 to rotate on the other.
    void SetSpeed (signed char speed)  {
        if (speed == 0)  {
            if (mSpeed != 0)  {
                //Serial.println("dettach");
                mServo.detach();
            }
        }
        else  {
            if (mSpeed == 0)  {
                //Serial.println("attach");
                mServo.attach(mPin);
            }
            //Serial.println("set speed");
            mServo.write(90 + speed);
        }
        mSpeed = speed;
    }

    inline void Detach (void)  {
        mServo.detach();
    }

  private:
    Servo          mServo;
    unsigned char  mPin;
    signed char    mSpeed;    // current speed
};
ContinuousRotationServo  servoDir(10);    // servo no pino 10
ContinuousRotationServo  servoEsq(9);    // outro servo, no pino 9

void setup () {
  pinMode(ir1, INPUT);     // Pin onde está o LED1 infravermelhos é pin output
  pinMode(ir2, INPUT);     // Pin onde está o LED2 infravermelhos é pin output
  pinMode(ir3, INPUT);     // Pin onde está o LED3 infravermelhos é pin output
  MsTimer2::set(5, flash); // Defenir intrrupções de 5 em 5 ms e durante a interrupção é chamada a função flash
  MsTimer2::start();       // Iniciar interrupções
}
void loop()
{
  scan();
  if ((digitalRead(ir1)==0) && (digitalRead(ir2)==0) && (digitalRead(ir3)==0))
  {
    para(); meiavolta(); scan(); 
}
if ((digitalRead(ir1)==0) && (digitalRead(ir2)==1) && (digitalRead(ir3)==0))
  {
    frente(); 
}
if ((digitalRead(ir1)==1) && (digitalRead(ir2)==1) && (digitalRead(ir3)==1))
  {
    frente(); 
}
if ((digitalRead(ir1)==1) && (digitalRead(ir2)==0) && (digitalRead(ir3)==1))
  {
    para(); direita(); scan(); 
}
if ((digitalRead(ir1)==1) && (digitalRead(ir2)==0) && (digitalRead(ir3)==0))
  {
    para(); direita(); scan(); 
}
if ((digitalRead(ir1)==0) && (digitalRead(ir2)==0) && (digitalRead(ir3)==1))
  {
    para(); esquerda(); scan(); 
}
}
void para()
{
  servoEsq.SetSpeed(0);   
  servoDir.SetSpeed(0);
  delay(500);
}
void meiavolta()
{
  servoEsq.SetSpeed(-45);   
  servoDir.SetSpeed(-45);
  delay(2000);
}
void frente()
{
  servoEsq.SetSpeed(-45);   
  servoDir.SetSpeed(45);
  scan();
}
void tras()
{
  servoEsq.SetSpeed(45);   
  servoDir.SetSpeed(-45);
  delay(2000);
}
void direita()
{
  servoEsq.SetSpeed(-45);   
  servoDir.SetSpeed(-45);
  delay(1500);
}
void esquerda()
{
  servoEsq.SetSpeed(45);   
  servoDir.SetSpeed(45);
  delay(1500);
}
void scan()
{
  while(digitalRead(ir1));
  while(digitalRead(ir2));
  while(digitalRead(ir3));
  delay(500);
}
void flash() {               // Função chamda durante a interrupção
  digitalWrite(12, output);  // Anceder ou apagar o LED IR
  output = !output;          // Alterar o output...
}


...compila, mas não funciona, este também deve dar vontade de rir, mas temos de começar por algum lado. Sei que muita coisa deve de estar mal e tenho estado a tentar perceber o que é, mas ainda sem sucesso.
   Onde tenho o valor recebido igual a zero ou um ( ==0) já tive o "High" e o "Low", já tentei com "else" mas nada, antes de estar a usar o "void frente" e os restantes estava a usar como no 1º código ( servoEsq.SetSpeed(); ) em um dos códigos que fiz ainda executou o 1º "if" mas depois não fazia mais nada, ou eu tenho estado a perceber mal o que tenho lido ou esta-me a falhar alguma coisa.
    Alguem pode dar uma ajuda? só que me apontem o caminho penso que já deve chegar   ::)
    Sei que o post é grande mas não deu para fazer mais pequeno.

Abraços. 
Blog: A Visão do Lobo

Nick antigo: kilobyte

senso

O teu grande problema está aqui:

void scan()
{
  while(digitalRead(ir1));
  while(digitalRead(ir2));
  while(digitalRead(ir3));
  delay(500);
}


Para além de teres um delay de meio segundo em que mais nada pode ser feita, o while só acaba quando o pino ler zero/LOW, e isso terá de acontecer ao mesmo tempo para que assim passes os três whiles e a função acaba.
Avr fanboy

LoneWolf

Boas, então como faço para ler os 3 sensores ao mesmo tempo e constantemente durante o programa?

Obrigado e abraços.
Blog: A Visão do Lobo

Nick antigo: kilobyte

senso

O que é que achas que esse código está a fazer?
É que não lês o valor para lado nenhum, nem nada..
Explica-me o que queres fazer?
Queres mesmo ler essas entradas a 16Mhz e não actuar consoante as mesmas, o tempo de resposta de um motor é milhares de vezes mais lento que a capacidade de processamento do Arduino.
Avr fanboy

LoneWolf

Achava que esse código ia ler os sensores  :-[
O que eu queria fazer era ler os sensores e dependendo da leitura e fazer determinada coisa.
QuoteQueres mesmo ler essas entradas a 16Mhz e não actuar consoante as mesmas...
pois devo estar a fazer tudo mal, talvez tenha de rever tudo.
Blog: A Visão do Lobo

Nick antigo: kilobyte

senso

Vê o exemplo que está no IDE que tem o nome de blinky without delay, basta leres os sensores de 10 em 10ms, ou até mais que continuas com um tempo de resposta que para ti é imediato.
Avr fanboy

LoneWolf

#38
Boas, obrigado pela dica senso.
Mais logo a noite volto a tentar e exemplo a ver o que consigo fazer, posso estar a fazer perguntas um pouco sem sentido mas tenho de fazer mais umas, então aqui vai....
...quando diz:
QuoteQueres mesmo ler essas entradas a 16Mhz e não actuar consoante as mesmas...

então como havia de ler as entradas? a que Mhz? e como devo actuar? 

QuoteÉ que não lês o valor para lado nenhum, nem nada..

ler ate estava a ler pelos vistos mas era só um de cada vez e por sequência 1, 2, 3 não lia o 2 e o 3 sem ler o 1.
Posso estar a meter os pés pelas mãos mais uma vez, mas o código dos servos do Njay tenho de o usar pois só assim os servos estão parados.
Agora outra duvida eu estou a usar os receptores IR de 3 patas se usar este código:
#include <MsTimer2.h>
#define irx 2   // Sensor IR no pin digital 2

static boolean output = HIGH;  // Variável para defenir o estado do LED de infravermelhos, é estática para ser usada durante a interrupção

void setup(){
  pinMode(irx, INPUT);     // Pin onde está o LED infravermelhos é pin output
  Serial.begin(9600);      // Iniciar comunicação Serial com o computador...
  MsTimer2::set(5, flash); // Defenir intrrupções de 5 em 5 ms e durante a interrupção é chamada a função flash
  MsTimer2::start();       // Iniciar interrupções
}

void loop(){
  while(digitalRead(irx));   // Enquanto não houver nada no Sensor não sai daqui, o sensor coloca 1 quando n detecta nada e passa a 0 qd detecta algo
  Serial.println("ICEBERG!"); // Oi.. Apanhou qualquer coisa... OH NÂO É UM ICEBERG... OH GOD, THE PAIN, CAN YOU FEEL THE PAIN?
  // MAYDAY MAYDAY!
  // - Alô diz iz German Cost Guard, can we help you? (Sotaque alemão)
  // YES, YES! We're SINKING!
  // - Okay so what are you sinking (thinking) about? (ahha XD)
}

void flash() {               // Função chamda durante a interrupção
  digitalWrite(12, output);  // Anceder ou apagar o LED IR
  output = !output;          // Alterar o output...
}

...o receptor apanha bem o Led IR nas distancias de 10~20cm o que já chegava por agora, mas se usar este código: 
#define sensorIR 0

void setup(){

  Serial.begin(9600); //Para podermos ver o valor na consola

}

void loop(){

  Serial.println(analogRead(sensorIR));

  delay(50);

}

...e mesmo com o Led IR a piscar ou sempre ligado não apanha nada, mas se apontar o Led IR do comando da TV ate apanha demais( reflectindo o sinal por tudo quanto é canto) não sei se terá a haver com a frequência do Led IR,  mas é disso ou é outra coisa?

Desde já o meu obrigado e boa continuação   ;) que eu tenho de ir bulir mais umas 5~6 horas.
Abraços.
Blog: A Visão do Lobo

Nick antigo: kilobyte

senso

Mais logo já te dou uma ajuda no código.
Avr fanboy

LoneWolf

Bons dias,
QuoteMais logo já te dou uma ajuda no código.

Obrigado senso pela disponibilidade, fico mesmo agradecido, assim que tiver algo volto a postar, a ver se consigo fazer mais alguma coisa este fim de semana.

Abraços  ;)
Blog: A Visão do Lobo

Nick antigo: kilobyte

senso

Não garanto que compile.

#include <Servo.h>
#include <MsTimer2.h>

#define ir1 7    // Sensor IR no pin digital 7
#define ir2 2    // Sensor IR no pin digital 2
#define ir3 4    // Sensor IR no pin digital 4

static boolean output = HIGH;
unsigned long processTime = 0;

/**
* Continuous rotation servo class.
* By Njay in 2009 (EmbeddedDreams.com)
* Licensed under CC BY NC SA ([url=http://creativecommons.org/licenses/by-nc-sa/2.5/pt/]http://creativecommons.org/licenses/by-nc-sa/2.5/pt/[/url]
* Wraps a MegaServo object to control a continuous rotation servo.
* The servo should be calibrated to be stopped when Megaservo::write()
* is set to 90.
* When speed is set to 0 to stop the servo, the servo is detached to
* make sure it will be completly stopped.
*/
class ContinuousRotationServo
{
public:
ContinuousRotationServo (unsigned char pin)  {
mSpeed = 0;
SetPin(pin);
}

ContinuousRotationServo (void)  {
mSpeed = 0;
}

inline void SetPin (unsigned char pin)  {
mPin = pin;
}

// Set the speed. 0 to be stopped, > 0 to rotate in one direction
// and < 0 to rotate on the other.
void SetSpeed (signed char speed)  {
if (speed == 0)  {
if (mSpeed != 0)  {
//Serial.println("dettach");
mServo.detach();
}
}
else  {
if (mSpeed == 0)  {
//Serial.println("attach");
mServo.attach(mPin);
}
//Serial.println("set speed");
mServo.write(90 + speed);
}
mSpeed = speed;
}

inline void Detach (void)  {
mServo.detach();
}

private:
Servo          mServo;
unsigned char  mPin;
signed char    mSpeed;    // current speed
};
ContinuousRotationServo  servoDir(10);    // servo no pino 10
ContinuousRotationServo  servoEsq(9);    // outro servo, no pino 9

void setup () {
pinMode(ir1, INPUT);     // Pin onde está o LED1 infravermelhos é pin output
pinMode(ir2, INPUT);     // Pin onde está o LED2 infravermelhos é pin output
pinMode(ir3, INPUT);     // Pin onde está o LED3 infravermelhos é pin output
MsTimer2::set(5, flash); // Defenir intrrupções de 5 em 5 ms e durante a interrupção é chamada a função flash
MsTimer2::start();       // Iniciar interrupções
}

void loop(){


if(millis() - processTime >= 10){ //A cada 10ms lê os sensores e age de acordo com o que leu, podes alterar este valor

processTime = millis();
unsigned char sensores = ((digitalRead(ir1)<<2)|(digitalRead(ir2)<<1)|(1<<digitalRead(ir3))); //Junta num byte a informacao dos 3 sensores
switch(sensores){
case 0x00: {
   para();
   meiavolta();
   break;
   }

case 0x02: {
   frente();
   break;
   }

case 0x07: {
   frente();
   break;
   }

case 0x05: {
   para();
   direita();
   break;
   }

case 0x04: {
   para();
   direita();
   break;
   }

case 0x01: {
   para();
   esquerda();
   break;
   }
}
}

}
void para(){

servoEsq.SetSpeed(0);   
servoDir.SetSpeed(0);

}

void meiavolta(){

servoEsq.SetSpeed(-45);   
servoDir.SetSpeed(-45);
delay(2000);
}

void frente(){

servoEsq.SetSpeed(-45);   
servoDir.SetSpeed(45);
}

void tras(){

servoEsq.SetSpeed(45);   
servoDir.SetSpeed(-45);
}

void direita(){

servoEsq.SetSpeed(-45);   
servoDir.SetSpeed(-45);
delay(1500);
}

void esquerda(){

servoEsq.SetSpeed(45);   
servoDir.SetSpeed(45);
delay(1500);
}


void flash() {               // Função chamda durante a interrupção
digitalWrite(12, output);  // Anceder ou apagar o LED IR
output = !output;          // Alterar o output...
}
Avr fanboy

LoneWolf

Boas senso, ena ena não era preciso apanhares o peixe por mim, mas obrigado  ;) fico a dever-te uns copos ( fica prometido, um dia se nos chegarmos a encontrar).
O código compila, mas ainda não testei mas mais logo já o vou fazer. Mas já tive a ver se intendia o que fizeste e já estou com uma duvida  ;D o porque de escreveres "case 0x02" e de não ser só "case 2" ou "case 02"? Pergunto porque na pagina do arduino já vi alguns exemplos mas escreviam "case 1", "case 2",....., e por ai fora, mas ainda não tinha visto com "case 0x02" e por ai adiante.

Abraços e mais uma vez obrigado e boa continuação. 
Blog: A Visão do Lobo

Nick antigo: kilobyte

senso

No teu código tinhas estes if's:

if ((digitalRead(ir1)==0) && (digitalRead(ir2)==0) && (digitalRead(ir3)==0))
  {
    para(); meiavolta(); scan();
}
if ((digitalRead(ir1)==0) && (digitalRead(ir2)==1) && (digitalRead(ir3)==0))
  {
    frente();
}
if ((digitalRead(ir1)==1) && (digitalRead(ir2)==1) && (digitalRead(ir3)==1))
  {
    frente();
}
if ((digitalRead(ir1)==1) && (digitalRead(ir2)==0) && (digitalRead(ir3)==1))
  {
    para(); direita(); scan();
}
if ((digitalRead(ir1)==1) && (digitalRead(ir2)==0) && (digitalRead(ir3)==0))
  {
    para(); direita(); scan();
}
if ((digitalRead(ir1)==0) && (digitalRead(ir2)==0) && (digitalRead(ir3)==1))
  {
    para(); esquerda(); scan();
}


O que eu fiz foi agrupar essas 3 leituras dos 3 pinos numa unica variavel usando shift lefts e OR's, ficando assim com uma unica variavel de 8 bits, em que realidade os bits que importam são os 3 menos significativos.

Agora se seguires os teus if's um a um, e agrupares os bits dos mesmos ficas com algo assim(estou a usar a mesma ordem do teu código para ser mais facil de entenderes):

000
010
111
101
100
001


Esses bits são o que é usado para fazer as decisões e no case podia meter várias coisas, por exemplo podes meter em binário, usando a designação 0b, em hexadecimal usando o 0x ou em decimal se fizeres a conversão, uma nota, NUNCA mas NUNCA coloques numeros começados por 0, porque um numero começado por 0 quer dizer que está em notação octal e podes ter muitos problemas até perceber que o teu 011 não é realmente 11 mas sim 9, e não é algo que salte á vista.

Vamos lá então converter os teus vários numeros para várias notações diferentes:


Os teus if's        Binário           Hexa-decimal     Decimal
000                0b00000000               0x00          0
010                0b00000010               0x02          2
111                0b00000111               0x07          7
101                0b00000101               0x05          5
100                0b00000100               0x04          4
001                0b00000001               0x01          1


Como nenhum dos numeros em hexa-decimal chega a A ou seja 10 em decimal a conversão de hexa para decimal é directa, mas só neste caso especifico.
Espero que esteja claro ;)
Pode ser que um dia volte a dar um passeio por Leiria lol.
Avr fanboy

LoneWolf

Boas noites,

     bem deste-me uma "chapada" de informação, sim senhor, muito bem explicado e de fácil compreensão 5* senso e obrigado, depois da janta já testo e se tudo correr bem posto um vídeo.

QuoteEspero que esteja claro ;)

mais parece que me acendeste um holofote lol

QuotePode ser que um dia volte a dar um passeio por Leiria lol.

eu ainda fico a 40km de Leiria, mas as coisas bem combinadas lá estarei para pagar a promessa  ;)

Abraços e obrigado.
Blog: A Visão do Lobo

Nick antigo: kilobyte