Pages: [1] 2   Go Down
Author Topic: Array de sensores CNY70,  (Read 1848 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Boas.
estou a efectuar um código para um seguidor de linhas, para isso tenho 5 sensores cny70 (não são cny70 mas são muito semelhantes e funcionam da mesma forma), e estou procurando obter um erro, e consoante esse erro o robot irá diminuir mais/menos a velocidade de um dos motores.

o que me acontece é que ao imprimir o valor do errorval este nunca me varia de 0.0, alguem em consegue ajudar e ver o que tenho de errado no código?

Code:
/* variaveis de utilizadas*/

const int nsensores = 5;
const int sensor[] = {2,3,4,5,6};
const int motor_right = 10;
const int motor_left = 11;

/* variaveis auxiliares*/
 
int senval[] = {0,0,0,0,0};
int vel_right = 0;
int vel_left = 0;
int maxvel = 200;
double errorval = 0.0;
boolean stop = false;

void setup(){
  Serial.begin(9600);
  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);
  pinMode (0, INPUT);
  pinMode (1, INPUT);
  pinMode (2, INPUT);
  pinMode (3, INPUT);
  pinMode (4, INPUT);
  digitalWrite (0, HIGH);
  digitalWrite (1, HIGH);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  digitalWrite (4, HIGH);
}
void loop(){
  
  //1º lemos o valor dos sensores
  readALLsensores();
  
  if(errorval < 0.0){
    vel_left = (int)(maxvel*(1-fabs(errorval)));
    vel_right = (int)(maxvel);
  }
  else if(errorval > 0.0){
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel*(1-errorval));
  }
  else{
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel);
  }
  //Fazer actuar os motores:
  analogWrite(motor_right,vel_right);
  analogWrite(motor_left, vel_left);
 
  delay(10);
  Serial.println(errorval);
  delay(500);
 
}

//FUNÇOES:
void readALLsensores(){
  for (int i=0; i < nsensores; i++)
  {
    senval[i] = digitalRead (sensor[i]);
  }
}

// escolher o sensor que esta sobre a linha
int bestsensor(int senval[])
{
  int best = 0;
  for (int i=0; i < nsensores; i++)
  {
    if(senval[i] == 1){
      best = i;    
    }
  }
  return best;
}
double error(int senval[])
{
  int best = bestsensor (senval);
  double lineError(int senVal[]);
 
  double error = 0.0;
  errorval = error;
 
  if (best== 0){
    error = -1.0;
  }
  else if(best== 1){
    error = -0.5;
  }
  else if( best == 2){
    error = 0.0;
  }
  else if(best == 3){
    error = 0.5;
  }
  else if(best == 4){
    error = 1.0;
  }
  return error;
}

experimentei também este código simples, e o errorval nunca m varia de 1.0, são coisas que eu não consigo perceber e perciso de ajuda, :

Code:
int sensor1 = 2;
int sensor2 = 3;
int sensor3 = 4;
int sensor4 = 5;
int sensor5 = 6;
double errorval = 0.0;

void setup(){
  Serial.begin(9600);
  digitalWrite(sensor1, HIGH);
  digitalWrite(sensor2,HIGH);
  digitalWrite(sensor3,HIGH);
  digitalWrite(sensor4,HIGH);
  digitalWrite(sensor5,HIGH);
}

void loop(){
  
  if(digitalRead(sensor1 == 1)){
    errorval = 1.0;
  }
  else if (digitalRead(sensor2 == 1)){
    errorval = 0.5;
  }
  else if (digitalRead(sensor3 == 1)){
    errorval = 0.0;
  }
  else if (digitalRead(sensor4 == 1)){
    errorval = -0.5;
  }
  else if(digitalRead (sensor5 == 1)){
    errorval = -1.0;
  }
  Serial.println(errorval);
  delay(500);
}

Logged

Rio de janeiro
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

No primeiro, vc não chama a função que atualiza o valor do erro. Por isso, o errorval continua com o valor inicial. 0.0.

Eu não consegui entender o porque de vc chamar a função digitalWrite (0, HIGH); quando vc quer que a porta funcione como uma entrada... Também, vc coloca as por 0~4 como input, mas depois lê as portas 2~6.

Att.
Logged

Sao Paulo - Brazil
Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

olá Fred,
como vc ligou os cny70 no arduino? vc tem um circuito amplificador com lm324?? ele veio com um circuito de suporte? mande os diagramas...
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ja alterei o código:

Code:
/* variaveis de utilizadas*/

const int nsensores = 5;
const int sensor[] = {2,3,4,5,6};
const int motor_right = 10;
const int motor_left = 11;

/* variaveis auxiliares*/
 
int senval[] = {0,0,0,0,0};
int vel_right = 0;
int vel_left = 0;
int maxvel = 200;
double errorval = 0.0;
boolean stop = false;

void setup(){
  Serial.begin(9600);
  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);
  pinMode (0, INPUT);
  pinMode (1, INPUT);
  pinMode (2, INPUT);
  pinMode (3, INPUT);
  pinMode (4, INPUT);
  digitalWrite (0, HIGH);
  digitalWrite (1, HIGH);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  digitalWrite (4, HIGH);
}
void loop(){
 
  //1º lemos o valor dos sensores
 
  ReadALLSensores();
  
  if(errorval < 0.0){
    vel_left = (int)(maxvel*(1-fabs(errorval)));
    vel_right = (int)(maxvel);
  }
  else if(errorval > 0.0){
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel*(1-errorval));
  }
  else{
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel);
  }
  //Fazer actuar os motores:
  analogWrite(motor_right,vel_right);
  analogWrite(motor_left, vel_left);
 
  delay(10);
  
  Serial.println(errorval);
  delay(500);
 
}
void readAllSensors(){
  for(int i=0; i < 5; i++)
  {
    senVal[i] = digitalRead(sensor[i]);
  }
}
  

// escolher o sensor que esta sobre a linha
double LineError(senval[])
{
  double error = 0.0;
int senval[] = {0,0,0,0,0};
  
for (int i=0; i < nsensores; i++)
  {
    senval[i] = digitalRead (sensor[i]);
  }
  if (senval) == 0b10000){
    error = -1.0;
  }
  else if (senval) == 0b11000){
    error = -0.75;
  }
  else if (senval) == 0b01000){
    error = -0.5;
  }
  else if (senval) == 0b01100){
    error = -0.25;
  }
  else if(senval) == 0b00100 || 0b01110){
    error = 0.0;
  }
  else if (senval) == 0b00110){
    error = 0.25;
  }
  else if(senval) == 0b00010){
    error = 0.5;
  }
  else if (senval) == 0b00011){
    error = 0.75;
  }
  else if (senval) == 0b00001){
    error = 1.0;
    }
  }
}


mas aponta -me erros nesta última função, alguem sabe a que se trata?
« Last Edit: May 17, 2010, 03:30:17 pm by Fred_Gomes » Logged

Rio de janeiro
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Você pode colocar o erro que aparece?

É erro de compilação ou erro na hora de rodar?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

era erro de compilação..
bem, já aqui tenho o código um bocado alterado (com a ajuda de membros fo forum "Lusorobotica" , só que não consigo fazer com o valorsensor seja apenas zeros e uns, pois também aparecem zeros, alguem sabe trabalhar bem com o sistema binário no arduino? e saber assim o que esta errado neste códido que me provoca uma má leitura do erro..

Code:
/* variaveis de utilizadas*/

const int nsensores = 5;
const int sensor[] = {2,3,4,5,6};
const int motor_right = 10;
const int motor_left = 11;

/* variaveis auxiliares*/
 
int senval[] = {0,0,0,0,0};
int vel_right = 0;
int vel_left = 0;
int maxvel = 200;
double errorval = 0.0;
boolean stop = false;

void setup(){
  Serial.begin(9600);
  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);
  pinMode (2, INPUT);      
  pinMode (3, INPUT);      
  pinMode (4, INPUT);      
  pinMode (5, INPUT);
  pinMode (6, INPUT);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  digitalWrite (4, HIGH);
  digitalWrite (5, HIGH);
  digitalWrite (6, HIGH);
}
void loop(){
 
  
 errorval = LineError();  
  if(errorval < 0.0){
    vel_left = (int)(maxvel*(1-fabs(errorval)));
    vel_right = (int)(maxvel);
  }
  else if(errorval > 0.0){
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel*(1-errorval));
  }
  else{
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel);
  }
  //Fazer actuar os motores:
  analogWrite(motor_right,vel_right);
  analogWrite(motor_left, vel_left);
 
  delay(10);
  

}
 
// escolher o sensor que esta sobre a linha

double LineError()
{
  double error = 0.0;
  for (int i=5; i < nsensores; i++){
  
    senval[i] = digitalRead (sensor[i]);
    Serial.println (senval[i]);
    delay(500);
  }
  unsigned int valorsensor=senval[2]+senval[3]<<3+senval[4]<<4+senval[5]<<5+senval[6]<<6;   //o que isto faz é juntar os valores do array senval num numero só                                 //assim já podes fazer as comparações nos if's
  if (valorsensor== 0b10000){
    error = -1.0;
  }
  else if (valorsensor == 0b11000){
    error = -0.75;
  }
  else if (valorsensor == 0b01000){
    error = -0.5;
  }
  else if (valorsensor == 0b01100){
    error = -0.25;
  }
  else if(valorsensor == (0b00100 || 0b01110)){
    error = 0.0;
  }
  else if (valorsensor == 0b00110){
    error = 0.25;
  }
  else if (valorsensor == 0b00010){
    error = 0.5;
  }
  else if (valorsensor == 0b00011){
    error = 0.75;
  }
  else if (valorsensor == 0b00001){
    error = 1.0;
  }
  Serial.println(valorsensor);
  delay(200);

  return error;
}
« Last Edit: May 17, 2010, 05:50:45 pm by Fred_Gomes » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Observe o seguinte codigo dentro do metodo: double error(int senval[])

...
  double error = 0.0;
  errorval = error;
....
voce esta atribuindo o valor 0.0 a variavel erro, depois atribuindo a variavel ao errorval, ou seja errorval esta ficando igual a zero.

Ou seja, a variavel (neste caso global) errorval vai ficar sempre zero.

Se esta trabalhando com uma variavel global, voce pode tratar ela sem a necessidade de uma função que retorna algum valor.

Recomendo retirar a variavel local error da função double error(int senval[]).

Qualquer coisa entre em contato.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sobre a segunda questão:

Cara você tem que ter enfoque na solução, não no problema. Porque motivo esta trabalhando com binário e fazendo operação de bit.........a  não ser que esteja estudando esses tipos de operações....
A única coisa que tem que fazer e verificar qual o sensor que esta com o maior valor(ou menor) para descobrir qual o sensor esta mais próximo da linha.

Outra coisa, coloque nome de métodos mais descritivo, lineError que dizer algum erro mais nada haver com “escolhe sensor que esta sobre a linha”, desculpe mais seu código esta muito ruim, você poderia ter colocando o método simplesmente como escolhe_senser_que_esta_sobre_a_linha(), garanto a você que qualquer um conseguiria entender.

Outra coisa é sobre essa operação de igualdade.....veja bem o que esta fazendo.....eu não vou nem comentar.

Segue um codigo so para mostrar como pode ser feito:

int escolhe_sensor_que_esta_sobre_a_linha(){
      int sensor = 0;
      double error = 0.0;
      //busca pelo sensor que esta mais proximo da linha, ou seja, esta captando valor mais escuro
  for (int i=5; i < nsensores; i++){
      int valor = digitalRead (sensor);
      if( valor > sensor){
       sensor = valor;
      }
  }
  return sensor;
}



Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Boas.
eu ainda começei à pouco tempo a mexer no arduino, tenho algumas dificuldades de programação..

se eu fizer como dizes ( a escolher o sensor que esta mais próximo da linha), eu não vou poder ter mais que 1 sensor sobre a linha, e isso muitas das vezes vai acontecer, daí optar por  fazer a leitura do array (em binário), mas ´coidog não funciona,

eu consigo ler o senval correctamente, mas o valorsensor é sempre 0, juntamente com error..
Logged

Rio de janeiro
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

O que vc precisa está mais ou menos nessa página:
http://arduino.cc/en/Reference/Bitshift

Ficaria mais ou menos assim:
byte sensores = 0;
FOR DE LEITURA
  sensores = (sensores << 1) + digitalRead(sensor[...]);
END

no começo o sensores == B00000000. Cada vez que vc usa o sensores<<1 ele desloca todos os bits na direção da seta por uma casa(acrescentado um 0 no espaço novo). O resultado de digital... é sempre 1 ou 0.
Digamos que o primeiro sensor retornou 1. Então
ERA sensores == B00000000
sensores << 1 não muda nada
digital... retorna 1, então no final
sensores = B00000001

O segundo leitor retornou 0, do mesmo modo,
sensores << 1 retorna B00000010
somando com o digital...
retorna B00000010.

E assim por diante. O resultado então de sensores vai ser
B000ABCDE
Onde A primeiro sensor, B segundo,...

Só que, toda essa parafernalha com bits só é útil para poupar espaço na memória do arduino.
Se a memória não for um fator limitante, basta fazer como vc estava antes, armazenando tudo em um array, e depois verificar cada caso com &&

Se vc quiser saber se só o primeiro e segundo estão retornando 1,
Code:
if((sensores[0] == 1) &&
   (sensores[1] == 1) &&
   (sensores[2] == 0) &&
   (sensores[3] == 0) &&
   (sensores[4] == 0)     )

Pensa um pouco a respeito e vê se consegue resolver.
Logged

Rio de janeiro
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

P.S.: Acho que a parafernalha com bits também adicionaria um pouquinho de velocidade às operações. Ainda assim, acho que não seria uma diferença perceptível no seu caso.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

eu não percebi bem o que isto faz:

if((sensores[0] == 1) &&
   (sensores[1] == 1) &&
   (sensores[2] == 0) &&
   (sensores[3] == 0) &&
   (sensores[4] == 0)     )


 o código que apresento asseguir já me retorna bem os valores em binário (imprindo os valores em binário em décima),

Code:
/* variaveis de utilizadas*/

const int nsensores = 5;
const int sensor[] = {2,3,4,5,6};
const int motor_right = 10;
const int motor_left = 11;

/* variaveis auxiliares*/
 
int senval[] = {0,0,0,0,0};
int vel_right = 0;
int vel_left = 0;
int maxvel = 200;
double errorval = 0.0;
boolean stop = false;

void setup(){
  Serial.begin(9600);
  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);
  pinMode (2, INPUT);    
  pinMode (3, INPUT);    
  pinMode (4, INPUT);    
  pinMode (5, INPUT);
  pinMode (6, INPUT);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  digitalWrite (4, HIGH);
  digitalWrite (5, HIGH);
  digitalWrite (6, HIGH);
}
void loop(){
 errorval = LineError();

 
 
  if(errorval < 0.0){
    vel_left = (int)(maxvel*(1-fabs(errorval)));
    vel_right = (int)(maxvel);
  }
  else if(errorval > 0.0){
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel*(1-errorval));
  }
  else{
    vel_left = (int)(maxvel);
    vel_right = (int)(maxvel);
  }
  //Fazer actuar os motores:
  analogWrite(motor_right,vel_right);
  analogWrite(motor_left, vel_left);
 
  delay(200);

}
 
// escolher o sensor que esta sobre a linha

double LineError()
{
  double error = 0.0;
  int valorsensor = 0;
  for (int i=0; i < nsensores; i++){
  
    senval[i] = digitalRead (sensor[i]);
  }
  valorsensor = (senval[0]) | (senval[1]<<1) | (senval[2]<<2) | (senval[3]<<3) | (senval[4]<<4);
  Serial.println ("valor do sensor");
  Serial.println(valorsensor);
  delay(500);


  if (valorsensor== 0b10000){
    error = -1.0;
  }
  else if (valorsensor == 0b11000){
    error = -0.75;
  }
  else if (valorsensor == 0b01000){
    error = -0.5;
  }
  else if (valorsensor == 0b01100){
    error = -0.25;
  }
  else if((valorsensor==0b00100) || (0b01110)){
    error = 0.0;
  }
  else if (valorsensor == 0b00110){
    error = 0.25;
  }
  else if (valorsensor == 0b00010){
    error = 0.5;
  }
  else if (valorsensor == 0b00011){
    error = 0.75;
  }
  else if (valorsensor == 0b00001){
    error = 1.0;
  }
  return error;
}

já experimentei colocar o valor décimal nos IF´s (equivalente ao valor em binário), mas o error nunca me varia de 0.0 não sei pq..
no entanto já obtenho os valores que necessito, so me falta resolver este problema..
Logged

Rio de janeiro
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nesse caso, o problema tá na linha:
Code:
 else if((valorsensor==0b00100) || (0b01110)){
    error = 0.0;
  }

Olha com mais cuidado a condição do if:
Code:
(valorsensor==0b00100) || (0b01110)
Ela é composta por duas partes:
Code:
(valorsensor==0b00100)
e
Code:
(0b01110)
ligados pelo ||.

A primeira, retorna se a igualdade é verdadeira ou não. A segunda, não tem nenhuma comparação, é só o valor puro (diferente de 0). Lembrando que 0 é  falso e qualquer coisa diferente é verdadeiro, qual o resultado da avaliação da condição do seu if?

O trecho que vc não entendeu faz exatamente o que eu disse:
vê se a resposta do primeiro e segundo senssores é 1 e o resto é 0.
Conheçe o &&?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oh,
eu entendi sim..
eu conheço o &&, eu disse que não estava entendendo pq vc fez isso em linhas separadas, e eu estou habituado numa so linha..

mas pq necessito eu desses and´s?,

eu aqui:
Code:
(valorsensor==0b00100) || (0b01110)
o que o arduino vai fazer é se valorsensor == 0b00100/ab1110,

não percebo qual o problema..
eu obtenho os algarismos (em decima), do array em binário que estou usando, como coloco isso agora para me gerar um erro?, não bastaria colocar um seguimento de IF´s para esse svalores ?

algo do tipo:

Code:
se (31){ error = 0.0;
o código está mal escrito, mas é so para  me fazer perceber, não bastaria fazer apenas algo assim? é que eu ja fiz isso e o error nunca sai de 0.0 não sei pq..
Logged

Rio de janeiro
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Separei as linhas sem nenhum motivo especial. Só pq ficou um pouco mais fácil de digitar.

O problema é exatamente esse.
Code:
(valorsensor==0b00100) || (0b01110)
Isso não avalia o que vc está achando.
Para ser do jeito que vc quer, deveria ser:
Code:
(valorsensor==0b00100) || (valorsensor=0b01110)

Tenta entender a diferença. Acho que vc ainda não chegou bem no ponto do que significa || e &&.

Qqer coisa, fala.
Logged

Pages: [1] 2   Go Up
Jump to: