ML2016-4

Controlled by a TV remote?

Now that we can move servo's, turn LEDs and relays on and off, wouldn't it be nice to have some control over them from afar without a computer, or for that matter, not even using cables?

How 'bout just using a simple TV remote control? Well, there are plenty of websites explaining how a TV remote works, and we could all imagine that there is some magic in the pulses that the infrared emitter is sending across the air from your hand to the other side...so, let’s keep it simple and grab a device that will decode all those pulses and make our Arduino do something useful!

Vishay makes a 38 kHz IR sensor, the TSOP34438 that can be bought from Mouser for a mere $1.27. It has three pins, Power (Vcc, pin 3), Ground (or common, pin 2) and the Signal, (or output, pin 1). The 34438 works with supply voltages from 2.5 V to 5.5 Vdc, so perfect for an Arduino that can provide 5 V or 3.3 V.

Since low budget is important too, we also buy the least expensive TV remote control at our local store, like the Onn 4 Device Universal Remote for $2.64. You might already have a spare remote handy from an unused television, and if it emits data on a 38 kHz carrier, you are in business. How would you know? You connect the TSOP to your Arduino, load the code shown below and open the Serial Port Monitor to let the Arduino show you the codes as you press the buttons. If you can get the same codes for the same buttons and enough different codes between different buttons, the remote passes the test.

We connect the 34438 with the signal pin (pin 1, on the left if the dome is facing you) to the Arduino’s D11 pin. The middle pin goes to ground (black, shown below) and the 3rd pin, on the right (yellow), connects to 5 V.


Pin 1 from TSOP34438 to pin 17 on ATMEGA328P

(D11 on Arduino) shown in purple.

Speed-Tip: if you have an Arduino Uno, you could also simply plug the TSOP34438 into the Arduino connector with pin 1 going to Arduino pin 11 and then you output a LOW on pin 10 and a HIGH on pin 9, for GND and Vcc, no wiring needed!

In order to use the Arduino library to read the values from the TSOP34438, you would need to install the IRremote library by downloading this file https://github.com/z3t0/Arduino-IRremote/archive/master.zip. Extra thanks to Ken Shirriff. I tried the Sketch → Include Library → Manage Libraries... route, but got some CRC errors, so I simply downloaded the file and use Sketch → Include Library → Add .ZIP library pointing it to the downloaded file. You also need to move the RobotIRremote folder from C:\Program Files (x86)\Arduino\libraries\RobotIRremote to somewhere else than libraries, since it also contains an IRremote library which is not what we need. After moving the RobotIRremote folder, restart the Arduino IDE again.

One special thing to know, this IR library uses Timer2 on the ATMEGA chip to read the data coming from the TSOP34438, so you won’t be able to use all the PWM pins as you did before. Timer2 controls PWM pins 3 and 11, so you need to avoid using these now as PWM pins.

Code for data to show TV remote codes in Serial Port Monitor (Ctrl-Shift-M):

// IRremote: receiving IR codes to display on

// Serial Port ( Ctrl-Shift-M )

#include <IRremote.h>

#include <Servo.h>

#define VERSION "My first IR project, 0.01"

// remote #defines goes here

#define LED_PIN 13

#define IR_RECEIVE_PIN 11

#define GND_PIN 10

#define VCC_PIN 9

#define SIGNAL_PIN 6

#define SERVO_PIN 5

#define SERVOLEFT 75

#define SERVORIGHT 105

#define SERVOCNTR 90

Servo myServo;

IRrecv myReceiver( IR_RECEIVE_PIN ); // receive on pin 11

decode_results code;

void setup() {

pinMode( LED_PIN, OUTPUT ); digitalWrite( LED_PIN, HIGH );

pinMode( GND_PIN, OUTPUT ); digitalWrite( GND_PIN, LOW );

pinMode( VCC_PIN, OUTPUT ); digitalWrite( VCC_PIN, HIGH );


Serial.begin( 115200 );

myReceiver.enableIRIn(); // set the receiver up

myServo.attach( SERVO_PIN ); myServo.write( SERVOCNTR );

pinMode( SIGNAL_PIN, OUTPUT ); digitalWrite( SIGNAL_PIN, LOW );

delay( 200 );

Serial.println( VERSION );

digitalWrite( LED_PIN, LOW );

} // setup

void loop() {

if ( myReceiver.decode( &code ) ) {

digitalWrite( LED_PIN, HIGH );

// switch goes here ...

Serial.println( code.value, HEX );

myReceiver.resume();

digitalWrite( LED_PIN, LOW );

} // if

} // loop

/******************************* END OF FILE **********************************/

And shown in the Serial Port Monitor, pressing UP, DOWN, LEFT and then RIGHT:

My first IR project, 0.01

20DF00FF → up

20DF807F → down

20DFC03F → left

20DF40BF → right

So all we need to do now is capture those codes in our code, and make the Arduino do something with them!

At the top:

#define REMOTE_UP 0x20DF00FF

#define REMOTE_DOWN 0x20DF807F

#define REMOTE_LEFT 0x20DFC03F

#define REMOTE_RIGHT 0x20DF40BF

And then we replace the comment shown as “// switch goes here ...” with

switch( code.value ) {

case REMOTE_UP:

digitalWrite( SIGNAL_PIN, HIGH );

Serial.println( ”UP” );

break;

case REMOTE_DOWN:

digitalWrite( SIGNAL_PIN, LOW );

Serial.println( ”DOWN” );

break;

case REMOTE_LEFT:

myServo.write( SERVOLEFT );

Serial.println( ”<-” );

break;

case REMOTE_RIGHT:

myServo.write( SERVORIGHT );

Serial.println( ”->” );

break;

default:

Serial.println( code.value, HEX );

break;

} // switch

And now the left and right buttons on the remote will move the servo left and right; and the up and down buttons will turn the signal LED on and off.

When you keep the remote button in, you will notice a whole bunch of FFFFFFFF‘s being produced, think how you could make use of that....maybe the first press let the servo move, but when you hold the button in it locks it...Dispatcher, may I have the main line again, pretty please?