Part of the OU_Davis_Old_Robot Library
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Sun Jul 17 2022 02:26:15 by
1.7.2