12 _type = QTRType::Analog;
21 uint8_t * oldSensorPins = _sensorPins;
22 _sensorPins = (uint8_t *)realloc(_sensorPins,
sizeof(uint8_t) * sensorCount);
23 if (_sensorPins ==
nullptr)
30 for (uint8_t i = 0; i < sensorCount; i++)
32 _sensorPins[i] = pins[i];
35 _sensorCount = sensorCount;
45 if (timeout > 32767) { timeout = 32767; }
47 if (_type == QTRType::RC) { _maxValue = timeout; }
52 if (samples > 64) { samples = 64; }
53 _samplesPerSensor = samples;
60 _oddEmitterPin = emitterPin;
61 pinMode(_oddEmitterPin, OUTPUT);
70 _oddEmitterPin = oddEmitterPin;
71 _evenEmitterPin = evenEmitterPin;
72 pinMode(_oddEmitterPin, OUTPUT);
73 pinMode(_evenEmitterPin, OUTPUT);
82 pinMode(_oddEmitterPin, INPUT);
88 pinMode(_evenEmitterPin, INPUT);
97 if (dimmingLevel > 31) { dimmingLevel = 31; }
98 _dimmingLevel = dimmingLevel;
104 bool pinChanged =
false;
110 if (emitters == QTREmitters::All ||
111 (_emitterPinCount == 2 && emitters == QTREmitters::Odd))
115 (digitalRead(_oddEmitterPin) == HIGH))
117 digitalWrite(_oddEmitterPin, LOW);
125 if (_emitterPinCount == 2 &&
126 (emitters == QTREmitters::All || emitters == QTREmitters::Even))
130 (digitalRead(_evenEmitterPin) == HIGH))
132 digitalWrite(_evenEmitterPin, LOW);
137 if (wait && pinChanged)
142 delayMicroseconds(1200);
146 delayMicroseconds(200);
153 bool pinChanged =
false;
154 uint16_t emittersOnStart;
160 if (emitters == QTREmitters::All ||
161 (_emitterPinCount == 2 && emitters == QTREmitters::Odd))
168 ( _dimmable || (digitalRead(_oddEmitterPin) == LOW)))
170 emittersOnStart = emittersOnWithPin(_oddEmitterPin);
178 if (_emitterPinCount == 2 &&
179 (emitters == QTREmitters::All || emitters == QTREmitters::Even))
186 (_dimmable || (digitalRead(_evenEmitterPin) == LOW)))
188 emittersOnStart = emittersOnWithPin(_evenEmitterPin);
193 if (wait && pinChanged)
200 while ((uint16_t)(micros() - emittersOnStart) < 300)
202 delayMicroseconds(10);
207 delayMicroseconds(200);
214 uint16_t QTRSensors::emittersOnWithPin(uint8_t pin)
216 if (_dimmable && (digitalRead(pin) == HIGH))
222 digitalWrite(pin, LOW);
223 delayMicroseconds(1200);
226 digitalWrite(pin, HIGH);
227 uint16_t emittersOnStart = micros();
229 if (_dimmable && (_dimmingLevel > 0))
233 for (uint8_t i = 0; i < _dimmingLevel; i++)
235 delayMicroseconds(1);
236 digitalWrite(pin, LOW);
237 delayMicroseconds(1);
238 digitalWrite(pin, HIGH);
244 return emittersOnStart;
253 case QTREmitters::Odd:
254 offEmitters = QTREmitters::Even;
257 case QTREmitters::Even:
258 offEmitters = QTREmitters::Odd;
261 case QTREmitters::All:
265 case QTREmitters::None:
275 uint16_t turnOffStart = micros();
286 while ((uint16_t)(micros() - turnOffStart) < 1200)
288 delayMicroseconds(10);
295 for (uint8_t i = 0; i < _sensorCount; i++)
328 void QTRSensors::calibrateOnOrOff(CalibrationData & calibration,
QTRReadMode mode)
335 if (!calibration.initialized)
337 uint16_t * oldMaximum = calibration.maximum;
338 calibration.maximum = (uint16_t *)realloc(calibration.maximum,
339 sizeof(uint16_t) * _sensorCount);
340 if (calibration.maximum ==
nullptr)
347 uint16_t * oldMinimum = calibration.minimum;
348 calibration.minimum = (uint16_t *)realloc(calibration.minimum,
349 sizeof(uint16_t) * _sensorCount);
350 if (calibration.minimum ==
nullptr)
359 for (uint8_t i = 0; i < _sensorCount; i++)
361 calibration.maximum[i] = 0;
362 calibration.minimum[i] = _maxValue;
365 calibration.initialized =
true;
368 for (uint8_t j = 0; j < 10; j++)
370 read(sensorValues, mode);
372 for (uint8_t i = 0; i < _sensorCount; i++)
375 if ((j == 0) || (sensorValues[i] > maxSensorValues[i]))
377 maxSensorValues[i] = sensorValues[i];
381 if ((j == 0) || (sensorValues[i] < minSensorValues[i]))
383 minSensorValues[i] = sensorValues[i];
389 for (uint8_t i = 0; i < _sensorCount; i++)
393 if (minSensorValues[i] > calibration.maximum[i])
395 calibration.maximum[i] = minSensorValues[i];
400 if (maxSensorValues[i] < calibration.minimum[i])
402 calibration.minimum[i] = maxSensorValues[i];
415 readPrivate(sensorValues);
421 readPrivate(sensorValues);
431 readPrivate(sensorValues, 0, 2);
437 readPrivate(sensorValues, 1, 2);
452 readPrivate(offValues);
454 for (uint8_t i = 0; i < _sensorCount; i++)
456 sensorValues[i] += _maxValue - offValues[i];
457 if (sensorValues[i] > _maxValue)
461 sensorValues[i] = _maxValue;
495 read(sensorValues, mode);
497 for (uint8_t i = 0; i < _sensorCount; i++)
499 uint16_t calmin, calmax;
538 uint16_t denominator = calmax - calmin;
541 if (denominator != 0)
543 value = (((int32_t)sensorValues[i]) - calmin) * 1000 / denominator;
546 if (value < 0) { value = 0; }
547 else if (value > 1000) { value = 1000; }
549 sensorValues[i] = value;
557 void QTRSensors::readPrivate(uint16_t * sensorValues, uint8_t start, uint8_t step)
559 if (_sensorPins ==
nullptr) {
return; }
564 for (uint8_t i = start; i < _sensorCount; i += step)
566 sensorValues[i] = _maxValue;
568 pinMode(_sensorPins[i], OUTPUT);
570 digitalWrite(_sensorPins[i], HIGH);
573 delayMicroseconds(10);
583 uint32_t startTime = micros();
586 for (uint8_t i = start; i < _sensorCount; i += step)
589 pinMode(_sensorPins[i], INPUT);
594 while (time < _maxValue)
600 time = micros() - startTime;
601 for (uint8_t i = start; i < _sensorCount; i += step)
603 if ((digitalRead(_sensorPins[i]) == LOW) && (time < sensorValues[i]))
606 sensorValues[i] = time;
615 case QTRType::Analog:
617 for (uint8_t i = start; i < _sensorCount; i += step)
622 for (uint8_t j = 0; j < _samplesPerSensor; j++)
624 for (uint8_t i = start; i < _sensorCount; i += step)
627 sensorValues[i] += analogRead(_sensorPins[i]);
632 for (uint8_t i = start; i < _sensorCount; i += step)
634 sensorValues[i] = (sensorValues[i] + (_samplesPerSensor >> 1)) /
644 uint16_t QTRSensors::readLinePrivate(uint16_t * sensorValues,
QTRReadMode mode,
656 for (uint8_t i = 0; i < _sensorCount; i++)
658 uint16_t value = sensorValues[i];
659 if (invertReadings) { value = 1000 - value; }
662 if (value > 200) { onLine =
true; }
667 avg += (uint32_t)value * (i * 1000);
675 if (_lastPosition < (_sensorCount - 1) * 1000 / 2)
682 return (_sensorCount - 1) * 1000;
686 _lastPosition = avg / sum;
687 return _lastPosition;
691 QTRSensors::~QTRSensors()
695 if (_sensorPins) { free(_sensorPins); }
const uint8_t QTRMaxSensors
The maximum number of sensors supported by an instance of this class.
QTREmitters
Emitters selected to turn on or off.
void calibrate(QTRReadMode mode=QTRReadMode::On)
Reads the sensors for calibration.
const uint8_t QTRNoEmitterPin
Represents an undefined emitter control pin.
void setSamplesPerSensor(uint8_t samples)
Sets the number of analog readings to average per analog sensor.
void setEmitterPins(uint8_t oddEmitterPin, uint8_t evenEmitterPin)
Sets separate odd and even emitter control pins for the sensors.
void setTypeRC()
Specifies that the sensors are RC.
void setTimeout(uint16_t timeout)
Sets the timeout for RC sensors.
void setEmitterPin(uint8_t emitterPin)
Sets the emitter control pin for the sensors.
void setSensorPins(const uint8_t *pins, uint8_t sensorCount)
Sets the sensor pins.
QTRReadMode
Emitter behavior when taking readings.
void readCalibrated(uint16_t *sensorValues, QTRReadMode mode=QTRReadMode::On)
Reads the sensors and provides calibrated values between 0 and 1000.
uint16_t * minimum
Lowest readings seen during calibration.
void resetCalibration()
Resets all calibration that has been done.
void read(uint16_t *sensorValues, QTRReadMode mode=QTRReadMode::On)
Reads the raw sensor values into an array.
CalibrationData calibrationOff
Data from calibrating with emitters off.
uint16_t * maximum
Highest readings seen during calibration.
void emittersOff(QTREmitters emitters=QTREmitters::All, bool wait=true)
Turns the IR LEDs off.
CalibrationData calibrationOn
Data from calibrating with emitters on.
void emittersSelect(QTREmitters emitters)
Turns on the selected emitters and turns off the other emitters with optimized timing.
void setDimmingLevel(uint8_t dimmingLevel)
Sets the dimming level.
void emittersOn(QTREmitters emitters=QTREmitters::All, bool wait=true)
Turns the IR LEDs on.
void setTypeAnalog()
Specifies that the sensor type is analog.
void releaseEmitterPins()
Releases emitter pin/pins that have been set.
bool initialized
Whether array pointers have been allocated and initialized.