htmi2serial_smallWARNING: The following is dodgy, and if you try it and blow up your receiver, HDMI port, or whatever, you should remember that the internetz are full of dodgy advice, and don’t come crying.

I’m looking to automate turning on my HTPC, AV receiver and TV. The current setup involves three remotes and, while it works, is rather less than ideal. There are a great many buttons, most of which I’ve never used.  I’ll explain the master plan in another post, but the gist of it is to use LIRC and a Microsoft MCE IR blaster to send IR codes to the TV and receiver.

Anyway, the first step is to capture all the keys from the remote into a form LIRC using irrecord. This utility makes it all quite simple and generates a LIRC config file for the particular remote.

However, the remotes I have only have a toggle button for switching power on to the TV and AV receiver. Ie sending the IR code once turns on the device, sending it again turns off the device. This presents a problem when automating stuff. Without feedback, it’s not possible to know if sending the toggle code turned the device on or off. If something (temporarily) obstructs the IR beam, then you could end up with a situation of turning the TV off and turning the receiver on, and so on.

Luckily most (some) TVs and receivers support IR codes to “power on” and to “power off”. These are called discrete codes. Sending the “power on” code multiple times has no effect once the device has powered up. I went digging around on the internetz and turned up this. It was then a simple matter of running the relavent codes through pronto2lirc then irrecord -a and I had a working LIRC configuration for my TV (Panasonic Viera).

My Yamaha receiver proved to be not quite so simple. Yamaha don’t seem quite so forthcoming with their IR codes. Never the less, internet peeps have published some Yamaha codes. However the discrete power on and power off codes I found turned on both zones of my receiver, which I didn’t really want.

So I thought I’ll just hack up some python to run through a list of IR codes and blat them at the receiver. Eventually one will turn it on, and I’ll have found it. However 16bits corresponds to 65536 possible codes, and at one per second that’s going to take 18ish hours, and I’d get a bit bored sitting in front of the receiver for that long.

If only there was a way to signal to the PC that the receiver has powered up. Looking on the back of the reciever there was roughly 1 million connectors as is the way with receivers, including some fancy Yamaha to iProduct connector.

The HDMI out connector attracted my attention. HDMI has a 5v line that gets energised when the receiver powers up (pinout here). Now all I needed was  a way to monitor it from the PC. A serial port seemed like the simplest solution. The RS232 specification says that +3v to +15v is a logic 0, and -3v to -15v is a logic 1, and -3v to 3v as undefined, but in reality most RS232 receivers return 0v as logic 1 (dodgy I know). By cutting the end off a cheap HDMI cable and wiring the HDMI +5v (pin 18) to the RS232 CTS line (DB9 pin 8), and HDMI ground (pin 17) to the RS232 ground line (DB9 pin 5), I’d made myself a wonderful new HDMI to RS232 cable.

Rather than risk blowing my receiver up, I tested the cable on a cheap video card. Realterm (Windows) or statserial (Linux) are handy utilities for checking line states.

Once I was satisfied that the cable was working, and the video card hadn’t blown up, it was time to go IR code hunting.

The first step was to generate an lircd remote configuration file containing all 65536 IR codes for the range I wanted to test. There were 3 ranges that the codes captured from irrecord appeared in: 0x5EA10000, 0x7E810000, and 0xFE800000. So it was necessary to repeat the process below 3 times (once for each offset).

First set the offset (high order 16bits) in makeir.py:

offset=0x5EA10000

Then generate the 65536 codes for that range:

python makeir.py > /home/nobbin/InfraRed/testcodes_5ea1.lircd

Next, tell lircd about this remote in its configuration file (usually /etc/lirc/lircd.conf):

include "/home/nobbin/InfraRed/testcodes_5ea1.lircd"

And then send each IR code via the blaster to the receiver (see sendir.py):

python sendir.py 0000 10000 /dev/ttyUSB0

If the receiver turns on, the script will halt, and I can note down the relavent IR code:

CTS change detected at TEST7E81

So what did I find? It turns out that any of the four “scene” keys will turn on the receiver, before switching to the appropriate input. Then I discovered two codes to enter the self test mode. Then finally I found the zone 2 and main zone power on codes.

In the 0x5EA10000 range:

  • TEST00FE corresponding to SCENE1 (BD/DVD) turned the receiver on, and switched to BD/DVD scene
  • TEST609E corresponding to SCENE3 (CD) turned the receiver on, and switched to CD scene
  • TEST906E corresponding to SCENE4 (RADIO) turned the receiver on, and switched to RADIO scene
  • TEST1B847 turned on all zones on the receiver
  • TESTC03E corresponding to SCENE2 (TV) turned the receiver on, and switched to TV scene
  • TEST1FB04 put the receiver into self test mode
  • TEST1FB84 put the receiver into self test mode

In the 0x7E810000 range:

  • TEST5DA2 turned on zone 2 of the receiver
  • TEST7E81 turned on the main zone of the receiver

This was what I was after, but now I needed the power off codes, and sending lots of codes to a powered up receiver could change any number of settings, so I needed a different approach. Luckily during the time spent waiting, I found the codes I was looking for, but in Yamaha/NEC format.

Note: It turns out the RX-V767 has a trigger output that outputs 12v when receiver turns on. This could be used instead of the HDMI 5v line.