Remote controlled robot

Hey guys, I've been working on building my first robot to learn more about Arduino. The robot is detailed in this guide: Build Your First Robot - With Plans and Step-by-Step Instructions

However, I am only using that robot's construction as I want to learn to program this thing myself. I got it to do a test run with the servos already, so I'm fairly certain I could get this thing to move. The problem I'm having is figuring out how to control it with an IR remote. I'm using the IR remote library to try to achieve this. I loaded the IRrecvDump sketch on to my Arduino to test the sensor (code shown below) and when I point my remote at it nothing shows up in the Serial monitor. I've tried several different remotes to no avail. Any thoughts on what I might be doing wrong? If you need more info let me know!

/*
 * IRremote: IRrecvDump - dump details of IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 5;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.println("Could not decode message");
  } 
  else {
    if (results->decode_type == NEC) {
      Serial.print("Decoded NEC: ");
    } 
    else if (results->decode_type == SONY) {
      Serial.print("Decoded SONY: ");
    } 
    else if (results->decode_type == RC5) {
      Serial.print("Decoded RC5: ");
    } 
    else if (results->decode_type == RC6) {
      Serial.print("Decoded RC6: ");
    }
    Serial.print(results->value, HEX);
    Serial.print(" (");
    Serial.print(results->bits, DEC);
    Serial.println(" bits)");
  }
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");

  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    } 
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
}


void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
}

What are you using to sense the IR signal? Usually, you need an IR receiver with 38kHz built in filter.

Like this one: http://www.sparkfun.com/products/10266

I have that exact receiver, sorry for not stating that in the OP. Also, all of the wiring is exactly as shown in the guide I linked. All other components have been tested to work, I'm just having trouble getting this IR sensor to work.

Have you tested the ir detector. You can test it as shown in the link Sensor tutorials - IR remote receiver/decoder tutorial

Your code works, I tried it on my setup. The only difference is that my RECV_PIN is on pin 11.

Ufoguy:
Have you tested the ir detector. You can test it as shown in the link Sensor tutorials - IR remote receiver/decoder tutorial

Just tested that, it worked perfectly.

JoeO:
Your code works, I tried it on my setup. The only difference is that my RECV_PIN is on pin 11.

My receiver's out pin is plugged into D5 so the code should work correctly for me as well. There must be something I'm doing wrong..

Bump, could use more help with this. Im out of ideas to try.

I've made a small breakthrough on this project. I was able to get my IR sensor to decode some of the buttons on my cable remote. I tried to make a program to allow me to control my robot with said remote but I'm having an issue. Each button is doing exactly what it should, meaning if I press my up arrow button, the robot moves forward, if I press down, it goes reverse etc. However, it will never respond to a new button press after the first. So if I tell it to move forward, I cant turn, reverse, stop or anything. Code is below, much appreciated if someone can tell me what I'm doing wrong.

#include <Servo.h>
#include <IRremote.h>

Servo servoLeft;
Servo servoRight;

const unsigned int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);

decode_results result;

void setup()
{
  servoLeft.attach(9);
  servoRight.attach(8); 
  irrecv.enableIRIn();
}

void loop()
{
   if(irrecv.decode(&result))
   {
     switch(result.value)
     {
       case 0x1CE350AF: 
         forward();
         break;
       case 0x1CE3D02F: 
         reverse();
         break;
       case 0x1CE3F807:
         spinLeft();
         break;
       case 0x1CE37887:
         spinRight();
         break;
       case 0x1CE3E817:
         stopRobot();
         break;
     }
     irrecv.resume();
     delay(10);
   }
}

void forward() 
{
  servoLeft.write(180);
  servoRight.write(0);
}

void reverse() 
{
  servoLeft.write(0);
  servoRight.write(180);
}

void spinLeft() 
{
  servoLeft.write(0);
  servoRight.write(0);
}

void spinRight() 
{
  servoLeft.write(180);
  servoRight.write(180);
}

void stopRobot() 
{
  servoLeft.write(90);
  servoRight.write(90);
}

How about setting the code below to a false condition inside of each switch?

if(irrecv.decode(&result))

cyclegadget:
How about setting the code below to a false condition inside of each switch?

if(irrecv.decode(&result))

Thanks for the suggestion but my code actually functions perfectly. It was merely user error lol. Before writing the code I pasted here, I had forgot to put the irrecv.resume(); function call in it. I changed it to the code I showed here, but I only ever compiled it, apparently I had forgot to upload it. I tried it again this morning and it works perfectly :slight_smile:

Hey guys, added more on to the robot. I got a HC-SR04 ultrasonic sensor today so I decided to try and make an automated mode for my robot. So far, my basic automated mode works but with one problem. I would like to be able to press a button to go to and from automatic mode. This would allow the user to control the robot, or let the robot navigate by it's self, with a single button push. However, my code (shown below) currently does the following:

At start, I am able to use the remote to control the robot just fine.
I press '0' on my remote (the button that activates automation) and the robot starts doing it's own thing.
The robot now no longer responds to any button commands.

I'm sure there is something I'm just doing completely wrong so if you guys can give me any suggestions, or point out a blunder in my code I'd appreciate it!

#include <Servo.h>
#include <IRremote.h>

Servo servoLeft;
Servo servoRight;

const unsigned int RECV_PIN = 11;
const unsigned int US_OUT_PIN = 13;
const unsigned int US_IN_PIN = 12;

IRrecv irrecv(RECV_PIN);
decode_results result;

long distanceFront = 0;
int startAvoidDistance = 20;

void setup()
{
  servoLeft.attach(9);
  servoRight.attach(8); 
  irrecv.enableIRIn();
  pinMode(US_OUT_PIN, OUTPUT);
}


void loop()
{
   if(irrecv.decode(&result))
   {
     if(result.value == 800)
       autoMode();
     else
       controlMode();
   }
}

void forward() 
{
  servoLeft.write(180);
  servoRight.write(0);
}

void reverse() 
{
  servoLeft.write(0);
  servoRight.write(180);
}

void spinLeft() 
{
  servoLeft.write(0);
  servoRight.write(0);
}

void spinRight() 
{
  servoLeft.write(180);
  servoRight.write(180);
}

void stopRobot() 
{
  servoLeft.write(91);
  servoRight.write(91);
}

unsigned long measure_distance()
{
  pinMode(US_OUT_PIN, OUTPUT);
  digitalWrite(US_OUT_PIN, LOW);
  delayMicroseconds(2);
  
  digitalWrite(US_OUT_PIN, HIGH);
  delayMicroseconds(5);
  digitalWrite(US_OUT_PIN, LOW);
  
  pinMode(US_IN_PIN, INPUT);
  duration = pulseIn(US_IN_PIN, HIGH);
  
  return msToCentimeters(duration);
}

long msToInches(long microseconds)
{
  return microseconds/74/2;
}

long msToCentimeters(long microseconds)
{
  return microseconds/29/2; 
}

boolean checkFront()
{
  distanceFront = measure_distance();
  return distanceFront > startAvoidDistance; 
}

void autoMode()
{
  do
  {
    if(checkFront() == true)
      {
        forward();
        delay(2500);
        stopRobot();
        delay(1000);
        checkFront();
        delay(500);
        irrecv.resume();
        delay(25);
      } 
      else
      {
        stopRobot();
        delay(500);
        spinLeft();
        delay(500);
        stopRobot();
        delay(500);
        checkFront();
        delay(500);
        irrecv.resume();
        delay(25);
      }
  }
  while(result.value == 800);
}

void controlMode()
{
   switch(result.value)
       {
         case 802: 
           forward();
           break;
         case 808: 
           reverse();
           break;
         case 804:
           spinLeft();
           break;
         case 806:
           spinRight();
           break;
         case 805:
           stopRobot();
           break;
       }
       irrecv.resume();
       delay(25);
}

I would guess that you are having trouble because you are using delay() some add up to about 4 seconds. The only thing that can get threw a delay is an interrupt.

It will take some work but, you could implement a timing method to eliminate delay().

As always the blink without delay sketch should be prescribed.