QTR-8RC reflectance sensor

Boas.
já consegui fazer a leitura dos sensores, utilizei o seguinte código:

 #include <PololuQTRSensors.h>

    PololuQTRSensorsRC qtr((unsigned char[]) {9,8,7,6,5,4,3,2}, 8);

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      unsigned int readings[8];
      qtr.read(readings);
      Serial.print ("sensor1  ");
      Serial.println(readings[0]);
      delay(1000);
      Serial.print ("sensor2  ");
      Serial.println(readings[1]);
      delay(1000);
      Serial.print ("sensor3  ");
      Serial.println(readings[2]);
      delay(1000);
      Serial.print ("sensor4  ");
      Serial.println(readings[3]);
      delay(1000);
      Serial.print ("sensor5  ");
      Serial.println(readings[4]);
      delay(1000);
      Serial.print ("sensor6  ");
      Serial.println(readings[5]);
      delay(1000);
      Serial.print ("sensor7  ");
      Serial.println(readings[6]);
      delay(1000);
      Serial.print ("sensor8  ");
      Serial.println(readings[7]);
      delay(1000);
    }

agora, estou tentando fazer mover os motores consoante o código, eu ja fiz um código que calcula o erro e faz girar os motores mais ou menos consoante o erro, mas esse código só funciona em leituras digitais,

para usar estes sensores necessito de fazer leituras que a própia biblioteca define, eu ainda não percebi como essa biblioteca cálcula o erro automaticamente...

vou postar o código que fiz ( não funciona não sei porque), dizer porque tomei algumas decisões, e agradeçia muito a vossa ajuda...

#include <PololuQTRSensors.h> 

PololuQTRSensorsRC qtr((unsigned char[]) {9,8,7,6,5,4,3,2}, 8);
int motor_right = 9;
int motor_left = 10;

//variaveis auxiliares.

int ltarguetval = 0;// valor a desejar no motor left.
int rtarguetval = 0;// valor a desejar no motor right.
int lnowval = 0;    // valor actual no motor left.
int rnowval = 0;    // valor actual no motor right.

void setup(){
  Serial.begin(9600);
  
  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);
 
  int i;
  for (i = 0; i < 250; i++)
  {
    qtr.calibrate();
    delay(20);
  }
}


void loop(){
  unsigned int sensors [8];
  int position = qtr.readLine(sensors);
  int error = position -1000;
  int lastError = 0;
  int maxspeed = 130;
  double KP = 0.1;
  int KD = 5;
  int motorspeed = KP * error + KD * (error - lastError);
  lastError = error;
  
  Serial.print (qtr.readLine (sensors));
  delay(500);
 
 
  if(sensors[3] > 750 && sensors[4] > 750)
  {
    return;
  }
 
 if (error = 0){
   rtarguetval = (int)maxspeed;
   ltarguetval = (int) maxspeed;
 }
 else if (error < 0 ){
    rtarguetval = (int)motorspeed;
    error = lastError;
  }
  else if ( error > 0){
    ltarguetval = (int)motorspeed;
    error = lastError;
  }
}

bem , eu tenho 8 sensores, e eu acho que deve haver uma "função" que permite indicar o meu estado ideal dos sensores, isto é, o estado a que os sensores devem estar para os motores andarem à máxima velocidade, e que nesse apenas nesse estado o erro seja 0., eu defini isso aqui:

if(sensors[3] > 750 && sensors[4] > 750)
  {
    return;
  }

, desejo que apenas os dois sensores do meio vejam preto, isto está correcto? (eu acho que não, mas não encontro outra forma de fazer isto, por isso estou pedinso a vossa ajuda),

e entendi que se esse fragmento não se verificasse existiria um erro, erro esse que iria determinar a velocidade dos motores..

se me conseguirem ajudar agradçeia imenso..

qual é este erro que você quer calcular?
quais os sensores no array sensors[] ativam quais motores?
você quer apenas detectar valores acima de 750? isso implica claro ou escuro certo?
Baseado nisso posso te ajudar a criar uma função que dado os sensors e sensors[j] , ele move o robo para das direções desejadas

vê este link:

eu coloquei 750 porque foi o que vi no código ( se tiver valores muito altos, os sensores estão sobre o preto, e vice versa, o valor dos sensores varia entre 0-4000).

a minha duvida mantêm-se, eu ali coloquei para fazer return quando o sensor 3 e 4 vir um valor acima de 750, porque entendi que esse valor é o valor dos sensores que eu quero que veja preto (mas volto a dizer, penso que isso está mal), daí pergunto, de todas as instruções da Pololu, como eu defino "o meu estado ideal " do robot, ou seja, o estado que os sensores devem estar para os dois motores girarem à maxima velocidade,

e quando esse estaod não se verifique exista um erro, que faça um determinado motor (curva pouco apertada) abrandar pouco, ou então abrandar muito (cruva muito apertada) e assim o robot fazer as curvas de forma perfeita!

(link das funções da Pololu)

eu já concretizei um código para usar com 5 sensores "normais" (leitura digital) e calculo o erro manualmente, mas com as funções da Pololu esse erro pode ser calculado automaticamente, e é essa a minha duvida ainda, como ele é calculado..

se quiseres que deixe aqui esse código que fiz para o poderes ver diz, eu já tentei adaptar esse codigo a estes sensores ( em vez de ver valores digitais coloquei o valor 4000 (que é quando estes sensores estão mesmo sobre o preto), mas o compilador aponta muitos erros, pois a forma de leiitura destes sensores também é diferente "dos normais" e o compilador não deve aceitar isso..

Olá Fred,
Então, lendo a documentação ficou mais claro,
vou te explicar
O método readLine lê o estado de todos os sensores, atualiza o array de entrada no seu caso sensors[], depois retorna a posição estimada da linha abaixo do seu sensor.
no seu caso com 8 sensores temos

void loop(){
  unsigned int sensors [8];
  int position = qtr.readLine(sensors);


  /'position tem um valor dado por

  0     *leitura_sensor1 + 1000*leitura_sensor2
  2000*leitura_sensor3 + 3000*leitura_sensor4
  4000*leitura_sensor5 + 5000*leitura_sensor6
  6000*leitura_sensor7 + 7000*leitura_sensor8
  
  Portanto , se position = 0, a linha preta esta abaixo do sensor1, 
  se position = 5000 ,  a linha preta esta abaixo do sensor 6, e assim
  por diante.
  position vai de 0 a 7000;
 
  a função erro, ele faz no exemplo para ajustar a posição dos sensores no robô, isso depende da geometria do seu sistema, por exemplo se você colocou esse array de sensores no meio do seu robô, provavelmente estará interessado nisso,

-3500 -2500 -1500 0 1500 2500 3500, onde o 0 é o meio entre os sensores 0,3 e 4,7 , certo?

portanto sua função erro vai ser


 /*
  int error = position -3500;

 //pronto agora vc pode verificar o seguinte

 if(error > 1000){ // qualquer valor acima de 1000
  //algum dos sensores da direta esta ativado
  motor_direira();// funcao que ativa o motor da direita
 }
 if(error < -1000){ // qualquer valor acima de -1000
  //algum dos sensores da esquerda esta ativado
  motor_esquerda();// funcao que ativa o motor da esquerda
 }

Note que desta maneira você esta avaliando se algo esta ocorrendo em média do lado esquerdo e do lado direito, mas você ainda tem a informação de qual sensor , dos 8, estão com uma linha em baixo ou não..
você poderia fazer um robô com trajetórias complexas., seguindo varias linhas!
Espero ter ajudado!

qualquer coisa estamos por ai
até!

Boas.
isto aqui: -3500 -2500 -1500 0 1500 2500 3500, onde o 0 é o meio entre os sensores 0,3 e 4,7 , certo?

porque colocaste os valores de -3500 a 3500?

eu fiz esta programação, mas não funciona, talvez o meu erro venha daí..

#include <PololuQTRSensors.h>

PololuQTRSensorsRC qtr((unsigned char[]) {9,8,7,6,5,4,3,2}, 8);
int motor_right = 9;
int motor_left = 10;

//variaveis auxiliares.

int ltarguetval = 0;// valor a desejar no motor left.
int rtarguetval = 0;// valor a desejar no motor right.
int lnowval = 0;    // valor actual no motor left.
int rnowval = 0;    // valor actual no motor right.

void setup(){
  Serial.begin(9600);

  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);

  int i;
  for (i = 0; i < 250; i++)
  {
    qtr.calibrate();
    delay(20);
  }
}


void loop(){
  unsigned int sensors [8];
  int position = qtr.readLine(sensors);
  int error = position -3500;
  int lastError = 0;
  int maxspeed = 130;
  double KP = 0.1;
  int KD = 5;
  int motorspeed = KP * error + KD * (error - lastError);
  lastError = error;

  Serial.println (qtr.readLine (sensors));
  delay(500);


  if(sensors[3] > 750 && sensors[4] > 750)
  {
    return;
  }

 if (error = 0){
   rtarguetval = (int)maxspeed;
   ltarguetval = (int) maxspeed;
 }
 else if (error < 3500 ){
    ltarguetval = (int)motorspeed;
    rtarguetval = maxspeed;
    error = lastError;
  }
  else if ( error > 3500){
    rtarguetval = (int)motorspeed;
    ltarguetval = maxspeed;
    error = lastError;
  }
    if(rtarguetval > rnowval){
    rnowval +=1;
  }else if (rtarguetval < rnowval){
    rnowval -=1;
  }
  if (ltarguetval > lnowval){
    lnowval +=1;
  }else if(ltarguetval < lnowval){
    lnowval -=1;
  }
}

diz o que achas do meu código, e erros que aches que possam estar afectar o mau funcionamento do robot indicamos, ou mesmo corrige mos sff..

outra coisa..
quando estou a fazer o readline, se colocar o dedo em cima do sensor 7, obtenho o valor 7000, o do lado, 6000, mas os outros nunca altera o valor, de vez em quando altera mas para valores pouco fiaveis, ou zeros, ou 4000, fico sem perceber porque.. no entanto confiremei as ligações dos sensores e estão todas correctas..

consegues ajudar me?

ahh! e explica me isto "onde o 0 é o meio entre os sensores 0,3 e 4,7 , certo?" não percebi...

o que eu quero que o robot faça é que ambos os motores girem à maxima velocidade quando tiver os dois sensores do meio no preto(sensor 3 e 4), não percebi o que disseste..

depois vê o meu codigo e tenta corrigit me sff..
Obrigado pela ajuda Radamés.

Olá Fred,
então quando position = 0 , isto é o sensor zero supostamente tampado e todos os outros aberto, o error = position - 3500, isto dá , erro = -3500, outro caso, quando a position = 3000, isto é o sensor 4 esta tampado e todos os outro aberto, error = 500, no final eu havia errado, os valores corretos para o erro, com centro nos sensores, 3 e 4 serão.
-3500 -2500 -1500 -500 500 1500 2500 3500
entende?

para o motor a maxima velocidade com a linha entre 3 e 4 eu faria

if(error >-500 && error < 500){
  motor na maxima velocidade
}else if(error > 500){
  liga motor da direita e desliga esquerda, talvez?!??!

}else if(error<-500){
  liga motor da esquerda e desliga o da direita, ??!??!
}

acho que é isso!
até!

mas não funciona:/
eu tenho os 8 sensores ligados, e ao colocar o meu dedo por cima dum sensor (um a um) o qtr.readline não me indica os valores esperados (0, 1000, 2000, etc), no entanto vai variando...
podemos trocar e-mails para me poderes ajudar melhor?

isto protasse duma forma muito estranho...
por exemplo, eu tinha o Serial monitor aberto, e colocava um objecto preto sobre o sensor 7, e dava me o valor 7000, 6, 6000 etc....

fecho o Serial monitor e volto abrir e so me gera zeros :-/ , porque acontece isso?estou mesmo sem saber o que fazer...

fiz este simples código so para ler o valor dos sensores:

#include <PololuQTRSensors.h>

PololuQTRSensorsRC qtr((unsigned char[]) {9,8,7,6,5,4,3,2}, 8);

void setup(){
  Serial.begin(9600);
  int i;
  for (i = 0; i < 250; i++)
  {
    qtr.calibrate();
    delay(20);
  }
}

void loop(){
  
  unsigned int sensors [8];
  int position = qtr.readLine(sensors);
  
  Serial.println (qtr.readLine (sensors));
  delay(500);
}

os unicos valores que obtenho são zeros..:S perciso mesmo de ajuda...

entre em contato comigo por email!
radamajna at gmail dot com

ja adicionei você,
se não receber nada diga algo por aqui...
obrigado pela disponibilidade radames :wink:

Boas.
acho que já sei onfde esta o meu erro na programação..
aqui : "-3500 -2500 -1500 -500 500 1500 2500 3500 ", eu nao defini isto no meu código, podes me dizer como defino estes valores de erro para o meu codigo??..

vê este código:

#include <PololuQTRSensors.h>

PololuQTRSensorsRC qtr((unsigned char[]) {9,8,7,6,5,4,3,2}, 8);
int motor_right = 9;
int motor_left = 10;

//variaveis auxiliares.

int ltarguetval = 0;// valor a desejar no motor left.
int rtarguetval = 0;// valor a desejar no motor right.
int lnowval = 0;    // valor actual no motor left.
int rnowval = 0;    // valor actual no motor right.

void setup(){
  Serial.begin(9600);

  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);

  int i;
  for (i = 0; i < 250; i++)
  {
    qtr.calibrate();
    delay(20);
  }
}


void loop(){
  unsigned int sensors [8];
  int position = qtr.readLine(sensors);
  int error = position -3500;
  int lastError = 0;
  int maxspeed = 130;
  double KP = 0.1;
  int KD = 5;
  int motorspeed = KP * error + KD * (error - lastError);
  lastError = error;

  Serial.println (qtr.readLine (sensors));
  delay(500);


  if(sensors[3] > 750 && sensors[4] > 750)
  {
    return;
  }

 if (error = 0){
   rtarguetval = (int)maxspeed;
   ltarguetval = (int) maxspeed;
 }
 else if (error < 3500 ){
    ltarguetval = (int)motorspeed;
    rtarguetval = maxspeed;
    error = lastError;
  }
  else if ( error > 3500){
    rtarguetval = (int)motorspeed;
    ltarguetval = maxspeed;
    error = lastError;
  }
    if(rtarguetval > rnowval){
    rnowval +=1;
  }else if (rtarguetval < rnowval){
    rnowval -=1;
  }
  if (ltarguetval > lnowval){
    lnowval +=1;
  }else if(ltarguetval < lnowval){
    lnowval -=1;
  }
}

esses valores não estão ai declarados pois não? apenas declaro o -3500, como declaro os outros??.. perciso de os declarar para que "ele saiba" que para os valores -500 e 500 tenho o sensor 3 e 4..

esqueçe o meu psit anterior,
eu ja percebi essa minha duvida, eu a definir "position -3500) estou a dizer que o se tiver o ultimo sensor da esquerda tapado tenho -3500, e de seguida esse valor vai variar de 1000 em 1000, consecutivamente, e a partir desse valor defino o "meu estado dos sensores" para que o robot ande à maxima velocidade...

mas fiz este codigo...

#include <PololuQTRSensors.h>

PololuQTRSensorsRC qtr((unsigned char[]) {9,8,7,6,5,4,3,2}, 8);
int motor_right = 10;
int motor_left = 11;

//variaveis auxiliares.

int ltarguetval = 0;// valor a desejar no motor left.
int rtarguetval = 0;// valor a desejar no motor right.
int lnowval = 0;    // valor actual no motor left.
int rnowval = 0;    // valor actual no motor right.

void setup(){
  Serial.begin(9600);

  pinMode (motor_right, OUTPUT);
  pinMode (motor_left, OUTPUT);

  int i;
  for (i = 0; i < 250; i++)
  {
    qtr.calibrate();
    delay(20);
  }
}


void loop(){
  unsigned int sensors [8];
  int position = qtr.readLine(sensors);
  int error = position -3500;
  int lastError = 0;
  int maxspeed = 130;
  double KP = 0.1;
  int KD = 5;
  int motorspeed = KP * error + KD * (error - lastError);
  lastError = error;

  Serial.println (position);
  delay(500);


  if(sensors[0] > 750 && sensors[1] > 750 && sensors[2] > 750 && sensors[3] > 750 && sensors[4] > 750 && sensors[5] > 750 && sensors[6] > 750 && sensors[7] > 750)
  {
    return;
  }

if(error >-500 && error < 500){
   rtarguetval = (int)maxspeed;
   ltarguetval = (int) maxspeed;
   error = lastError;
 }
 else if (error > 500 ){
    rtarguetval = (int)motorspeed;
    ltarguetval = maxspeed;
    error = lastError;
  }
  else if ( error < -500){
    ltarguetval = (int)motorspeed;
    rtarguetval = maxspeed;
    error = lastError;
  }
    if(rtarguetval > rnowval){
    rnowval +=1;
  }else if (rtarguetval < rnowval){
    rnowval -=1;
  }
  if (ltarguetval > lnowval){
    lnowval +=1;
  }else if(ltarguetval < lnowval){
    lnowval -=1;
  }
}

parece me estar correcto (vê e comenta sff), mas não funciona...

eu ao fazer o print de position, os valores que eu vou obter, nao vao ser de -3500 a 3500, mas sim de 0 a 7000 ( os tais valores que cada sensor gera se estiver tapado, pq faz isso??

como altero o código para que o qtr.readline varie de -3500 a 3500?

e ainda há outra coisa estranhissima que me acontece :-X nunca me aconteceu isto antes... eu tenho o serial monitor aberto e esta me a gerar uns valores (correctos, de 0 a 7000) se fechar e abrir o monitor de novo, já pode não me ser gerado esses valores, ou gera so zeros, ou outros valores, mas diferentes... sabes algum motivo que possa estar a provocar isso?...

Olá Fred,
Você não declara esses valores de erros, a partir do valor da position você faz um reajusta
error = position - 3500, supondo que seu position funcione corretamente, 0, 1000, 2000, .... 7000, o error vai reajustar isso para uma valor entre -3500 e 3500, pois quando position = 0 , error = 0 - 3500 =0 ou quando position = 7000 entao error = 7000 - 3500 = 3500, certo?

até

sim isso eu entendi..
mas esses valores não estão reajustando..
eu só obtenho valores de 0 a 7000 consoante o sensor que estiver tapado.. e não valores de -3500 a 3500, o que estou fazendo de errado no codigo ?

vc precisa imprimir o error e não o position

 Serial.println (error);

se eu fizer isso o unico valor que me gera é -3500 :-/

vc já me adicionou no gtalk? radamajna at gmai dot com
me passa seu contato

sim add..
fred_pgomes@hotmail.com