Friday, November 6, 2009

An Arduino universal remote and more

Edit: Code here

So I have a large 7.1 surround system hooked to my computer for games and watching movies (when the 720p projector is on). This is a large external receiver, a Yamaha RXV663. It uses enough current to keep it warm even if sound isn't coming out of it. Thing is, I have been putting my computer to sleep for a few years now, but I always forget to turn the receiver off. Being lazy/forgetful like that, I ordered an extra boarduino a while ago to solve the problem. Now I'm finally putting it to use.

I scavenged a couple parts.. the 3 pin IR receiver from an old Audigy LiveDrive (those 5 1/4 drive bay things with jacks and such.. never used the crappy remote anyways) and an old IR remote which I broke in half and soldered a header on to. The IR led's seem to draw a lot of current so I put a 1000uf cap on the power rails. (they are pulsed via switching transistor)

The real workhorse here is this guys IR library:

Arc Language Blog: An Arduino universal remote: record and playback IR signals

I only had to modify an include file to make the existing NEC remote routine interpret and send Yamaha codes. I'm not sure if I did it all right, but it wasn't really important to me as long as it could send the codes I needed.
I only had to modify these values:
// pulse parameters in usec
#define NEC_HDR_MARK 8900
#define NEC_HDR_SPACE 4600
#define NEC_BIT_MARK 600
#define NEC_ONE_SPACE 600
#define NEC_ZERO_SPACE 1700
#define NEC_RPT_SPACE 2250

and simply send the code like this:
irsend.sendNEC(0x817E01FE, 32); // send turn off
irsend.sendNEC(0x817E817E, 32); // send turn on

You can see that those codes match these from the LIRC site, minus whatever prefix 817E is (could be a part of the header?) Anyways, it works great.

Now I'm off to write the other part of it, a C# app that will detect a PowerModeChanged event (documented here) and send an OFF pulse when the machine is entering standby, ON when it is waking up. I want it to leave it alone when the computer is rebooting so it doesn't needlessly cycle the relays in the amp.. it will send some info over the arduino's serial port via USB. (I thought I could get away with using DTR or something, and no app on the computer but no dice. Alternatively I could use something like the power LED on the case to signal the arduino, but I didn't want to mess with small gauge wires sticking out and getting cut on things) So I'm pretty committed to an always running c# app that will keep the arduino informed of the computers status.

With this system I can also send the other codes that have been documented on the LIRC site too, an example usage:
When I watch movies with the projector, I switch the input on the amp to be a coaxial SPDIF input and set windows to use the digital out, so that I get unmolested bitaccurate audio from whatever I'm watching.
However when I'm playing a game, I need to use the analog 7.1 sound card outputs and the multichan input on the amp.

With this power management monitoring app, maybe it could get the current default audio device and switch the amp input based on that.. all automatic! Next it will be dispensing beer into my mouth while watching movies.

Kudos to Ken for his arduino IR library!

Code for this is in the followup post here. It works great!

I am going to buy one of those tiny miniusb arduino's for this, and put it in a little box with a jack for an IR blaster.

Here is a bad picture of the prototype


  1. Hi,
    You should post here:

    That guy seems to know a lot more about it than I do, I think I may have just gotten lucky with the settings that I used.


  2. Hello. Just wanted to tell you. Im soo stealing your code to improve the waf factor on my setup. I have an old marantz reciever, a combined dvd/vcr, a chromecatst, a hdr, a wii and an external hdmi switch, witch can output digital sound to the reciever from hdmi inputs or from the tv(rac). I have tried with programmable ir remotes, but no cigar. So now instead ill glue a ir led onto every units ir eye, basically a poor mans optocoupler. Use a single output to control them. Get the multiremote to send in a code thats incompatible with my units, and build custom macros in the arduino. So like you did, just expanding the theeme a little.