Uniform min values after calibration

I am using an Arduino Nano Every piggyback mounted on a Pololu QTR-8RC sensor. On the Arduino I installed my code based on the Pololu example and modified it
to communicate with my rpi and to store and retrieve calibration results in/from EEPOM.
After resolving my previous issue (QTR-8RC reads too big values after calibration), the whole setup worked just fine for a few days.
I experimented with changing the baud rate of the RPi-arduino communication. This didn’t yield any gain in the speed of the whole program, so I reset it back to the original 115200 baud.
After that, the left qtr started to report a uniform position of 3500 as all the IR sensors reported 1000 uniformly, no matter where the black line was.
I decided to uninstall this particular component. I installed a new qtr paired with a new arduino nano every.
Everything else remained the same. I am using the same arduino SW and the same rpi python code. The new device (arduino-qtr combination) seems to work, but the readings are weird.
The driving surface is made of OSB boards (which aren’t white by far), and the black line is made of black isolating tape 19 mm wide.
After the calibration, all the min values are zero and all the max values are 2500 uniformly.
The coresponding positional readings after the calibration are not accurate, because the actual values read by the IR sensors are all above 100.
These are the actual values when all the IR sensors are positioned above the OSB board and no black line is present:
219__169__169__169__169__169__193__273, the corresponding positional reading (readLine) of the device is 3662.
These are the actual values when only the first IR sensor is positioned partially over the black line and all other IR sensors are positioned above the OSB board:
628__169__169__169__145__145__169__248, the corresponding positional reading (readLine) of the device is 2751.

Please advise.

Hello.

I am not sure if I understand the problem. It sounds like the calibration is working:

But then you start talking about the “actual values.” What do you mean when you refer to the “actual values;” are those the raw readings from the reflectance sensors? (If you are using our QTR reflectance sensor library, you would get the raw measurements using the read() function instead of the readCalibrated() function.)

Could you post the simplest, complete program that demonstrates the problem? A video showing the problem might be helpful too.

- Patrick

Hi Patrick,
thank you for your answer. I am using the old 3.9 qtr arduino library and for the “actual” readings I am using the readLine function. I attach the code. My function that prints the readings of all 8 sensors is “sendDataa()”.
The code:

#include <QTRSensors.h>
#include <EEPROM.h>

#define NUM_SENSORS   8     // number of sensors used
#define TIMEOUT       2500  // waits for 2500 microseconds for sensor outputs to go low
#define EMITTER_PIN   10     // emitter is controlled by digital pin 



QTRSensorsRC qtrrc((unsigned char[]) {14, 15, 16, 17, 18, 19, 20, 21}, NUM_SENSORS, TIMEOUT, EMITTER_PIN); 
unsigned int sensorValues[NUM_SENSORS];


//EEPROM Addressing for calibration storage
#define addrCalibratedMinimumOn 0
#define addrCalibratedMaximumOn 128



const int ledPin=13;
String nom = "Arduino";
String msg;
int termination = 0;

void setup() {
  Serial.begin(115200); //original 9600, na uno 115200
  pinMode(ledPin,OUTPUT);
}

void loop() {
  readSerialPort();
  unsigned int position = qtrrc.readLine(sensorValues);

  if (msg == "data") {
    sendData();
  }else if(msg == "dataa") {
    termination=0;
    sendDataa();    
  }else if(msg=="cal"){
    resetValues();
    calibrateQTR();  
  }else if(msg=="read"){
    readQTR();
  }else if(msg=="store"){
    storeQTR();
  }else if(msg=="recall"){
    resetValues();
    recallQTR(); 
    Serial.println();      
  }
  else if(msg=="rdata"){
    resetValues();
    recallQTR(); 
    sendData();      
  }  
  delay(250); // originalno 500, QTRExample ima 250
}

void readSerialPort() {
  msg = "";
  if (Serial.available()) {
    delay(10);
    while (Serial.available() > 0) {
      msg += (char)Serial.read();
    }
    Serial.flush();
  }
}

void sendData() {
  //write data 
  unsigned int position = qtrrc.readLine(sensorValues);
  //for (unsigned char i = 0; i < NUM_SENSORS; i++)
  //{
   // Serial.print(sensorValues[i]);
    //Serial.print("__");
  //}
  Serial.println(position); // comment this line out if you are using raw values
  //Serial.println();
  delay(250);
}

void sendDataa() 
{
  //write data 
  unsigned int position = qtrrc.readLine(sensorValues);
  //test if senzor over black termination (cross) line
  for (unsigned char i = 0; i < NUM_SENSORS; i++)
  {
    if (sensorValues[i] > 800) {
      termination += 1;
      } 
   }     
  //print values
  for (unsigned char i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensorValues[i]);
    Serial.print("__");
  }
  if (termination == 8) {
    position = 8000;
  }
  Serial.print(termination); 
  Serial.print("_:");
  Serial.println(position);
  delay(250);
}

void calibrateQTR()
{
  
  delay(500);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);    // turn on Arduino's LED to indicate we are in calibration mode
  
  for (int i = 0; i < 400; i++)  // make the calibration take about 10 seconds
  {
    qtrrc.calibrate(QTR_EMITTERS_ON);       // reads all sensors 10 times at 2500 us per read (i.e. ~25 ms per call)
  }
  digitalWrite(13, LOW);     // turn off Arduino's LED to indicate we are through with calibration
  Serial.println();
}

void readQTR() //Reading Calibration Data...
{

   for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtrrc.calibratedMinimumOn[i]);
    Serial.print("_");
  }
  
  // print the calibration maximum values measured when emitters were on
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(qtrrc.calibratedMaximumOn[i]);
    Serial.print("_");
  }
  Serial.println();
}

void storeQTR() //Storing Calibration Data into EEPROM...
{
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    EEPROM.put(addrCalibratedMinimumOn+(i*sizeof(qtrrc.calibratedMinimumOn[i])), qtrrc.calibratedMinimumOn[i]);
  }

  for (int i = 0; i < NUM_SENSORS; i++)
  {
    EEPROM.put(addrCalibratedMaximumOn+(i*sizeof(qtrrc.calibratedMaximumOn[i])), qtrrc.calibratedMaximumOn[i]);
  }
  
  Serial.println();

}

void recallQTR() //Recalling Calibration Data from EEPROM...
{
  
  qtrrc.calibrate(QTR_EMITTERS_ON); 
  //EEPROM.readBlock<unsigned int>(addrCalibratedMinimumOn, qtrrc.calibratedMinimumOn, 8);
  //EEPROM.readBlock<unsigned int>(addrCalibratedMaximumOn, qtrrc.calibratedMaximumOn, 8);
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    EEPROM.get(addrCalibratedMinimumOn+(i*2), qtrrc.calibratedMinimumOn[i]);
  }

  for (int i = 0; i < NUM_SENSORS; i++)
  {
    EEPROM.get(addrCalibratedMaximumOn+(i*2), qtrrc.calibratedMaximumOn[i]);
  }  
  //Serial.println();

}


void resetValues() //Reset values
{
  qtrrc.calibrate(QTR_EMITTERS_ON);
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    qtrrc.calibratedMinimumOn[i] = 0;
  }

  for (int i = 0; i < NUM_SENSORS; i++)
  {
    qtrrc.calibratedMaximumOn[i] = 0;
  }  
}

I decided to migrate the whole code to the newest version (4.0) of the qtr arduino library. After that everything works just fine.

I am glad to hear you found a solution. Thanks for letting us know.

- Patrick