Hi!
I’m completely new to electronics, and I wanted to build a line follower from scratch. I decided to use a MCP23017 breakout board with my Arduino Nano and wire a QTR-MD-16RC to the MCP23017. To get it to run with the Adafruit MCP23017 library, I ended up modifying the qtr sensor library code a bit (just the readPrivate function) but it keeps giving me 0 readings across the board with both the min and max for all sensors being 2500 when calibration finishes. However, when just one sensor is hooked up to the MCP23017, it does work, but kind of weirdly.
Here are some things I’ve tried:
- Increasing the number of calibrations up to 1600 from the default didn’t seem to do much - I couldn’t get even 2 sensors to work on the expansion board.
- Hooking up the sensors to the remaining pins I have on my nano seems to work completely fine - I get normal readings!
It’s very likely my modifications of the library broke something. I’ve also noticed that when using my modified version with the calls to the Adafruit MCP23017 library, the sensor calibrates a lot slower. I’m also modifying SensorCount and the array passed into setSensorPins() correctly, so I don’t think that’s related to the problem.
void QTRSensors::readPrivate(uint16_t * sensorValues, uint8_t start, uint8_t step)
{
if (_sensorPins == nullptr) { return; }
switch (_type)
{
case QTRType::RC:
for (uint8_t i = start; i < _sensorCount; i += step)
{
sensorValues[i] = _maxValue;
// make sensor line an output (drives low briefly, but doesn't matter)
mcp.pinMode(_sensorPins[i], OUTPUT);
// pinMode(_sensorPins[i], OUTPUT);
// drive sensor line high
mcp.digitalWrite(_sensorPins[i], HIGH);
// digitalWrite(_sensorPins[i], HIGH);
}
delayMicroseconds(10); // charge lines for 10 us
{
// disable interrupts so we can switch all the pins as close to the same
// time as possible
// noInterrupts();
// record start time before the first sensor is switched to input
// (similarly, time is checked before the first sensor is read in the
// loop below)
uint32_t startTime = micros();
uint16_t time = 0;
for (uint8_t i = start; i < _sensorCount; i += step)
{
// make sensor line an input (should also ensure pull-up is disabled)
mcp.pinMode(_sensorPins[i], INPUT);
// pinMode(_sensorPins[i], INPUT);
}
// interrupts();
while (time < _maxValue)
{
// disable interrupts so we can read all the pins as close to the same
// time as possible
// noInterrupts();
time = micros() - startTime;
for (uint8_t i = start; i < _sensorCount; i += step)
{
if ((mcp.digitalRead(_sensorPins[i]) == LOW) && (time < sensorValues[i]))
// if ((digitalRead(_sensorPins[i]) == LOW) && (time < sensorValues[i]))
{
// record the first time the line reads low
sensorValues[i] = time;
}
}
// interrupts(); // re-enable
}
}
return;
case QTRType::Analog:
// reset the values
for (uint8_t i = start; i < _sensorCount; i += step)
{
sensorValues[i] = 0;
}
for (uint8_t j = 0; j < _samplesPerSensor; j++)
{
for (uint8_t i = start; i < _sensorCount; i += step)
{
// add the conversion result
sensorValues[i] += analogRead(_sensorPins[i]);
}
}
// get the rounded average of the readings for each sensor
for (uint8_t i = start; i < _sensorCount; i += step)
{
sensorValues[i] = (sensorValues[i] + (_samplesPerSensor >> 1)) /
_samplesPerSensor;
}
return;
default: // QTRType::Undefined or invalid - do nothing
return;
}
}
^ my modifications of readPrivate(), just replacing every digitalRead or pinMode with the Adafruit library equivalent
^ seemingly completely normal readings when the sensor is wired to pins on the nano - D11 and D12
^ the readings I get when just one of the sensors is connected to pin PA0 of the MCP23017, where I’m just passing my finger directly underneath the sensor and it seems to be reacting
^ the readings when I get two of the sensors connected to the MCP23017 (pins PA0 & PA1), and basically any number of sensors above that
Again, I’m basically a complete beginner so I’m sorry if this post comes off as silly. Thank you!
edit: looked it up and it seems the max current the MCP23017 can handle is 150mA while the QTR-MD-16RC gets up to 250mA…is this why it’s not working?