Hi,
I am trying to make a linefollowing robot and I am using the Pololu QTR-8A, the pololu micro metal gear (30:1) motors, and the pololu DRV8835 arduino motor shield.
I am using six of the eight sensors from the QTR (sensor 2,3,4,5,6,7) and are connected to an arduino UNO to analog pins
0-5.
This is my code:
#include <DRV8835MotorShield.h>
#include <QTRSensors.h>
#define Kp 0.05 // experiment to determine this, start by something small that just makes your bot follow the line at a slow speed
#define Kd 2 // experiment to determine this, slowly increase the speeds and adjust this value. ( Note: Kp < Kd)
#define rightMaxSpeed 200 // max speed of the robot
#define leftMaxSpeed 200 // max speed of the robot
#define rightBaseSpeed 150 // this is the speed at which the motors should spin when the robot is perfectly on the line
#define leftBaseSpeed 150 // this is the speed at which the motors should spin when the robot is perfectly on the line
#define NUM_SENSORS 6 // number of sensors used
#define TIMEOUT 2500 // waits for 2500 us for sensor outputs to go low
#define EMITTER_PIN 2 // emitter is controlled by digital pin 2
DRV8835MotorShield motors; //don't forget this line
QTRSensorsAnalog qtra((unsigned char[]) { 0, 1, 2, 3, 4, 5} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN); // sensor connected through analog pins A0 - A5 i.e. digital pins 14-19
unsigned int sensorValues[NUM_SENSORS];
void setup()
{
motors.flipM1(true);
motors.flipM2(true);
/* comment this part out for automatic calibration
if ( i < 25 || i >= 75 ) // turn to the left and right to expose the sensors to the brightest and darkest readings that may be encountered
turn_right();
else
turn_left(); */
qtra.calibrate(QTR_EMITTERS_ON);
delay(20);
delay(10000); // wait for 10s to position the bot before entering the main loop
/* comment out for serial printing
Serial.begin(9600);
for (int i = 0; i < NUM_SENSORS; i++)
{
Serial.print(qtrrc.calibratedMinimumOn[i]);
Serial.print(' ');
}
Serial.println();
for (int i = 0; i < NUM_SENSORS; i++)
{
Serial.print(qtrrc.calibratedMaximumOn[i]);
Serial.print(' ');
}
Serial.println();
Serial.println();
*/
}
int lastError = 0;
void loop()
{
unsigned int sensors[6];
int position = qtra.readLine(sensors); // get calibrated readings along with the line position, refer to the QTR Sensors Arduino Library for more details on line position.
int error = position - 2500;
int motorSpeed = Kp * error + Kd * (error - lastError);
lastError = error;
int rightMotorSpeed = rightBaseSpeed + motorSpeed;
int leftMotorSpeed = leftBaseSpeed - motorSpeed;
if (rightMotorSpeed > rightMaxSpeed ) rightMotorSpeed = rightMaxSpeed; // prevent the motor from going beyond max speed
if (leftMotorSpeed > leftMaxSpeed ) leftMotorSpeed = leftMaxSpeed; // prevent the motor from going beyond max speed
if (rightMotorSpeed < 0) rightMotorSpeed = 0; // keep the motor speed positive
if (leftMotorSpeed < 0) leftMotorSpeed = 0; // keep the motor speed positive
{
// move forward with appropriate speeds
motors.setM1Speed(rightMotorSpeed); //only works if "DRV8835MotorShield motors;" is defined in the beginning
motors.setM2Speed(leftMotorSpeed);
}
}
All the robot does is driving fast in circles.
I do get readings from the QTR sensor when I read it from the serial monitors. It also gets 5V from the arduino, so as far as hardware is concerned, I don’t think that is the problem.
Could someone look at my code and tell me if it is any good?