Arduino 红外解码算法

IR Codes... the non-standardest thing on Earth?

Each remote control maker seems to have invented their own IR-signal protocol. So, to send a certain order, we must first find out what that order shall look like. It will be a rapid sequence of "LED on" and "LED off", with each manufacturer having different definitions of how long a LED should be on or off, how to represent "binary 1" and "binary 0" and so forth. There is of course no standard at all for the different commands or the number of bits in a message.

On the other hand, I guess it's good that all devices speak different languages so that they don't interfer with one another. Whatever.

 

Anyway, Ken Shirriff has sorted this out, and published the IRremote library. 

With the IRrecvDump example code, I "interviewed" the remotes for the Panasonic TV, the Samsung DVD, the Onkyo receiver and the Apple remote.

 

Here's the how-to:

Step 1 - Connect an IR-receiver to Arduino and Arduino to PC

Step 2- Load up the IRrecvDump sketch (from IRremote library example)

Step 3 - Fire off your remote signals into the IR receiver

All this is as described in the Shirriff blog. After a while I got lost in all the codes, so I started over and took good notes this time. 

 

The key thing, of course, is to find out whether the received codes are correct. As I harvested codes, I entered them in another IR-LED equipped Arduino setup in front of the TV to see if my equipment responded as expected. Some did, some didn't.

 

I found out, for instance, that the Apple Remote “Menu” generated the following output:

Decoded NEC: 77E14060 (32 bits)

Raw (68): 11228 9100 -4350 600 -500 650 -1550 650 -1550 650 -1550 650 -450 650 -1550 650 -1550 650 -1550 650 -1550 650 -1550 650 -1600 600 -500 650 -450 650 -450 650 -450 650 -1600 650 -450 650 -1550 650 -450 650 -450 650 -500 650 -450 650 -450 650 -450 650 -500 650 -1550 650 -1550 650 -450 650 -450 650 -450 650 -500 650 -450 650

 

This means that the Apple remote behaves like a NEC remote, and that I should be able to emulate the Apple Menu order with a call like this: irsend.sendNEC(0x77E14060, 32) . When I tested this, the Apple box responded. This did indeed work. Good!.

 

I got similar seemingly valid output for the Samsung and Onkyo remotes.

 

Step 4 – Struggle with the Panasonic remote
For the Panasonic, however, I encountered problems. Here’s a summary of that saga:

 

4.1)
It turned out the IRremote library’s buffer for receiving data was too small for this remote. So, I changed 
IRremote.h to include (instead of buffer length 76)

#define RAWBUF 140 // Length of raw duration buffer

 

After the usual save - recompile - reload etc, things looked just a little better:

Unknown encoding: F7283C77 (32 bits)

Raw (100): -31814 3550 -1600 550 -350 500 -1200 500 -350 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -350 500 -350 550 -300 550 -1200 500 -350 500 -350 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -1200 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -350 500 -350 550 -300 550 -350 500 -350 500 -1200 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -1200 550 -350 500 -350 500 -1200 500 

 

I have summarized the changes I made to the IRremote library here.

 

4.2)
With the above, I could receive the raw signal. Good, but the IRremote library says "unknown" and produces a differrent encoding (the F7283C77 above) every time, so the conclusion is that this remote isn't understood by the library. That's fine - the blog has lots of information about how to add new protocols, so we’ll give that a try next.

 

4.3)

Now, I’ll add the PANASONIC protocol to the IRremote library. For starters, I must define HDR_MARK, HDR_SPACE, BIT_MARK, ONE_SPACE and ZERO_SPACE, apparently. Find out more in the Shirriff blog post.

 

I am guessing (for non-guessers, please refer to the blog) that the raw dump above has the meaning I list below. Consider this raw dump snippet...

Raw (100): -31814 3550 -1600 550 -350 500 -1200 500 -350 550 -350 500 -350 500 -350 ... and so forth

 

Raw (100): -31814  I’ll ignore that part

3550 ….. This would be the header mark, HDR_MARK … one of these at the start of the IR message

-1600 ….HDR_SPACE, maybe… a gap between header and actual message

550 ….BIT_MARK… a gap between the zeroes and ones of the actual IR message

-350 ZERO_SPACE … here’s the Zero. A number in the negative 3-400 range

500  another BIT_MARK

-1200 ….ONE_SPACE … and here’s the One. A number in the negative 1200 range

… and so forth.

 

I may be wrong, but I’ll give this a try rather than absorb everything written about it.

 

I fired off a number of IR signals from the remote, and what I think is HDR_MARK varied between 3500 and 3600, so I’ll set it to 3550. With the same method, for the rest, I ended up with

 

#define PANASONIC_HDR_MARK 3550
#define PANASONIC_HDR_SPACE 1650
#define PANASONIC_BIT_MARK 500
#define PANASONIC_ONE_SPACE 1200
#define PANASONIC_ZERO_SPACE 350

 

4.4)
The above definitions are added to the IRremote's component 
IRremoteint.h. Also, I attempted to add a sendPanasonic (), but with limited success. Instead, I found a post from a mister Wolfgang among the comments in the Shirriff blog and changed my code accordingly. His “mark” and “space” are quite similar to mine, but the code includes a couple of space(30000) which I don’t know why they are needed. I added those to my code, and things started to work as far as SEND. The “receive and decode” I have not tested. But I don’t need it, since I instead will use the RAW output to conclude what I need to send.

 

4.5)
How to go from the raw dump data to send-able information? Here's an example: The raw output for Panasonic power on/off is

Raw (100): -31814 3550 -1600 550 -350 500 -1200 500 -350 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -350 500 -350 550 -300 550 -1200 500 -350 500 -350 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -1200 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -350 500 -350 550 -300 550 -350 500 -350 500 -1200 550 -350 500 -350 500 -350 500 -350 500 -350 550 -350 500 -350 500 -1200 550 -350 500 -350 500 -1200 500

 

Remove the beginning up until the HDR_SPACE, i.e. the -1600:

…then remove everything that doesn’t have a minus in front. We're left with:

-350 -1200 -350 -350 -350 -350 -350 -350 -350 -350
-350 -350 -300 -1200 -350 -350 -350 -350 -350 -350
-350 -350 -350 -1200 -350 -350 -350 -350 -350 -350
-350 -350 -350 -300 -350 -350 -1200 -350 -350 -350
-350 -350 -350 -350 -1200 -350 -350 -1200

 

If a small negative (-350ish in this case) equals zero and a larger negative (-1200ish) equals one, the above is the same as... 

0100 0000 0000 0100 0000 0001 0000 0000 0000 1000 0000 1001
In hex, that’s  

4004 0100 0809

That's the message we're looking for! But, it;s 48 bit long and the IRremote library send calls only accept 32-bit input parameters.  One way to cure that (I’m sure there are better ways) would be to add a second in-parameter in a sendPanasonic function. Like this:

irsend.sendPanasonic(0x40040100, 0x08090000, 48);

 

So - I added such code to the IRremote library. Again, my additions may not be the most brilliant coding, but they work.  

 

4.6)
OK, now I just need to get this figured out for the other Panasonic codes I need.

You can see the end result in the sketch code.

 

Of course, if there are many orders to decode, it would be better to build and test the "receive and decode" portion for the new protocol, but in this case, it was just a few IR orders to consider, so I did it in the above tedious way.

 

 

Step 5 – Now, fix the Samsung remote

The Samsung remote isn't understood by IRremote either.  It seems to be "almost" recognized as a NEC remote, though. But, it spits out more than 32 bits, so the library needs some more changes. I’ll use the same HDR_SPACE etc as for NEC, as a first attempt. We’ll see if it works.

  

The raw dump reveals that the signal is 42 bits (but says the decoded signal is 32 bit. I’ll just ignore that).

 

For example: 

Decoded NEC: 6604CFE2 (32 bits)

Raw (88): 21916 9050 -4350 700 -500 650 -1550 700 -1500 700 -550 700 -450 700 -1550 700 -1500 700 -550 650 -500 700 -500 650 -500 700 -550 650 -500 700 -1550 650 -500 700 -550 650 -1550 700 -1500 700 -500 700 -500 700 -1550 650 -1550 700 -1500 700 -1600 650 -1550 650 -1600 700 -1500 700 -500 700 -450 700 -550 700 -1500 700 -500 700 -450 700 -1600 650 -500 700 -1550 650 -1550 650 -1600 700 -450 700 -1550 700 -1500 700 -450 650

 

This equals (with the -550ish being zero and the -1600ish being one):

0110 0110 0000 0100 1100 1111 1110 0010 0101 1101 10

In hex, that’s  

6604 CFE2 5D8

 

42 bits. So, the call from my application will be:

irsend.sendSamsung(0x6604CFE2, 0x5D800000, 42);

 

new function in IRremote.cpp (the library component) is also required:

void IRsend::sendSamsung(unsigned long data1, unsigned long data2, int nbits)

 

I basically just made a copy of sendNEC, and added a loop for sending out the extra 10 bits.

 

Step 6– Test everything

As mentioned in the earlier steps, I was using the example code IRsendDemo as a template running on an Arduino outfitted with an IR LED, I tried out all of these codes in front of my TV equipment.

After many iterations, everything works fine!

 

Step 7 - Make some software

(Actually, I of course did this programming before I soldered together my final version of the HW above, and made sure everything worked in my breadboard prototype first).

 

The sketch is included here

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值