Beginners: please read this post and this post before posting to the forum.
0 Members and 1 Guest are viewing this topic.
#include <PololuQTRSensors.h> // create an object for your type of sensor (RC or Analog) // in this example we have three sensors on analog inputs 0 - 2, a.k.a. digital pins 14 - 16 PololuQTRSensorsRC qtr((unsigned char[]) {14, 15, 16}, 3); // PololuQTRSensorsA qtr((unsigned char[]) {0, 1, 2}, 3); void setup() { // optional: wait for some input from the user, such as a button press // then start calibration phase and move the sensors over both // reflectance extremes they will encounter in your application: int i; for (i = 0; i < 250; i++) // make the calibration take about 5 seconds { qtr.calibrate(); delay(20); } // optional: signal that the calibration phase is now over and wait for further // input from the user, such as a button press Serial.begin(9600); } void loop() { unsigned int sensors[3]; // get calibrated sensor values returned in the sensors array, along with the line position // position will range from 0 to 2000, with 1000 corresponding to the line over the middle sensor int position = qtr.readLine(sensors); // output to Serial monitorSerial.print(sensors[0]); Serial.print(" ");Serial.print(sensors[1]); Serial.print(" ");Serial.print(sensors[2]); Serial.print(" ");Serial.println(); // if all three sensors see very low reflectance, take some appropriate action for this situation 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; } // compute our "error" from the line position. We will make it so that the error is zero when // the middle sensor is over the line, because this is our goal. Error will range from // -1000 to +1000. If we have sensor 0 on the left and sensor 2 on the right, a reading of -1000 // means that we see the line on the left and a reading of +1000 means we see the line on // the right. int error = position - 1000; int leftMotorSpeed = 100; int rightMotorSpeed = 100; if (error < -500) // the line is on the left leftMotorSpeed = 0; // turn left if (error > 500) // the line is on the right rightMotorSpeed = 0; // turn right // set motor speeds using the two motor speed variables above }
// Reads the sensor values into an array. There *MUST* be space// for as many values as there were sensors specified in the constructor.// Example usage:// unsigned int sensor_values[8];// sensors.read(sensor_values);// ...// The values returned are in microseconds and range from 0 to// timeout_us (as specified in the constructor).void PololuQTRSensorsRC::readPrivate(unsigned int *sensor_values){ unsigned char i; unsigned char start_time; unsigned char delta_time; unsigned int time = 0; unsigned char last_b = _portBMask; unsigned char last_c = _portCMask; unsigned char last_d = _portDMask; // reset the values for(i = 0; i < _numSensors; i++) sensor_values[i] = 0; // set all sensor pins to outputs DDRB |= _portBMask; DDRC |= _portCMask; DDRD |= _portDMask; // drive high for 10 us PORTB |= _portBMask; PORTC |= _portCMask; PORTD |= _portDMask; delayMicroseconds(10); // set all ports to inputs DDRB &= ~_portBMask; DDRC &= ~_portCMask; DDRD &= ~_portDMask; // turn off pull ups PORTB &= ~_portBMask; PORTC &= ~_portCMask; PORTD &= ~_portDMask; unsigned char prevTCCR2A = TCCR2A; unsigned char prevTCCR2B = TCCR2B; TCCR2A |= 0x03; TCCR2B = 0x02; // run timer2 in normal mode at 2.5 MHz // this is compatible with OrangutanMotors start_time = TCNT2; while (time < _maxValue) { // Keep track of the total time. // This explicitly casts the difference to unsigned char, so // we don't add negative values. delta_time = TCNT2 - start_time; time += delta_time; start_time += delta_time; // continue immediately if there is no change if (PINB == last_b && PINC == last_c && PIND == last_d) continue; // save the last observed values last_b = PINB; last_c = PINC; last_d = PIND; // figure out which pins changed for (i = 0; i < _numSensors; i++) { if (sensor_values[i] == 0 && !(*_register[i] & _bitmask[i])) sensor_values[i] = time; } } TCCR2A = prevTCCR2A; TCCR2B = prevTCCR2B; for(i = 0; i < _numSensors; i++) if (!sensor_values[i]) sensor_values[i] = _maxValue;}
// Calibrated minumum and maximum values. These start at 1000 and // 0, respectively, so that the very first sensor reading will // update both of them. // // The pointers are unallocated until calibrate() is called, and // then allocated to exactly the size required. Depending on the // readMode argument to calibrate, only the On or Off values may // be allocated, as required. // // These variables are made public so that you can use them for // your own calculations and do things like saving the values to // EEPROM, performing sanity checking, etc. unsigned int *calibratedMinimumOn; unsigned int *calibratedMaximumOn; unsigned int *calibratedMinimumOff; unsigned int *calibratedMaximumOff;
// output to Serial monitorfor(i=0;i<3;i++) //number of Sensors {Serial.print(calibratedMaximumOn[i]); Serial.print(" ");Serial.print(calibratedMinimumOn[i]); Serial.print(" ");Serial.print(calibratedMaximumOff[i]); Serial.print(" ");Serial.print(calibratedMinimumOff[i]); Serial.print(" ");}