Controlling Your TV

Foreword

We have IR emitting LEDs on our robot, and you've learned how TV remote controls work. Do you think we can control your TV with our robot? The answer is YES!

This lesson is meant to help you get practice exploring code in order to accomplish your own projects. It involves reading into an Arduino library, and finding out how to use it for your own purposes.

Get Started

Our goal is to make the TV change channel, to the next channel, every 10 seconds automatically. This is our high level goal.

If you think about it, what you need to do is blink the IR emitter LED in a very specific sequence. You already know how to blink LEDs slowly, you just got to use the same idea, but faster, right?.

You are right, but the problem is finding out what you need to send out. You might be thinking, "we have a debug sketch that tells me what the TV remote is sending, I could just copy that and send it back", and you know what, you are kind of right, keep in mind, that data has already been decoded. You don't actually know how long each mark and space is, even if you know the decoded data.

"How did you get those waveform pictures in the previous lesson? Those shows me how long each mark and space should be."
That was captured with a tool called a logic analyzer. If you own one, you are probably skilled enough to not even need any of my lessons. For this class, I will pretend you don't own one.

The Library

"If there is a library for reading received IR codes, there must be a library for sending IR codes, right?" Bingo, actually it's the same library, it does both in one library. When I found the library on github, the front page said "This library enables you to send and receive using infra-red signals on an Arduino".

The library's Github page doesn't really tell you how to use it. It actually says "TODO (Check examples for now)" where it was supposed to explain "Usage". That's what we are about to do.

Studying the Example

Take a look at this example: IRsendDemo.ino (github link)


/*
 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */


#include <IRremote.h>

IRsend irsend;

void setup()
{
}

void loop() {
	for (int i = 0; i < 3; i++) {
		irsend.sendSony(0xa90, 12);
		delay(40);
	}
	delay(5000); //5 second delay between each signal burst
}

Notice a few things...

An IR LED must be connected to Arduino PWM pin 3. This I have done when I designed the robot's circuit and PCB. I fully understood how to use this library before designing the circuit. Here's the parts of the diagram I'm talking about:

IRsend irsend; seems to be how to globally declare an instance of IRsend that we can use, and thus, using functions should look like irsend.doSomething();

irsend.sendSony(0xa90, 12); seems to be how to actually send the code. It says "Sony", and your TV might be Sharp or Samsung. We also need to find out what 0xA90 and 12 actually means.

Warning: Library Name Confusion

The code that I wrote say #include <IRremote_Include.h> but other people write #include <IRremote.h>

Why?

This IRremote library has some installation steps that require you to delete stuff from inside Arduino IDE. Now since the public library computers are locked-down, it is impossible to do this. But by simply renaming IRremote.h to IRremote_Include.h, we avoid this problem.

This only works if you are using the sketchbook I prepared for you.

Studying the Library

We need to look through the library code and find out how to write similar code, but for whatever brand of TV you have (I will pretend you have Samsung for the rest of this lesson). Remember the stuff I told you about reading what is available in a library from the Arduino lesson.

If you look at the files inside the library, they've made it very easy to find the brand you need.

Open ir_Sony.cpp (github link)

One of the first functions you'll see is void IRsend::sendSony(unsigned long data, int nbits). This means the 0xA90 should mean "data" and 12 should mean "nbits" (number of bits). Cool, so let's see the version of the function meant for Samsung.

Open ir_Samsung.cpp (github link)

In roughly the same spot as before, you see void IRsend::sendSAMSUNG (unsigned long data, int nbits). This means the function call would look like irsend.sendSAMSUNG(0xSomeNumber, AnotherNumber); and we just need to find out what "data" should be and "nbits" should be.

Remember the sketch "IrRemoteDebug" (github link) and how it dumped the brand and code? Open the sketch "IrRemoteDebugWithBits" (github link). As the name implies, it will tell you how many bits each command should be.

What's in this data structure?

If you compared the two skeches IrRemoteDebug and IrRemoteDebugWithBits, you'll notice that the information about "number of bits" is stored in results.bits , which means it's a part of the results data structure. You should be wondering, "how do I know what a data structure contains?"

Since the declaration of results is decode_results results;, we know decode_results is the actual type of the data structure, results is just a variable name that represents one instance of the data structure. Open up "IRremote.h" (github link), and you'll find this piece of code:


//------------------------------------------------------------------------------
// Results returned from the decoder
//
class decode_results
{
	public:
		decode_type_t          decode_type;  // UNKNOWN, NEC, SONY, RC5, ...
		unsigned int           address;      // Used by Panasonic & Sharp [16-bits]
		unsigned long          value;        // Decoded value [max 32-bits]
		int                    bits;         // Number of bits in decoded value
		volatile unsigned int  *rawbuf;      // Raw intervals in 50uS ticks
		int                    rawlen;       // Number of records in rawbuf
		int                    overflow;     // true iff IR raw code too long
};

If you have trouble finding out exactly which file to look in, remember that most good code editors have a function to search across files. Also, GitHub has a search function that can search within specific projects.

So now, if you are ever confused about how to find out what a data structure contains, you know how to find out.

Almost Done

With the new debug data, you should be able to use the same steps to obtain the "nbits" you need.

Have a look at the code from before again...


	for (int i = 0; i < 3; i++) {
		irsend.sendSony(0xa90, 12);
		delay(40);
	}
	delay(5000); //5 second delay between each signal burst

I don't think my lessons covered for-loops before, it's a loop that has a start condition int i = 0 (i starts at 0), a condition i < 3 (i must be less than 3 to continue), and an "afterthought" i++ (increase i by 1 each loop). Anyways, the for-loop is there to send the command 3 times, really quickly (we know it's quick because the delay is only 40 milliseconds). The longer 5000 millisecond delay obviously delays 5 seconds.

The Arduino reference on language structures will cover more topics such as for-loops, and other loop types. Also remember all the websites you can learn from.

I think you've learned enough to be able to finish this project. You know what function to change, and what numbers to change. Go for it.

Afterwords

What could you do with this project? You can make your own Logitech Harmony Hub if you just add some bluetooth module to your robot. There are plenty of possibilities.

If you have a friend who also has one of our robots, you could make them talk to each other.




Click Here, to return to the list of classes