Interfacing Parallax QTI Line Sensors to the Orangutans

My experience getting Parallax QTI sensors working with an Orangutan is a sordid story of ignorance and not looking for the answers in any of the right places. But to spare anyone else the nerve-grinding aggravation I went through, I’ll share the story’s punchline:

From reading the data sheet for the QTI, it looks like a 0-5V analog device. It’s not. It has an onboard capacitor that accumulates a charge based on how much reflected IR light the QTI sees. So reading one out is a little funky. Here’s the routine I wrote for reading QTI sensors on an Orangutan. It’s written to use Orangutan-lib, but it should work with any implementation of ADC routines:

// Routine for reading QTI sensors
//
// Reading the datasheet, you'd think the Parallax QTI sensor was a
// strict analog device.  Not so!  The capacitor on the QTI isn't 
// for filtering noise.  It's a charge integrator.
//
// To use a QTI sensor, you must:
//
// 1 - Set the I/O line to output
// 2 - Bring the I/O line high to drain the capacitor
// 3 - Wait 0.230ms for the drain to finish
// 4 - Bring the I/O line low
// 5 - Set the I/O line as input
// 6 - Wait 0.230ms for the capacitor to charge
// 7 - Read the ADC for that channel
//
// Convoluted?  Yes.  But it does work.  Why'd they design it that
// way?  My guess is the photoreflector they used is noisy, and this
// is a good way not only to dump the noise, but to up the overall
// sensitivity since it's an integrated device.

int qti(unsigned char channel)
{
	// Make sure the channel is between 0 and 7
	channel &= 0x7;

	// Set PCx as output
	DDRC |= (1 << channel);
	// Bring that pin high
	PORTC |= (1 << channel);
	// Delay 0.230ms
	_delay_us(230);
	// Bring that pin low
	PORTC &= ~(1 << channel);
	// Set PC0 as input
	DDRC &= ~(1 << channel);
	// Delay 0.230ms
	_delay_us(230);
	// Read the channel
	return(analog8(channel));
}

This makes a couple of assumptions, one of which is false:

1 - That PORTC also functions as the port for analog inputs. This is true on the ATMega48/168 Orangutans, but may not be true of older Orangutans or for the Orangutan-X2.

2 - That all the analog I/O lines can be used as outputs. This isn’t true. Basically it means you can use PORTC.0 through PORTC.5 for driving QTI sensors. That “channel &= 0x7” line should really clamp it to 5, not 7.

3 - That you have F_CPU set (you should do this anyway…) This relies on microsecond delays for discharging and charging the capacitor on the QTI.

4 - This assumes 230us is the right time to delay. I’m not 100% convinced of this. This equates to the zero time delay in the Basic Stamp, so it’s what I used. But using this value the ADC only reads about 214 even when the detector is saturated. I’m guessing something closer to 300us would be better. Some experimentation is required.

I don’t know how much utility this will have for anyone but me, but I figured I’d share.

Have fun!

Tom

P.S. My Baby-O line follower slowly sloooowly gets built!

1 Like