Part of the OU_Davis_Old_Robot Library

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers QTR_8A.cpp Source File

QTR_8A.cpp

00001 //ported from arduino with some changes 
00002 //by Austin Saunders
00003 
00004 #include "mbed.h"
00005 #include "QTR_8A.h"
00006 #include "MCP3008.h"
00007 
00008 //6 sensors
00009 
00010 /*
00011 QTR_8A::QTR_8A(PinName L3, PinName L2, PinName L1, PinName R1, PinName R2, PinName R3, PinName E) : _L3(L3), _L2(L2), _L1(L1), _R1(R1), _R2(R2), _R3(R3), _E(E)
00012 {
00013     calibratedMinimum=0;
00014     calibratedMaximum=0;
00015 }
00016 */
00017 MCP3008 Ain(p11,p12,p13,p14);
00018 
00019 QTR_8A::QTR_8A(PinName E) :  _E(E)
00020 {
00021     calibratedMinimum=0;
00022     calibratedMaximum=0;
00023     emittersOff();
00024 }
00025 
00026 
00027 
00028 QTR_8A::~QTR_8A()
00029 {
00030 
00031 }
00032 
00033 
00034 void QTR_8A::emittersOn()
00035 {
00036     _E = 1;
00037     wait(0.0004);//wait 300us so that the analogin doesn't read faster than the speed of light!!
00038 }
00039 
00040 void QTR_8A::emittersOff()
00041 {
00042     _E = 0;
00043     wait(0.0004);//wait 300us so that the analogin doesn't read faster than the speed of light!!
00044 }
00045 
00046 void QTR_8A::read(unsigned int *sensor_values)
00047 {
00048     int numSamplesPerSensor = 4;
00049     //reset the values
00050     for(int i=0; i<8; i++) {
00051         sensor_values[i] = 0;
00052     }
00053     emittersOn();
00054     for (int j = 0; j < numSamplesPerSensor; j++) {
00055         sensor_values[0]+=Ain.read(0);
00056         sensor_values[1]+=Ain.read(1);
00057         sensor_values[2]+=Ain.read(2);
00058         sensor_values[3]+=Ain.read(3);
00059         sensor_values[4]+=Ain.read(4);
00060         sensor_values[5]+=Ain.read(5);
00061         sensor_values[6]+=Ain.read(6);
00062         sensor_values[7]+=Ain.read(7);
00063     }
00064     emittersOff();
00065     // get the rounded average of the readings for each sensor
00066     for (int i = 0; i < 8; i++) {
00067         sensor_values[i] = (sensor_values[i]+(numSamplesPerSensor>>1))/numSamplesPerSensor;
00068     }
00069 
00070 }
00071 
00072 void QTR_8A::calibrate()
00073 {
00074     calibrateon(&calibratedMinimum,&calibratedMaximum);
00075 }
00076 
00077 void QTR_8A::calibrateon(unsigned int**calibratedMinimum,unsigned int**calibratedMaximum){
00078 
00079     unsigned int sensor_values[8];
00080     unsigned int max_sensor_values[8];
00081     unsigned int min_sensor_values[8];
00082 
00083     // Allocate the arrays if necessary.
00084     if(*calibratedMaximum == 0) {
00085         *calibratedMaximum = (unsigned int*)malloc(sizeof(unsigned int)*8);
00086 
00087         // If the malloc failed, don't continue.
00088         if(*calibratedMaximum == 0) {
00089             return;
00090         }
00091         // Initialize the max and min calibrated values to values that
00092         // will cause the first reading to update them.
00093 
00094         for(int i=0; i<8; i++) {
00095             (*calibratedMaximum)[i] = 0;
00096         }
00097     }
00098     if(*calibratedMinimum == 0) {
00099         *calibratedMinimum = (unsigned int*)malloc(sizeof(unsigned int)*8);
00100 
00101         // If the malloc failed, don't continue.
00102         if(*calibratedMinimum == 0) {
00103             return;
00104         }
00105 
00106         for(int i=0; i<8; i++) {
00107             (*calibratedMinimum)[i] = 1023;
00108         }
00109     }
00110 
00111     for(int j=0; j<10; j++) {
00112         read(sensor_values);
00113         for(int i=0; i<8; i++) {
00114             // set the max we found THIS time
00115             if(j == 0 || max_sensor_values[i] < sensor_values[i])
00116                 max_sensor_values[i] = sensor_values[i];
00117 
00118             // set the min we found THIS time
00119             if(j == 0 || min_sensor_values[i] > sensor_values[i])
00120                 min_sensor_values[i] = sensor_values[i];
00121         }
00122     }
00123 
00124     // record the min and max calibration values
00125     for(int i=0; i<8; i++) {
00126         if(min_sensor_values[i] > (*calibratedMaximum)[i])
00127             (*calibratedMaximum)[i] = min_sensor_values[i];
00128         if(max_sensor_values[i] < (*calibratedMinimum)[i])
00129             (*calibratedMinimum)[i] = max_sensor_values[i];
00130     }
00131 }
00132 
00133 
00134 
00135 void QTR_8A::resetCalibration()
00136 {
00137     for(int i=0; i<8; i++) {
00138         calibratedMinimum[i] = 1023;
00139         calibratedMaximum[i] = 0;
00140     }
00141 }
00142 
00143 void QTR_8A::readCalibrated(unsigned int *sensor_values)
00144 {
00145     if(!calibratedMinimum || !calibratedMaximum) {
00146         return;
00147     }
00148     read(sensor_values);
00149 
00150     for(int i=0; i<8; i++) {
00151         unsigned int calmin,calmax;
00152         unsigned int denominator;
00153         calmax = calibratedMaximum[i];
00154         calmin = calibratedMinimum[i];
00155         denominator = calmax - calmin;
00156 
00157         signed int x = 0;
00158         if(denominator != 0) {
00159             x = (((signed long)sensor_values[i]) - calmin)* 1000 / denominator;
00160         }
00161         if(x < 0) {
00162             x = 0;
00163         } else if(x > 1000) {
00164             x = 1000;
00165         }
00166         sensor_values[i] = x;
00167 
00168     }
00169 }
00170 
00171 int QTR_8A::readLine(unsigned int *sensor_values)
00172 {
00173     unsigned int on_line = 0;
00174     unsigned long avg; // this is for the weighted total, which is long
00175     // before division
00176     unsigned int sum; // this is for the denominator which is <= 64000
00177     static int last_value=0; // assume initially that the line is left.
00178 
00179     readCalibrated(sensor_values);
00180 
00181     avg = 0;
00182     sum = 0;
00183 
00184     for(int i=0; i<8; i++) {
00185         int value = sensor_values[i];
00186 
00187 
00188         // keep track of whether we see the line at all
00189         if(value > 350) {
00190             on_line = 1;
00191         }
00192 
00193         // only average in values that are above a noise threshold
00194         if(value > 20) {
00195             avg += (long)(value) * (i * 1000);
00196             sum += value;
00197         }
00198     }
00199 
00200     if(!on_line) {
00201         // If it last read to the left of center, return 0.
00202         if(last_value < 3500) {
00203             return 0;
00204         }
00205 
00206         // If it last read to the right of center, return the max.
00207         else {
00208             return 7000;
00209         }
00210 
00211     }
00212 
00213     last_value = avg/sum;
00214 
00215     return last_value;
00216 }
00217 
00218 
00219 
00220