3Pi - Additional QTR-1RC Sensors Help

Hi there,

Im new to robotics and I thought the 3Pi would be a good development platform to start.

My current project is to try and make the 3Pi drive around on a table and not fall off. I thought that the in-built IR sensors would do this for me and I have the robot driving around and coming to a stop when it senses the edge.
Unfortunately the sensors aren’t far out enough by the wheels so if its going up to an edge at an angle it won’t see the edge and just fall off.
(after soldering the broken parts back on :cry: ) I decided I would need an extra set of sensors out by the wheels and decided to use PD0 & PD1 with the QTR-1RC’s.

I am now very stuck with what to do next?!

I think I am going to need to edit Pololu3pi.cpp’s “Pololu3pi::init” function as follows:

void Pololu3pi::init(unsigned int line_sensor_timeout_us)
	// Set up the line sensor and turn off the emitters.
	// The sensors are on PC0..4, and the emitter is on PC5.
	unsigned char pins[5] = {14,15,16,17,18};


void Pololu3pi::init(unsigned int line_sensor_timeout_us)
	// Set up the line sensor and turn off the emitters.
	// The sensors are on PC0..4, and the emitter is on PC5.
	unsigned char pins[7] = {0,1,14,15,16,17,18};

But after compiling libpololu.a with those changes I get very strange errors from Make:

and then when I delete Main.elf and let Make build it again I get:

I am including #include “Pololu3pi.h” so i don’t know why its saying undefined reference to `readLineSensors’

If anyone has any experience with this kind of thing could you please point me in the right direction.
I have little understanding of C++. And I am currently compiling on a Mac if it makes any difference to anyone.

Thanks for your time and any help would be much appreciated.


That’s a strange error. Can you do a “make clean” in the library directory and recompile it again?

Same error as before!

However I have made some progress; I am now using qtr.h to read in the sensors with specified pins. I now need to physically hook it up to PD0 & PD1.

Any Tips?

- M

Oh, I just realized that you are using C++. It looks like you are using the C compiled (avr-gcc) with C++ code (your Main.c). That doesn’t sound right to me, but you had something working before, so maybe I just don’t understand what you are doing? The undefined reference error has to do with linking, so the fact that you included the .h file doesn’t matter at all. You have to make sure you are linking with -lpololu.

Anyway, you can use the AVR Library without the Pololu3pi class if you want to - it really doesn’t do much other than initializing the qtr object for you. Please let me know if you have more trouble getting it working! Also, if you do get it working, I want to see a video of this hacked 3pi zipping around a tabletop…it sounds exciting.


Thanks for the quick reply. I think am going to do without the Pololu3pi class as you said. There is one more thing…

This is my current setup - 90Degree header pin soldered to the QTR-1RC. With the paired prototyping holes connected (temporarily)

And all I’m getting back is “2” when the built-in ones are giving me a number/2000.
All I can think of is that its not charging the capacitor?

Any Ideas,

Thanks, M.

So you are connecting both VIN and OUT to PD0? That’s not going to work, because as soon as you set PD0 to an input, the LED will shut off, and the capacitor will discharge through the LED. Instead, VIN should connect to the 5V supply (VCC) for continuous operation.


O yer! Mind Blank - I was troubleshooting with that set up for ages!
Still no luck though hummm…

This is my code for gathering data from the IR sensors:

unsigned int sensors[6]; // An array to hold sensor values
unsigned char irPins[6] = {0, 14, 15, 16, 17, 18};  // 1 = PD1, 0 = PD0

qtr_rc_init(irPins, 6, 2000, 19);
qtr_read(sensors, IR_EMITTERS_ON);

Can I treat the external IR sensors exactly the same way as the built-in ones (in terms of programming)?

Thanks a lot for all your time and help

- M

Okay, sounds like you are getting closer! I hope we can work this out.

So, you are switching from C++ to C now? What values do you get from your current setup? Do the original 3pi sensors at least give you good values with that code? You aren’t showing me all of your code here, but I don’t think you are doing the right thing with qtr_calibrate. The idea is that you expose the sensors to some white and black regions, running qtr_calibrate a few times on each color, so it can record the minimum and maximum values. Then, the function qtr_read_calibrated can be used to return calibrated values. There’s no sense in doing the calibration before you even understand whether you sensors are working, though - you want to see the raw values to measure their basic performance.

The QTR-1RC sensors won’t be the same as the ones on the 3pi, because of different capacitor and resistor values. However, with calibration, you should be able to use them together.


Also, before, you had both sensor wires plugged in to PD1; is something now on PD0? Because you are using PD0 in your code.

I have very little understanding of C++ and so was always working in C, but I was trying to re-compile libpololu.a with my changes to the Pololu3pi class - which is in C++. - Hope this makes sense :question:

Yes, I get good values back from the built-in sensors just not the QTR’s. I was troubleshooting and so changed round the pin’s just to check but have always paralleled this in my code.
Oooo, so does calibrate just take in values form the sensors and then give you values relative to their initial values?

This is my full current code: (too long to post directly)
Current.rtf (14.1 KB)

What values are you getting from that sensor? It’s a little hard to tell what’s going on in your code, since it’s got so much else going on. Can you simplify it to the shortest possible program that produces unexpected results? It may be that the timeout of 2000 is just too short for the QTR-1RC, and you need to try 4000 or 8000 to get good readings.


Got It :smiley: It was the dammed Batteries!! Charged them up last night and it just worked - I didn’t even think about it being the batteries as the built-in Sensors worked…
Any chance you could explain how to calibrate the QTR with the inbuilt sensors to get the same ‘level’ of output?

Heres my initializeQTR funcion if anyone needs it:

void initializeQTR(BOOL print_out)
	unsigned int sensors[6]; // An array to hold sensor values
	unsigned char irPins[6] = {0, 14, 15, 16, 17, 18}; // Built in sensors pins (14, 15, 16, 17, 18), PD0 & PD1 (0, 1)
	qtr_rc_init(irPins, 6, 2000, 19);
	if(print_out == TRUE)
			qtr_read(sensors, IR_EMITTERS_ON);
			lcd_goto_xy(0,0);					// Top Line
			lcd_goto_xy(0,1);					// Bottom Line

Thanks for all your help!

- Marcus

Great, I’m glad you got it working. What kind of values are you seeing out of the new sensors, compared to the old ones, out of curiosity?

The qtr_calibrate() function is described in the C/C++ Library User’s Guide, and there is some sample code there which shows you what to do with it. Basically, you need to call it a bunch of times, while moving your robot from black to white. In your case, maybe you need to calibrate both on and off the table to get the right range of values. After appropriate calibration, qtr_read_calibrated() will return numbers that are in the range of 0 - 1000, where 0 corresponds to the lowest signal you read during calibration and 1000 corresponds to the highest (darkest).

Does that make sense?

Im getting back very high values - low reflectance - compared to the built-in ones.
I think i understand qtr_calibrate. Ill have a go and get back to you with a video… Thanks.


One thing you should note is that the discharge capacitors on the QTR-1RC sensors are several times bigger than the ones on the sensors built into the 3pi, so this means you will in general see longer discharge times from the 1RCs than you do from the 3pi sensors. You will also see longer discharge times due to your 1RCs being mounted higher off the ground than the 3pi sensors. Still, if you calibrate properly, you shouldn’t have to worry about these differences (just make sure you set the timeout parameter to be long enough for the 1RCs).

- Ben