Build this project at our next weekend-long Arduino workshop!

Remote Control Cardboard Box

The remote control cardboard box robot uses a standard (“universal”) infrared TV remote and a infrared receiver to control a cardboard box with two motorized wheels. You analyze your remote to see what messages it’s sending, and use your data to choose which buttons cause which actions on the box robot.

Hardware

Wiring

  1. Wire up your Arduino as shown in the image below:

    Fritzing diagram
    Fritzing diagram of motors, a driver, and IR receiver | full size »
    Schematic diagram
    Schematic diagram of motors, a driver, and IR receiver | full size »

  2. Use alligator clips to connect the motors, one end clipped to a motor lead, and the other end clipped to a jumper wire.

  3. Make sure you connect the correct wires for your chosen IR receiver. Search Google for your receiver’s part number, and you should find a PDF “data sheet” with an image like this one:

    Data sheet excerpt

    In this sheet, pin V<sub>S</sub> should be connected to 5V, pin GND to ground, and OUT to Arduino digital pin 2. Use the values in your sheet to connect the correct pins!

Software

  1. First, test your motor wiring by running the following motor testing code. The wheels should move forward for a second, then stop for a second, and repeat. If either or both wheels are rotating in the wrong direction, switch two connectors around on those wheels.

    /*
      Motor Tester
      Scaffolding to figure out motor directions.
     */
    
    int motorRightForward   = 9;
    int motorRightReverse   = 10;
    int motorLeftForward    = 11;
    int motorLeftReverse    = 12;
    
    void setup() {
      pinMode(motorRightForward, OUTPUT);
      pinMode(motorRightReverse, OUTPUT);
      pinMode(motorLeftForward, OUTPUT);
      pinMode(motorLeftReverse, OUTPUT);
    }
    
    void forward() {
      digitalWrite(motorRightForward, HIGH);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, HIGH);
      digitalWrite(motorLeftReverse, LOW);
    }
    
    void halt() {
      digitalWrite(motorRightForward, LOW);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, LOW);
      digitalWrite(motorLeftReverse, LOW);  
    }
    
    void loop() {
      forward();
      delay(1000);
      halt();
      delay(1000);
    }
    
  2. Install the IR Remote library: in Arduino, in the “Sketch” menu, select “Import Library…” then “Add Library…”, and in the resulting diablog box, navigate to the IRremote.zip file you just downloaded. (Note: this library conflicts with a built-in library in Arduino version 1.6.0 – if you’re getting a strange error, try Arduino version 1.6.4`!)`

  3. Upload this remote control cardboard box testing code, but note that your remote control won’t trigger the wheels yet:

    /**
      Remote Control Motor Driver
    
      Set two motor pins based on input from an infrared remote control.
     **/
    
    #include <IRremote.h>
    
    int remoteInputPin = 2;
    IRrecv receiver(remoteInputPin);
    decode_results results;
    
    int motorRightForward   = 9;
    int motorRightReverse   = 10;
    int motorLeftForward    = 11;
    int motorLeftReverse    = 12;
    
    void setup() {
      Serial.begin(9600);
      receiver.enableIRIn();
    
      pinMode(motorRightForward, OUTPUT);
      pinMode(motorRightReverse, OUTPUT);
      pinMode(motorLeftForward, OUTPUT);
      pinMode(motorLeftReverse, OUTPUT);
    }
    
    void forward() {
      digitalWrite(motorRightForward, HIGH);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, HIGH);
      digitalWrite(motorLeftReverse, LOW);
    }
    
    void halt() {
      digitalWrite(motorRightForward, LOW);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, LOW);
      digitalWrite(motorLeftReverse, LOW);  
    }
    
    // add more control functions here!
    
    // end of control functions
    
    void loop() {
      if (receiver.decode(&results)) {
        Serial.println(results.value, HEX);
    
        if (results.value == 0xABCD) {
          Serial.println("FORWARD");
          forward();
        } else if (results.value == 0x0000) {
          Serial.println("HALT");
          halt();
        } // add more "else if" conditions here for other buttons!
    
        receiver.resume();
      }
    }
    
  4. Open the Serial Monitor in Arduino – that’s the magnifying glass icon in the upper-right corner of the window. Pick a button that you want to trigger your box’s forward motion. Press that button and see which number appears in the serial monitor. This is the hexadecimal version of the number the remote sends when you press the button. Copy this number.

  5. Inside the void loop() function, find the if statement that falls above the "FORWARD" line. Update the condition (results.value == 0xABCD), replacing ABCD with the number you found above. (Note: the 0x prefix tells Arduino that the number is written in hexademical – without it, you may get some strange error, or it may just not work at all!)

  6. Upload your code and make sure the forward button on your remote makes your box move forward. If it doesn’t – what went wrong? If nothing happens at all, check to make sure you are still seeing the same number in the serial monitor. If the box moves, but not in the direction you expect, check the forward & reverse pins for each motor.

  7. Repeat steps 4-6 for the halt function, picking a new button, copying it into the "HALT" if statement in the code, and testing.

  8. To fully control your box, you’ll want extra control functions: at least reverse, left, and right. Each should be triggered by a specific button on your remote.

    Write functions for reverse, left, and right – these will look very similar to the existing forward and halt functions, but with different HIGH and LOW settings depending on which way you want each motor to turn for each function. Place the new functions after the forward and halt functions, but not inside any other function. (These are top-level functions we can use from anywhere in the code!)

    Add additional else if statements for reverse, left, and right. These will look very similar to the else if statement for the halt function, except you’ll compare results.value to a different button number, call the reverse(), left(), or right() function instead of halt(), and print a different string.

  9. Test! Your code may end up looking something like this:

    /**
      Remote Control Motor Driver
    
      Set two motor pins based on input from an infrared remote control.
     **/
    
    #include <IRremote.h>
    
    int remoteInputPin = 2;
    IRrecv receiver(remoteInputPin);
    decode_results results;
    
    int motorRightForward   = 9;
    int motorRightReverse   = 10;
    int motorLeftForward    = 11;
    int motorLeftReverse    = 12;
    
    void setup() {
      Serial.begin(9600);
      receiver.enableIRIn();
    
      pinMode(motorRightForward, OUTPUT);
      pinMode(motorRightReverse, OUTPUT);
      pinMode(motorLeftForward, OUTPUT);
      pinMode(motorLeftReverse, OUTPUT);
    }
    
    void forward() {
      digitalWrite(motorRightForward, HIGH);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, HIGH);
      digitalWrite(motorLeftReverse, LOW);
    }
    
    void reverse() {
      digitalWrite(motorRightForward, LOW);
      digitalWrite(motorRightReverse, HIGH);
      digitalWrite(motorLeftForward, LOW);
      digitalWrite(motorLeftReverse, HIGH);
    }
    
    void left() {
      digitalWrite(motorRightForward, HIGH);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, LOW);
      digitalWrite(motorLeftReverse, HIGH);
    }
    
    void right() {
      digitalWrite(motorRightForward, LOW);
      digitalWrite(motorRightReverse, HIGH);
      digitalWrite(motorLeftForward, HIGH);
      digitalWrite(motorLeftReverse, LOW);
    }
    
    void halt() {
      digitalWrite(motorRightForward, LOW);
      digitalWrite(motorRightReverse, LOW);
      digitalWrite(motorLeftForward, LOW);
      digitalWrite(motorLeftReverse, LOW);  
    }
    
    void loop() {
      if (receiver.decode(&results)) {
        Serial.println(results.value, HEX);
    
        if (results.value == 0xABCD) {
          Serial.println("FORWARD");
          forward();
        } else if (results.value == 0xDCBA) {
          Serial.println("REVERSE");
          reverse();
        } else if (results.value == 0x1234) {
          Serial.println("LEFT");
          left();
        } else if (results.value == 0x4321) {
          Serial.println("RIGHT");
          right();
        } else if (results.value == 0x0000) {
          Serial.println("HALT");
          halt();
        }
    
        receiver.resume();
      }
    }