Interfacing a NEC IR remote

I wonder if anyone can give me an idea as to what may be wrong. I am unable to intreface a NEC IR remote to my Arduino Decimilla.

Here's the situation: I've built an object-avoiding 'bot. It has geared motors, driven by a LM293 on pins 4,5 and 11,12. It has a Sharp IR sensor for seeing objects, connected to analog pin zero. The IR sensor is mounted on a servo. The servo is connected to pin 10 and is driven using the ServoTimer1 library, which I understand uses timer 1. All is well with this setup.

Now I want to optionally control the 'both with a remote. I ripped the IR receiver out of a dead DVD player (Toshiba) and I have the corresponding remote. I'm using the NECir library. Hooking up the IR and running the sample program works great. The program prints out codes as I push buttons on the remote.

Now even without wiring the IR to the 'bot, if I simply include libraary NECir and add an ir.begin() statement to my setup() function, all heck breaks loose. One of my motors stops turning completely. The other seems to turn sporadically. The servo seems to "slip" to its zero position, almost as if it was being disconnected for short periods of time.

From what little I can tell NECir used Timer 2, not Timer 1. Any idea what might be going on?

You may be running out of RAM. Try and reduce the amount of memory used by your sketch (removing strings printed to the serial port for example) and see if that fixes it.

Is there a way to check how much RAM I'm using? Not sure why I'd get the symptoms I'm seeing vs. the program crashing if it was RAM ...

Unfortunately there's no easy way to tell how much RAM you are using.

The only way is t count all your variables and string literals and add them up.

When you run out of RAM compleatly strange and unpredictable things can happen. The way i have understod it works is that the 1K of RAM is being used from both ends. Your variables and strings e.t.c. is using of it from one end and the processor is allocating internal "variables" from the other end. So if these two ways of using the RAM collides somewher in the middle.... well you can guess the rest.

This article explains it pretty good http://itp.nyu.edu/~gpv206/2008/04/making_the_most_of_arduino_mem.html

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(distance
SERVO_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