I am currently in the process of developing code for a line following robot using an Arduino Uno R3 board and an Ardumoto to control the happenings of the bot. Neither myself nor my teammates have any prior experience with any type of coding or programming. With this being said… I have some coding questions…
I received code to work the Pololu QRT-8RC Sensor as well as a few libraries to allow for its’ success. Unfortunately, it doesn’t want to compile. I am going to give out all of the code and then the errors and hope that you can see something we’ve done wrong.
Here is the Main code:
#include <PololuQTRSensors.h>
#include <AFMotor.h>
AF_DCMotor motor1(1, MOTOR12_8KHZ ); // PIN 11 - create motor #1 pwm
AF_DCMotor motor2(2, MOTOR12_8KHZ ); // PIN 3 - create motor #2 pwm
// Change the values below to suit your robot's motors, weight, wheel type, etc.
#define KP .2
#define KD 5
#define M1_DEFAULT_SPEED 50
#define M2_DEFAULT_SPEED 50
#define M1_MAX_SPEED 70
#define M2_MAX_SPEED 70
#define MIDDLE_SENSOR 3
#define NUM_SENSORS 5 // 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
#define DEBUG 0 // set to 1 if serial debug output needed
PololuQTRSensorsRC qtrrc((unsigned char[]) { 18,17,16,15,14} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];
void setup()
{
delay(1000);
manual_calibration();
set_motors(0,0);
}
int lastError = 0;
int last_proportional = 0;
int integral = 0;
void loop()
{
unsigned int sensors[5];
int position = qtrrc.readLine(sensors);
int error = position - 2000;
int motorSpeed = KP * error + KD * (error - lastError);
lastError = error;
int leftMotorSpeed = M1_DEFAULT_SPEED + motorSpeed;
int rightMotorSpeed = M2_DEFAULT_SPEED - motorSpeed;
// set motor speeds using the two motor speed variables above
set_motors(leftMotorSpeed, rightMotorSpeed);
}
void set_motors(int motor1speed, int motor2speed)
{
if (motor1speed > M1_MAX_SPEED ) motor1speed = M1_MAX_SPEED; // limit top speed
if (motor2speed > M2_MAX_SPEED ) motor2speed = M2_MAX_SPEED; // limit top speed
if (motor1speed < 0) motor1speed = 0; // keep motor above 0
if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0
motor1.setSpeed(motor1speed); // set motor speed
motor2.setSpeed(motor2speed); // set motor speed
motor1.run(FORWARD);
motor2.run(FORWARD);
}
void manual_calibration() {
int i;
for (i = 0; i < 250; i++) // the calibration will take a few seconds
{
qtrrc.calibrate(QTR_EMITTERS_ON);
delay(20);
}
if (DEBUG) { // if true, generate sensor dats via serial output
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();
}
}
Here is the ArduMoto.h Library:
#ifndef ArduMotor_h
#define ArduMotor_h
#include "defines.h"
class ArduMoto
{
public:
ArduMoto(); // Constructor
~ArduMoto(); // Destructor
void begin();
void beginMotoA(int directionPin, int pwmPin);
void beginMotoB(int directionPin, int pwmPin);
void setSpeed(char moto, int speed); // Set the speed of a selected motor, range: -100 to +100
void slowChange(char moto, int speed); // Fade the speed of a motor slowly to a specific value: range -100 to 100
void stop(char moto);
void brake(char moto); // Brake the motor
private:
int _motoSpeedA;
int _motoSpeedB;
};
#endif
Here is the PololuQTRSensors.h Library:
#ifndef PololuQTRSensors_h
#define PololuQTRSensors_h
#define QTR_EMITTERS_OFF 0
#define QTR_EMITTERS_ON 1
#define QTR_EMITTERS_ON_AND_OFF 2
class PololuQTRSensors
{
public:
void read(unsigned int *sensor_values, unsigned char readMode = QTR_EMITTERS_ON);
void emittersOff();
void emittersOn();
void calibrate(unsigned char readMode = QTR_EMITTERS_ON);
void readCalibrated(unsigned int *sensor_values, unsigned char readMode = QTR_EMITTERS_ON);
int readLine(unsigned int *sensor_values, unsigned char readMode = QTR_EMITTERS_ON, unsigned char white_line = 0);
unsigned int *calibratedMinimumOn;
unsigned int *calibratedMaximumOn;
unsigned int *calibratedMinimumOff;
unsigned int *calibratedMaximumOff;
~PololuQTRSensors();
protected:
PololuQTRSensors()
{
};
void init(unsigned char numSensors, unsigned char emitterPin,
unsigned char type);
unsigned char _numSensors;
unsigned char _emitterBitmask;
// pointer to emitter PORT register
volatile unsigned char* _emitterPORT; // needs to be volatile
// pointer to emitter DDR register
volatile unsigned char* _emitterDDR; // needs to be volatile
unsigned int _maxValue; // the maximum value returned by this function
private:
unsigned char _type; // the type of the derived class (QTR_RC
// or QTR_A)
// Handles the actual calibration. calibratedMinimum and
// calibratedMaximum are pointers to the requested calibration
// arrays, which will be allocated if necessary.
void calibrateOnOrOff(unsigned int **calibratedMinimum,
unsigned int **calibratedMaximum,
unsigned char readMode);
};
// Object to be used for QTR-1RC and QTR-8RC sensors
class PololuQTRSensorsRC : public PololuQTRSensors
{
// allows the base PololuQTRSensors class to access this class'
// readPrivate()
friend class PololuQTRSensors;
public:
// if this constructor is used, the user must call init() before using
// the methods in this class
PololuQTRSensorsRC() { }
// this constructor just calls init()
PololuQTRSensorsRC(unsigned char* pins, unsigned char numSensors,
unsigned int timeout = 4000, unsigned char emitterPin = 255);
void init(unsigned char* pins, unsigned char numSensors,
unsigned int timeout = 4000, unsigned char emitterPin = 255);
private:
void readPrivate(unsigned int *sensor_values);
private:
unsigned char _bitmask[8];
// pointer to PIN registers
volatile unsigned char* _register[8]; // needs to be volatile
unsigned char _portBMask;
unsigned char _portCMask;
unsigned char _portDMask;
};
// Object to be used for QTR-1A and QTR-8A sensors
class PololuQTRSensorsAnalog : public PololuQTRSensors
{
// allows the base PololuQTRSensors class to access this class'
// readPrivate()
friend class PololuQTRSensors;
public:
// if this constructor is used, the user must call init() before using
// the methods in this class
PololuQTRSensorsAnalog() { }
// this constructor just calls init()
PololuQTRSensorsAnalog(unsigned char* analogPins,
unsigned char numSensors, unsigned char numSamplesPerSensor = 4,
unsigned char emitterPin = 255);
void init(unsigned char* analogPins, unsigned char numSensors,
unsigned char numSamplesPerSensor = 4, unsigned char emitterPin = 255);
private:
void readPrivate(unsigned int *sensor_values);
private:
unsigned char _analogPins[8];
unsigned char _numSamplesPerSensor;
unsigned char _portCMask;
};
#endif
Thank you so very much.