Well, I found a solution by trial and error which I'll offer here for anyone else that may run into a similar problem. I found that I could not receive signals from the remote while the motors were running. If I stopped the motors I had no problem receiving IR. So my solution was to implement a motor "duty-cycle" within the loop() function.
Here's a copy of the working code:
#include <NECIRrcv.h>
#include <ServoTimer1.h>
/* Pin assignments */
#define EYEPIN 0 // IR detector/emitter
#define SERVOPIN 9 // eye control
#define BUMPERPIN 7 // bump switch
#define IRPIN 8 // NCR IR detector is connected to
#define MOTOR_L1 5
#define MOTOR_L2 6
#define MOTOR_R1 11
#define MOTOR_R2 12
#define LEDPIN 13
// Servo motor contstants
#define SERVO_STEP_SIZE 5
#define NUM_SERVO_STEPS 36
#define STRAIGHT_AHEAD 18
// IR distance constants
#define DANGER_DISTANCE 500
ServoTimer1 servo;
NECIRrcv ir(IRPIN);
void setup()
{
pinMode(MOTOR_L1, OUTPUT);
pinMode(MOTOR_L2, OUTPUT);
pinMode(MOTOR_R1, OUTPUT);
pinMode(MOTOR_R2, OUTPUT);
pinMode(LEDPIN, OUTPUT);
servo.attach(SERVOPIN);
moveServo(STRAIGHT_AHEAD);
ir.begin() ;
// Serial.begin(9600) ;
// Serial.println("NEC IR code reception") ;
}
void loop()
{
unsigned long ircode=0;
static boolean remoteControl = false;
//The motors go off at the end of every loop to give the remote a chance to get caught.
//Turn it on here and make sure it runs a bit (do it yourself PWN)
motorOn();
for (int i=0; i<250; i++); // Make sure the motor gets to run a little
//Check to see if we smashed into anything. If so, back up and look for a better way to go.
if (digitalRead(BUMPERPIN) == HIGH) {
motorReverse();
motorOn();
delay(1000);
motorOff();
if (bestDirection() > 0)
motorSpinRight();
else
motorSpinLeft();
motorOn();
delay(500);
motorOff();
}
//This section controls the 'bot with the NCR IR remote.
//Buttons used are Power ON/OFF, the four arrow keys, and the enter key.
if (ir.available()) {
ircode = ir.read();
// Serial.print("got code: 0x") ;
// Serial.println(ircode,HEX) ;
}
//Power button toggles the variable remoteControl on and off.
if (ircode == 0xED12BA45) {
motorStop();
if (remoteControl == true) {
digitalWrite(LEDPIN, LOW);
remoteControl = false;
}
else {
digitalWrite(LEDPIN, HIGH);
remoteControl = true;
}
}
//When we're under remoteControl, obey the buttons, otherwise ignore them.
if (remoteControl == true) {
switch (ircode) { // Up arrow
case 0x7F80BA45:
motorForward();
break;
case 0x7E81BA45: // Down arrow
motorReverse();
break;
case 0xB24DBA45: // Left arrow
if (isMoving())
motorTurnRight();
else
motorSpinRight();
break;
case 0xAE51BA45: // Right arrow
if (isMoving())
motorTurnLeft();
else
motorSpinLeft();
break;
case 0xDE21BA45: // Emter
motorStop();
break;
default: // Anthing else, including nothing at all, is ignored.
break;
}
}
else { // Remote control = off
// Check to see if there's anything in front of us. Debounce the IR even though we are moving...
int distance = analogRead(EYEPIN);
while (abs(distance - analogRead(EYEPIN)) > 20) {
distance = analogRead(EYEPIN);
}
// If there's an obstacle too close to us, stop and turn around.
if (distance > DANGER_DISTANCE) {
motorOff();
if (bestDirection() > 0) motorSpinRight();
else motorSpinLeft();
motorOn();
delay(500);
motorStop();
}
else {
motorForward();
}
}
// Turning the motor off allows IR button presses to be received.
motorOff();
}
/*
- Routine to return the direction of least obstruction so we can turn that way.
- Greater than zero for right, less than zero for left.
*/
int bestDirection() {
int total=0, distance;
for (int i=0; i<=NUM_SERVO_STEPS; i++) {
moveServo(i);
//Debounce the IR reading, the servo is bouncing around a lot.
distance = analogRead(EYEPIN);
while (abs(analogRead(EYEPIN) - distance) > 10) {
distance = analogRead(EYEPIN);
}
if (i < NUM_SERVO_STEPS/2)
total -= distance;
else
total += distance;
}
moveServo(STRAIGHT_AHEAD); // Center it back again.
return(total);
}
/* Routines to move the servo /
void moveServo(int distance) {
servo.write(distanceSERVO_STEP_SIZE);
delay(50); /* For the servo to settle */
}
/* Routines to move the motors */
int motorL1, motorL2, motorR1, motorR2;
bool isMoving(void) {
if ((motorL1 == motorL2) and (motorR1 == motorR2))
return(false); //not moving
return(true); //moving
}
void motorOff(void) {
digitalWrite(MOTOR_L1, LOW);
digitalWrite(MOTOR_L2, LOW);
digitalWrite(MOTOR_R1, LOW);
digitalWrite(MOTOR_R2, LOW);
}
void motorOn(void) {
digitalWrite(MOTOR_L1, motorL1);
digitalWrite(MOTOR_L2, motorL2);
digitalWrite(MOTOR_R1, motorR1);
digitalWrite(MOTOR_R2, motorR2);
}
void motorStop(void) {
motorL1 = LOW;
motorL2 = LOW;
motorR1 = LOW;
motorR2 = LOW;
}
void motorForward(void) {
motorL1 = HIGH;
motorL2 = LOW;
motorR1 = HIGH;
motorR2 = LOW;
}
void motorReverse(void) {
motorL1 = LOW;
motorL2