Pololu QTR-8RC IR Sensor Software

I wrote some code to test working with the Pololu QTR-8RC IR Sensor (shown below). I expected the binary display to go quickly to zero and the counter display to show how many counts to get to 0. However, if I move the sensor over a black and white surface, the binary display of PC0 and PC1 can switch back and forth betwen 0 and 1. I thought based on the sensor notes, once at zero, the sensor must be reset to 1 before switching back to a 0. Am I missing something?

/*****************************************************************************
 * Orangutan LV-168 Program: IR Test                                         *
 *                                                                           *
 * PURPOSE: This program provides a test routine to read a Pololu QTR-8RC    *
 * IR Sensor (2 sensor chip) and display the timing values on the LCD        *
 *                                                                           *
 * CONNECTIONS:	PC0 - Left Sensor											 *
 *				PC1 - Right Sensor											 *
 *				BUTTON0 - Button 0											 *
 *                                                                           *
 * CHANGE RECORD:                                                            *
 * DATE			DEVELOPER		CHANGE										 *
 * 16 Apr 2008	Romeo			Initial Development                          *
 *****************************************************************************/

// F_CPU tells util/delay.h our clock frequency
#define F_CPU 20000000UL	// Orangutan LV-168 frequency (20MHz)
#include "device.h"
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"			// provides routines for using the LCD

//IR Sensor Inputs
#define PC0nPC1				((1 << PC0) | (1 << PC1))	//Pins 0 & 1 on PORT C

// Onboard Buttons:
#define BUTTONS				((1 << BUTTON0) | (1 << BUTTON1) | (1 << BUTTON2))

// Set button pins as inputs and enable pullups on those pins
#define initButtons()		BUTTON_DDR &= ~BUTTONS; BUTTON_PORT |= BUTTONS
#define checkForButton()	( ~BUTTON_PIN & BUTTONS )

void ReadIRSensor()
{
	// Initialize Variables
	unsigned char IR;
	unsigned char newIR;
	unsigned int  ctr = 0;

	// Set the I/O line to an output and drive it high 
	// Allow at least 10 us for the 10 nF capacitor to charge
	DDRC  |= PC0nPC1;					 				// Set PC0 & PC1 as Output
	PORTC |= PC0nPC1;	  	 							// Set High
	_delay_us(10);

	// Make the I/O line an input (high impedance) 
	DDRC  &= ~PC0nPC1;									// Set PC0 & PC1 as inputs
	PORTC |=  PC0nPC1;									// Enable pull up resistors (Reads High)

	// Measure the time for the capacitor to discharge by waiting for the I/O line to go low 
	lcd_clear();
	IR = (PINC & PC0nPC1);
	lcd_gotoxy(0,1);
	lcd_binary(IR);

	while (IR != 0)
	{
		newIR = (PINC & PC0nPC1);
		if (newIR != IR)
		{
			lcd_gotoxy(0,0);
			lcd_int(ctr);
			lcd_gotoxy(0,1);
			lcd_binary(newIR);
			IR = newIR;
		}
		ctr++;
	}
}

int main()
{
	unsigned char button;

	initButtons();

	lcd_init();

	while (1)
	{
		lcd_clear();
		lcd_gotoxy(0, 0);
		lcd_string("Press 1");

		while (!(button = checkForButton()));	// wait for button press
		_delay_ms(10);							// debounce press
		while (checkForButton());				// wait for button release
		_delay_ms(10);							// debounce release

		if (button & (1 << BUTTON0))			// set motors based on trimpot
		{
			button = 0;
			ReadIRSensor();
		}
	}

	return 0;
}

Hello.

One problem I see right off the bat is your enabling the pull-ups on your sensor input lines. Once you charge the capacitors by driving the inputs high, you should set your inputs to be high-impedance, not pulled high.

Try changing your code from

// Make the I/O line an input (high impedance) 
   DDRC  &= ~PC0nPC1;                           // Set PC0 & PC1 as inputs
   PORTC |=  PC0nPC1;                           // Enable pull up resistors (Reads High)

to

// Make the I/O line an input (high impedance) 
   DDRC  &= ~PC0nPC1;                           // Set PC0 & PC1 as inputs
   PORTC &= ~PC0nPC1;                           // high-impedance inputs (pull-ups disabled)

and see if this leads to more reasonable behavior. If not, can you give me a more detailed description of what you’re doing and what you observe as a result?

- Ben

Ben,
Thanks, that worked great.