Jonas Schäfer

Remotely controlling a Denon AVR-1910 from Linux

The Denon AVR-1910 is, by current standards, an ancient device. It does not have ethernet. It does not have wifi. There are no apps to control it. Only an old-school infrared remote control. As ours lives in a closed cabinet, the infrared remote control unit isn't even usable. The signals do not reach the receiver.

This is compensated somewhat by being able to control volume and number of audio channels via the network through PulseAudio on the Raspberry Pi, which is the main source of signals for the Denon. However, generally it is preferable to control the volume through the last segment of an audio processing chain, if possible, to get the best quality possible. In addition, when it comes to how stereo signals are upmixed to the 5.1 output, there are various options available in the Denon (and no sensible option in PulseAudio) and they do not apply to any situation equally.

Hence, it would be nice to be able to control the device remotely.

Available remote control interfaces

There are three options:

  1. HDMI Consumer Electronics Control (HDMI-CEC) allows devices in an HDMI "tree" (with a TV or similar device usually being the root of the tree) to exchange commands. This can be a TV forwarding remote control codes to upstream devices (such as DVD players) or a playback device which wakes up the TV or asks it to switch source.
  2. Hack the port on the Denon which is curiously labelled "Room-to-room remote control in".
  3. Use an IR blaster to inject infrared remote control signals right into the photodiode the Denon uses to receive signals from the physical IR remote control unit.

Option 1: HDMI-CEC

Option one would obviously be the most modern. I ran a few tests using the Pi and they were mostly successful: I was able to control volume and power status via HDMI-CEC. However, this comes with a nasty downside: The receiver, when the HDMI-CEC endpoint is enabled via the menu, will not turn off the auxiliary power output. That means that as long as the AVR has power, even if it is just in standby, the subwoofer connected to the aux out is fully powered. That is a huge waste of power. The subwoofer does have an auto standby mode, but I found that this is unreliable during quiet pieces of music or tracks with sections of low bass, effectively removing the lows.

So with HDMI-CEC not being a viable option. I briefly considered getting a switched power outlet and control that via the Pi to then control the Denon via HDMI-CEC, but a research did not reveal any device which doesn't depend on wifi working and being available. That I consider annoying, because the A/V cabinet is otherwise mostly autonomous from the access point (being connected via ethernet to other devices and thus able to survive even while the access point is down).

The other approach for switching power to the Denon would be something home brew, but I'd really not like to mess with mains voltage.

Option 2: Room-to-Room Remote Control In

This is a peculiar feature of the Denon, and massively underdocumented. In the manual, it ominously refers to "room-to-room functionality", without giving any concrete example on how you would connect it to anything. It is not described what kind of protocol is spoken there.

Luckily, it is possible to find a service manual for the Denon AVR-1910 in the internet, with complete parts lists, schematics and PCB layouts. I'll not bore you with the details of other people's schematics. The gist is, after some AC coupling, the RC in is fed into a Sony CXA1511L IR demodulator IC. This takes a remote control signal modulated with 38 kHz (just like the hardware remote) and outputs it on some pin which is then, presumably, fed into some IC deeper inside the AVR.

This is actually pretty neat. It would allow connecting, for instance, the Raspberry Pi and somehow generating that signal to inject remote control commands. The downside is that even after studying the schematics in detail, I'm not convinced that connecting GND and a signal from the Pi would not potentially cause havoc to either device or the audio quality. Pis are not exactly known for being low-noise and audio equipment tends to be finnicky about that.

That led me to wonder whether there would be a way to somehow electrically insulate this and couple the signal into the Denon optically...

Option 3: Infrared Blaster

... when I realized that there is a very standard way to do so: Just tape an IR emitter diode in front of the IR photodiode of the Denon and make it emit whatever I need it to.

This is clearly the safest option. It would also be very reliable if the diode is placed in close proximity and fed with sufficient power. It does not require electrically coupling two pieces of hardware which may never have been meant to be connected.

So this is, finally, the way I'll go.

How to generate the signals? And what signals even?

Now that we know how to feed control signals, we need to figure out what signals to feed. And how to generate them.

Infrared remotes work by modulating a "slow" signal on top of a carrier square wave, typically between 35 kHz and 42 kHz. In case of the Denon, it is 38 kHz (or compatible to that, anyway). That means a signal looks roughly like this:

Demodulated signal:

     ______________________________________           _____________
____|                                      |_________|             |_______

Modulated signal:

     _   _   _   _   _   _   _   _   _   _            _   _   _   _
____| |_| |_| |_| |_| |_| |_| |_| |_| |_| |__________| |_| |_| |_| |_______

With a 38 kHz carrier, each low-high cycle of the modulated signal is 26.316us long.

The modulated signal is then used to drive an infared light-emitting diode. Those are easily fast enough to work with a 38 kHz signal, so that's not a problem. The light travels through space toward the photodiode in the receiving device, where there's typically a bandpass selecting for the carrier (to exclude any non-signal noise, for instance heat or sunlight). Then the carrier is demodulated back into the original signal. The bandpass and other filtering will typically include a delay, which is why most IR protocols would avoid too short bursts, because those may be missed.

Now that we know how the signal would be modulated, we'd have to learn what to modulate. This is more tricky, because it is also often underdocumented. Luckily, there is the IRMP (Infrared-Multiprotocol-Decoder) project with excellent documentation on many different infrared remote protocols, including the one used by Denon.

The Denon protocol encodes a binary zero with a 310us burst, followed by 745us of pause. A binary one is encoded by a 310us burst and a 1780us pause. The signal is terminated by a 310us pulse without defined pause afterward (i.e. a pause much longer than 1780us; the stop bit). That way, 15 bits are encoded which make up the complete IR command.

Now we know how bits are encoded, but we don't know which bits to encode.

There are two ways to find that out: One option is to search the internet for documentation on the specific IR commands used by Denon. The other option is to teach lircd (Linux Infrared Remote Control Daemon) to understand the encoding, point a remote at a photodiode at a lircd-compatible device and let it learn the commands.

In fact, surprisingly, in this case both options actually work. It is possible to find the IR command set for the AVR-3803, which is not model I have, but which (un-?)surprisingly uses much of the same IR commands.

Getting Infrared Signals In and Out of a Raspberry Pi

The Raspberry Pi comes with pre-made configuration which can be used to read demodulated IR signals from any arbitrary GPIO. Likewise, it can generate modulated IR signals on arbitrary GPIOs. This is achieved by bit-banging, which is CPU intensive and in general ugly. Nontheless, let us briefly talk about this option just in case you're not as interested in hardware and microcontrollers as I am.

  • The gpio-ir device tree overlay can be used to turn any GPIO pin into an IR receiver (provided you feed it demodulated IR signals)
  • The gpio-ir-tx device tree overlay can be used turn any GPIO pin into an IR transmitter (emitting modulated IR signals)

You can read more about using the ready-made device tree overlays with lircd. But this is not the road I'll go down.

Along all the way of research, I came up with the idea of not ditching the remote control unit altogether, but instead making it usable by placing an IR receiver diode somewhere and forwarding that signal to the Denon, too. I would like to be able to control the Pi (or rather, software running on it) using the many spare buttons on the remote control, while simultaneously using it to control the Denon, all from a single IR receiver.

To implement this on the Pi requires one of two things:

  • A realtime thing listening on the events from /dev/lirc0, replaying them immediately. This has no latency, but I am fairly certain that a /dev/lirc0 only supports a single reader at a time, which would mean that this requires messing with lircd to do what we want.
  • Let lircd interpret the signals, listen for key events from lircd and then make it send them again through the photodiode. This is totally possible; lircd does, in fact, support sending. However, here the problem becomes latency: lircd has to wait for the full key sequence to be received, which can take between 10 ms and 100 ms depending on the remote signal coding. That is a noticeable latency which can get annoying when doing things like volume control.

I don't like either of those options.

I do happen to have an ATtiny2313a 8-bit microcontroller in stock though. Those happen to have timers. And pin change interrupts. And a USART. And a PWM output which can be used to generate an 38 kHz carrier signal.

In the next post (Designing an Infrared Forwarder/Sniffer/Injector Microcontroller Firmware), we'll go into the nitty gritty details of what a microcontroller needs to do to achieve this goal. If you're not into making your own hardware things, I'd highly recommend to go back to that post about using the ready-made device tree overlays with lircd; it should get you a long way.