Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Maik Schmidt - Arduino A Quick-Start Guide, 2nd Edition (The Pragmatic Programmers) - 2015.pdf
Скачиваний:
146
Добавлен:
22.03.2016
Размер:
30.47 Mб
Скачать

Cloning a Remote 207

remote, it will send the same code over and over again as long as you press the key. An Apple remote will send the key’s command code only once, and after that it sends the code 0xffffffff as long as you press the key.

Figure 30—Capture the IR codes of a Samsung remote

After you’ve grabbed a remote’s control codes, you can use them to build your own remote. You’ll learn how to do that in the next section.

Cloning a Remote

As soon as you know the protocol and the command codes a remote uses, you can clone it. You need only an infrared LED that doesn’t differ much from the LEDs we’ve used before. The only difference is that it emits “invisible” light. The figure shows how to connect it to pin 3 of an Arduino. (The library we’re using in this section expects the infrared LED to be connected to pin 3.) Note that you can’t use an LED without a resistor. (See Current, Voltage, and Resistance, on page 239, to learn more about it.)

We could try to generate the infrared signals ourselves, but that’d be tedious and error-prone. It’s better to use the existing implementation in the IRremote library. We’ll use it to create our own TvRemote

class that encapsulates all of the gory protocol details. Here’s the class:

report erratum • discuss

Chapter 12. Creating Your Own Universal Remote Control 208

 

RemoteControl/TvRemote/TvRemote.ino

Line 1

#include <IRremote.h>

-

 

-

class TvRemote {

-

 

5enum {

-

CMD_LEN

= 32,

GUIDE

= 0xE0E0F20D,

-

POWER

= 0xE0E040BF,

TOOLS

= 0xE0E0D22D,

-

SOURCE

= 0xE0E0807F,

INFO

= 0xE0E0F807,

-

HDMI

= 0xE0E0D12E,

OPTIONS

= 0xE0E016E9,

10

ONE

= 0xE0E020DF,

UP_K

= 0xE0E006F9,

-

TWO

= 0xE0E0A05F,

LEFT_K

= 0xE0E0A659,

-

THREE

= 0xE0E0609F,

RIGHT_K

= 0xE0E046B9,

-

FOUR

= 0xE0E010EF,

DOWN_K

= 0xE0E08679,

-

FIVE

= 0xE0E0906F,

RETURN

= 0xE0E01AE5,

15

SIX

= 0xE0E050AF,

EXIT

= 0xE0E0B44B,

-

SEVEN

= 0xE0E030CF,

A

= 0xE0E036C9,

-

EIGHT

= 0xE0E0B04F,

B

= 0xE0E028D7,

-

NINE

= 0xE0E0708F,

C

= 0xE0E0A857,

-

TXT

= 0xE0E034CB,

D

= 0xE0E06897,

20

ZERO

= 0xE0E08877,

PIP

= 0xE0E004FB,

-

PRE_CH

= 0xE0E0C837,

SEARCH

= 0xE0E0CE31,

-

VOL_UP

= 0xE0E0E01F,

DUAL

= 0xE0E000FF,

-

VOL_DOWN

= 0xE0E0D02F,

USB_HUB

= 0xE0E025DA,

-

MUTE

= 0xE0E0F00F,

P_SIZE

= 0xE0E07C83,

25

CH_LIST

= 0xE0E0D629,

SUBTITLE

= 0xE0E0A45B,

-

PROG_UP

= 0xE0E048B7,

REWIND

= 0xE0E0A25D,

-

PROG_DOWN

= 0xE0E008F7,

PAUSE

= 0xE0E052AD,

-

MENU

= 0xE0E058A7,

FORWARD

= 0xE0E012ED,

-

SMART_TV

= 0xE0E09E61,

RECORD

= 0xE0E0926D,

30

PLAY

= 0xE0E0E21D,

STOP

= 0xE0E0629D

-};

-

-IRsend tv;

-

35 void send_command(const long command) {

-tv.sendSAMSUNG(command, CMD_LEN);

-}

-

-public:

40

 

 

-

void guide()

{ send_command(GUIDE); }

-

void power()

{ send_command(POWER); }

-

void tools()

{ send_command(TOOLS); }

-

void source()

{ send_command(SOURCE); }

45

void info()

{ send_command(INFO); }

-

void hdmi()

{ send_command(HDMI); }

-

void zero()

{ send_command(ZERO); }

-

void one()

{ send_command(ONE); }

-

void two()

{ send_command(TWO); }

report erratum • discuss

Cloning a Remote 209

50

void three()

{ send_command(THREE); }

-

void four()

{ send_command(FOUR); }

-

void five()

{ send_command(FIVE); }

-

void six()

{ send_command(SIX); }

-

void seven()

{ send_command(SEVEN); }

55

void eight()

{ send_command(EIGHT); }

-

void nine()

{ send_command(NINE); }

-

void up()

{ send_command(UP_K); }

-

void left()

{ send_command(LEFT_K); }

-

void right()

{ send_command(RIGHT_K); }

60

void down()

{ send_command(DOWN_K); }

-

void ret()

{ send_command(RETURN); }

-

void exit()

{ send_command(EXIT); }

-

void a()

{ send_command(A); }

-

void b()

{ send_command(B); }

65

void c()

{ send_command(C); }

-

void d()

{ send_command(D); }

-

void txt()

{ send_command(TXT); }

-

void pip()

{ send_command(PIP); }

-

void pre_ch()

{ send_command(PRE_CH); }

70

void search()

{ send_command(SEARCH); }

-

void vol_up()

{ send_command(VOL_UP); }

-

void vol_down()

{ send_command(VOL_DOWN); }

-

void dual()

{ send_command(DUAL); }

-

void usb_hub()

{ send_command(USB_HUB); }

75

void mute()

{ send_command(MUTE); }

-

void p_size()

{ send_command(P_SIZE); }

-

void ch_list()

{ send_command(CH_LIST); }

-

void subtitle()

{ send_command(SUBTITLE); }

-

void prog_up()

{ send_command(PROG_UP); }

80

void prog_down()

{ send_command(PROG_DOWN); }

-

void pause()

{ send_command(PAUSE); }

-

void rewind()

{ send_command(REWIND); }

-

void forward()

{ send_command(FORWARD); }

-

void menu()

{ send_command(MENU); }

85

void smart_tv()

{ send_command(SMART_TV); }

-

void record()

{ send_command(RECORD); }

-

void play()

{ send_command(PLAY); }

-

void stop()

{ send_command(STOP); }

- };

The code starts with an enumeration that contains all the constants we need: the length of each control code (CMD_LEN) and the control codes themselves. There’s one entry in the enumeration for each key on our remote control.

In line 33, we define an IRsend object named tv that we’ll use to send commands using the send_command method. send_command uses IRsend’s sendSAMSUNG method because in this example we’re using a Samsung remote control. If you’re using a device from Sony or Sharp, you have to adjust the code accordingly. Note

report erratum • discuss

Chapter 12. Creating Your Own Universal Remote Control 210

that at the time of this writing, the IRremote library is able to decode remote controls from Sanyo, Mitsubishi, and LG, but it doesn’t support sending

 

commands to devices from these manufacturers.

 

After we’ve established the basis, we can implement all commands with a

 

single function call, so implementing power, menu, play, and so on is a piece of

 

cake.

 

Using the TvRemote class is easy, too. In the following sketch, we use it to

 

control a Samsung TV from the Arduino’s serial monitor:

 

RemoteControl/TvRemote/TvRemote.ino

Line 1

const unsigned int BAUD_RATE = 9600;

-

 

-TvRemote tv;

-String command = "";

5

boolean input_available = false;

-

 

-void setup() {

-Serial.begin(BAUD_RATE);

-}

10

-void serialEvent() {

-while (Serial.available()) {

-const char c = Serial.read();

-if (c == '\n')

15 input_available = true;

-else

-command += c;

-}

-}

20

-void loop() {

-if (input_available) {

-Serial.print("Received command: ");

-Serial.println(command);

25

if (command == "guide")

tv.guide();

-

else if (command == "power")

tv.power();

-

else if (command == "tools")

tv.tools();

-

else if (command == "source")

tv.source();

-

else if (command == "info")

tv.info();

30

else if (command == "hdmi")

tv.hdmi();

-

else if (command == "zero")

tv.zero();

-

else if (command == "one")

tv.one();

-

else if (command == "two")

tv.two();

-

else if (command == "three")

tv.three();

35

else if (command == "four")

tv.four();

-

else if (command == "five")

tv.five();

-

else if (command == "six")

tv.six();

-

else if (command == "seven")

tv.seven();

report erratum • discuss

Cloning a Remote 211

-

else if (command == "eight")

tv.eight();

40

else if (command == "nine")

tv.nine();

-

else if (command == "up")

tv.up();

-

else if (command == "left")

tv.left();

-

else if (command == "right")

tv.right();

-

else if (command == "down")

tv.down();

45

else if (command == "ret")

tv.ret();

-

else if (command == "exit")

tv.exit();

-

else if (command == "a")

tv.a();

-

else if (command == "b")

tv.b();

-

else if (command == "c")

tv.c();

50

else if (command == "d")

tv.d();

-

else if (command == "txt")

tv.txt();

-

else if (command == "pip")

tv.pip();

-

else if (command == "pre_ch")

tv.pre_ch();

-

else if (command == "search")

tv.search();

55

else if (command == "vol_up")

tv.vol_up();

-

else if (command == "vol_down")

tv.vol_down();

-

else if (command == "dual")

tv.dual();

-

else if (command == "usb_hub")

tv.usb_hub();

-

else if (command == "mute")

tv.mute();

60

else if (command == "p_size")

tv.p_size();

-

else if (command == "ch_list")

tv.ch_list();

-

else if (command == "subtitle")

tv.subtitle();

-

else if (command == "prog_up")

tv.prog_up();

-else if (command == "prog_down") tv.prog_down();

65

else if (command == "pause")

tv.pause();

-

else if (command == "rewind")

tv.rewind();

-

else

if (command

== "forward")

tv.forward();

-

else

if (command

== "menu")

tv.menu();

-else if (command == "smart_tv") tv.smart_tv();

70

else if (command == "record")

tv.record();

-

else

if (command

== "play")

tv.play();

-

else

if (command

== "stop")

tv.stop();

-else Serial.println("Command is unknown.");

-

75 command = "";

-input_available = false;

-}

-}

In lines 3 to 5, we define a global TvRemote object named tv, a string named command that holds the current command, and a Boolean flag named input_available that is true when the sketch has received a new command. As usual, we initialize the serial port in the setup function.

The Arduino calls the serialEvent function defined in line 11 when new data arrives at the serial port. (Learn more about serialEvent in Serial Communication Using Various Languages, on page 255.) We append that data to the command

report erratum • discuss

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]