QTR-8RC reflectance sensor (with Arduino Duemilanove)

Hello,

You did not set the motor speeds to 130. What line of code do you think did this?

It sounds like you do not understand PID, especially the importance of the D term. Instead of asking us how it works, you should go read about it somewhere, such as on wikipedia.

Again, we cannot help you with your motor control without knowing what motor driver or controller you are using.

-Paul

I’m using two DC motors, and I intend to do what was mentioned before, if 00011000 both motors turn at maximum speed, if any, 00110000, left the engine slows down a little, but if you have: 1100000, the engine on the left ja slows a lot, that’s what I do …

I mensiono speed of 130 engines here: maxspeed int = 130;

however I am struggling to put the engines walk according to the error (calculated automatically), and that’s what I’m asking to help me …

Setting a variable is not the same thing as setting the actual speeds of your motors. To do that you need to send a command to some kind of motor controller or use a PWM output of the Arduino connected to a motor driver. Do you have a motor controller or motor driver?

-Paul

yes I have, I am using the L293D,
I know I have to do this, but I have doubts how to do this in my code, and that’s what I’m asking for help …
if I pdoesse exemplify a code to adjust the speed of my motors to the calculated error thanks …

Ps: I can illustrate this in my code please? adds two variables ara the 2 engines and exemplifies me a code to use the variables created …

Okay, the example you copied the code from had two variables defined:

#   // M1 and M2 are base motor speeds.  That is to say, they are the speeds the motors should  
#   // spin at if you are perfectly on the line with no error.  If your motors are well matched,  
#   // M1 and M2 will be equal.  When you start testing your PID loop, it might help to start with  
#   // small values for M1 and M2.  You can then increase the speed as you fine-tune your  
#   // PID constants KP and KD.  
#   int m1Speed = M1 + motorSpeed;  
#   int m2Speed = M2 - motorSpeed;  
#   
#   // it might help to keep the speeds positive (this is optional)  
#   // note that you might want to add a similiar line to keep the speeds from exceeding  
#   // any maximum allowed value  
#   if (m1Speed < 0)  
#     m1Speed = 0;  
#   if (m2Speed < 0)  
#     m2Speed = 0;

What else do you need?
-Paul

#include <PololuQTRSensors.h> 

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

void setup(){
  
  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 (position);
  delay(500);
 
 
  if(sensors[3] > 750 && sensors[4] > 750)
  {
    return;
  }
 
 if (error = 0){
   motor_right = (int)maxspeed;
   motor_left = (int) maxspeed;
 }
 else if (error < 0 ){
    right_motor = (int)motorspeed;
    error = lastError;
  }
  else if ( error > 0){
    left_motor = (int)motorspeed;
    error = lastError;
  }
}

what do you think of my code? more properly how to use PID control, it seems to him right?

Ps: the code accuses some mistakes, says that the variables “motor_right” and “motor_left” encontrolo not within that scope, but it’s gonna need it? I have seen those variables declared at the beginning of the code?

Hello,

If you have an error message, please copy and paste it directly instead of just describing what it was like. If you pay attention to the actual error message, you will see that it is complaining about “right_motor” not being defined, which is correct.

Anyway, it seems like you have some real confusion about what you are doing.

First, the idea with our code was that when motorspeed is negative, you turn to one side, and when it is positive, you turn to the other side. If you had an Orangutan controller, you could do something as simple as:

set_motors(255+motorspeed,255-motorspeed);

with no if() at all.

Second, you still do not have any code to actually set the speed of your motors. You need to go ask on the Arduino forum for help with the Arduino, and when you do that, you will need to tell them how you have connected the L293D, or nobody will be able to help you.

-Paul

because I do the reading of “readline” so I get zero?

#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;
  }
}

Sorry, I do not understand your question. It sounds like you are saying that readline does not work for you, but it worked before, so if you are having more trouble, you need to tell us what you have changed, what you expected, and what happened.

-Paul

So …
before I was not use the “readline” but, QTR_read, and yes it worked … with the function readLine, I hoped to get a value of all sensors, Why not get?

another question, I already explained this question before, but got no concrete answer …

pololu.com/docs/0J19/3

# if (sensors[0] > 750 && sensors[1] > 750 && sensors[2] > 750)  
#   {  
#     // do something.  Maybe this means we're at the edge of a course or about to fall off a table,  
#     // in which case, we might want to stop moving, back up, and turn around.  
#     return;  
#   }

this code fragment is for what exactly?, what I understood (and I put in my code) is that the sensors the sensors that I put this piece of code that are “must be seeing black” because they are the I wish to see the line, and only when they are to see the black line engines are on the maximum speed, ie only when the sensors see the black line there is no error, you see?, I am right or wrong about my thinking?, if you’re wrong can correct me?

img339.imageshack.us/i/dsc09373r.jpg/

#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;
  }
}

I leave here a picture of my circuit, but and its programming code (does not work, engines or she moves), the integrated I am using to control the DC motors is the L293D, and I want to do is the code: when two sensors are using to see the black line (sensor 3 and 4) both engines turning at full speed, if that does not happen, one of the engines will slow (or very little, depending on the error) so that the robot can make the turn in a “perfect”.
if I can help I would be very grateful.

Hello,

As far as I can tell you did not ask that question before. Sorry if I missed it, but all I can find is something similar that you put in your own code. Anyway, like the comment in that section of code says, if the sensors are all seeing black, maybe the robot is at the edge of a table or has been picked up. In either case, it is not on the line any more, so some appropriate action should be taken. It has nothing to do with what you “wish” your robot were doing. You can definitely leave that out for an initial attempt at line following.

As I have said many times, you do not have any code in your program that would actually set any motor speeds. We cannot give you any more help with the Arduino code here.

-Paul

I’m defining the speed of the engine here:

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

I really wanted your help at programming level, it is not working,
gostaritenho and to use this library (it’s in use it that is my problem) because without the use I have already done a code (shown above).

me if you can not help it, the forum arduino doubt they do, because it has opened a post and not getting an answer, and on schedule with these sensors, the most appropriate forum for help I think this will be the same …

if I can help thank.

Hello,

You are asking a question about basic Arduino programming in a Pololu support forum. I am sorry that the Arduino people are not helping you, but you will not get any more help on this issue here. Maybe you can try this tutorial.

-Paul

H bridge is connected …
my problem is not that …

I once asked a question about the functions provided by Pololu that no answer also, maybe the problem is al …

the question was that I with the “QTR read” consio read the value of the sensors (1 to 1) but with “readline” no, so I get zero? Why?
Sugira uma tradução melhor

Hello,

Sorry for missing that question. The qtr.readLine() function should work exactly the same as the qtr.readCalibrated() function, except that it returns the line position.

To figure out what is causing the problem for you, please simplify your code as much as possible and post the version that works AND the version that does not work. I want to know whether changing readLine() to readCalibrated() (or readCalibrated() to read()) causes it to start working. Please describe exactly what you did to test it and what the result was in both cases.

-Paul

Good …
I did the following code:

#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 (error);
  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;
  }
}

based on this code:https://www.pololu.com/docs/0J19/3

I think it should work, however I find myself with several problems … such as:

I did “position error = -3500” What I think should happen to make the print of “error” as the sensor was covered, have a variable value, (-3500,-2500.-1500, -500,500,1500, 2500.3500), but only get the value 3500 … Why? can you help me?

Another problem I have is that when making the print of “position” get the values: 0 … 3000 … 7000, according to the sensor, but if you close the serial monitor already open and get back different values, as only zeros, or other values that do not have any Senst, I find it very strange, as it happens?

if I can clarify … thank
thanks for availability …

Hello,

You had something working before, so please simplify your code as much as possible and post the version that works AND the version that does not work. I want to know whether changing readLine() to readCalibrated() (or readCalibrated() to read()) causes it to start working. Please describe exactly what you did to test it and what the result was in both cases.

Please remove any lines that are not necessary for debugging the sensors, such as:

int motor_right = 10;

I will be happy to help you compare the two versions after you follow these instructions, but most likely you will find your problem along the way.

-Paul

then …

I tried using readCalibrated (), using the following code fragment:

void loop(){
  int readCalibrated ;
  unsigned int sensors [8];
  int position = readCalibrated;
  int error = position -3500;
  int lastError = 0;
  Serial.println (position);
  delay(500);

and values that continue to get only zeros, or replacing the readCalibrated () by reda () or readLine (), am I using the wrong function to read the sensors?

Hello,

You do not seem to understand what I am asking for. I am going to try to make it very clear:

  1. Simplify your working and non-working code as much as possible, removing any lines that are not important for the test. There should only be one or two lines different between the two versions.
  2. Try them both. Write down exactly what you did to test them and what happened.
  3. Post the entire code for both versions and the results of your test.

If you do not do all three steps, I can’t help you.

-Paul

Good once again …
I am having difficulties in making motors rotate as expected, the analog values that I should get the PWM outputs should range from 0 to 255, however if you do the print engine speed, using the following code:

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

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

obtenho os seguintes valores:

17850
17850
17850
12750
7650
2550
-2550
-7650
-17850
-17850

depending on the sensor that is black, what am I doing wrong? values should only vary from 0 to 255.