Accessing calibrated PololuQTRSensorsRC values

Hello all,

I was wandering if you could help me with a problem. I made a micro-robot with baby-O B-328 robot controller on-board that among other things, it can track and follow a line.

I am using 2 QTR RC Sensors and so far I made it to flawlessly follow a black line with a PD control algorithm.

Now my problem is that I am looking for a way to avoid calibrating the sensors every time I switch the robot on. I know that in the Pololu library I can access the calibrated values as follows:

unsigned int *calibratedMaximumOn = qtr_calibrated_maximum_on(); unsigned int *calibratedMinimumOn = qtr_calibrated_minimum_on();

However, how can I store this values to controller’s EEPROM and how can I use this values of calibrated max/min, without recalibrating my robot when I switch it on again?

Any help would be greatly appreciated.

Best,

Akis

The AVR Libc includes some functions that make it easy to use EEPROM: just add " #include <avr/eeprom.h> " on the top of your code. You can use the eeprom_write_word(address, integer) to write values and eeprom_read_word(address) to read values. More information on using EEPROM could be found here. Below is an example of using EEPROM:

#include <avr/eeprom.h>
#define MAX_ADDR 0

void testEEPROM()
{
	unsigned int *calibratedMax = qtr_calibrated_maximum_on();
	if (calibratedMax != NULL)
	{
		eeprom_write_word(MAX_ADDR, calibratedMax[0]);  // store calibrated maximum in EEPROM
		int calibratedMaxFromEeprom = eeprom_read_word(MAX_ADDR);  // read it back from EEPROM
	}
}

- Jeremy

Thank you Jeremy that was helpful!!

Does anybody you have any idea of how to use the stored values instead of re-calibrating the sensors?

Thank you again :slight_smile:

Akis

Hello.

If you post the calibration portion of your code, I can show you how to modify it to do what you want.

- Ben

Hello Ben,

Sorry for my late response. My calibration portion of the code is the straight forward code you present in your examples:

[code]void initialize(){

// Auto-calibration: turn right and left while calibrating the
// sensors.
for(counter=0;counter<80;counter++)
{
	if(counter < 20 || counter >= 60)
		set_motors(50,-50);	
	else
		set_motors(-50,50);
		
	
	// This function records a set of sensor readings and keeps
	// track of the minimum and maximum values encountered.  The
	// IR_EMITTERS_ON argument means that the IR LEDs will be
	// turned on during the reading, which is usually what you
	// want.
	qtr_calibrate(QTR_EMITTERS_ON);

	// Since our counter runs to 80, the total delay will be
	// 80*20 = 1600 ms.
	delay_ms(20);
}
set_motors(0,0);
// optional: signal that the calibration phase is now over and wait 	

// for further input from the user, such as a button press
delay_ms(1000);
}
[/code]

Now, what I need to do is to store the calibrated max/min values in the EEPROM as Jeremy instructed me and the reuse these values when I switch my robot back again, without running the calibration procedure again.

Any help would be greatly appreciate it.

Akis

I think the following (untested) functions should work for you:

[code]void saveCalibrationToEEPROM()
{
unsigned int *calibratedMax = qtr_calibrated_maximum_on();
if (calibratedMax != 0)
{
eeprom_write_word(0, calibratedMax[0]);
eeprom_write_word(2, calibratedMax[1]);
}
unsigned int *calibratedMin = qtr_calibrated_minimum_on();
if (calibratedMin != 0)
{
eeprom_write_word(4, calibratedMin[0]);
eeprom_write_word(6, calibratedMin[1]);
}
}

void loadCalibrationFromEEPROM()
{
qtr_calibrate(QTR_EMITTERS_ON); // calling this just to allocate calibration arrays
unsigned int *calibratedMax = qtr_calibrated_maximum_on();
if (calibratedMax != NULL)
{
calibratedMax[0] = eeprom_read_word(0);
calibratedMax[1] = eeprom_read_word(2);
}
unsigned int *calibratedMin = qtr_calibrated_minimum_on();
if (calibratedMin != NULL)
{
calibratedMin[0] = eeprom_read_word(4);
calibratedMin[1] = eeprom_read_word(6);
}
}[/code]

To use them, you should implement something on startup that lets you decide whether to have the robot calibrate itself or whether to instead load calibration values from EEPROM. For example, in pseudocode:

if button A pressed
  calibrate
  call saveCalibrationToEEPROM()
else if button B is pressed
  call loadCalibrationFromEEPROM()

Does that make sense? I suggest you try testing my code before relying on it too heavily. One way to do so would be to use a USB-to-serial adapter to let you print out the calibration values that you are saving to EEPROM, and then reset and print out the ones you are loading back from EEPROM to make sure they match. If you have trouble getting it to work or there is something you don’t understand, please let me know.

- Ben

Thanks a lot Ben!!!

I will test it and I will let you know :slight_smile:

Best,

Akis