Hacking Denon DRA-F109 remote connector (Updated 27.05.2015)

Recently I bought Denon DRA-F109 Stereo Receiver. In this post I describe how the receiver may be integrated with Raspberry Pi by using receiver’s Remote Connector, enabling to use Denon remote to control both devices. Integration covers also alarm clock built into the DRA-F109, display dimmer, sleep timer and power control, as it was native Denon system device.

Hardware setup

The device itself is only tuner with amplifier. It also has couple of external inputs (2 coaxial, 1 optical and 2 analog). The other parts F109 system are CD player (DCD-F109) and network player (DNP-F109) that are connected using coaxial inputs. The remote control bundled with DRA-F109 is an overkill for just amplifier, but you can connect all three devices if they are connected using Remote Connector cable which is 3.5 mm TRS connector.

Since I have only the receiver and use Raspberry Pi with HiFiBerry Digi as an audio player I wanted to use Denon remote to controll both. Till date I was using a generic remote with TSOP4838 IR receiver connected to Raspberry GPIO pin, then IR codes were translated into actions by lirc. This was also working with Denon remote, but was in some way limited: buttons except input selection, volume control, etc. didn’t do anything when receiver was in external input, but some of them actually did have function in tuner mode (e.g. rewind/forward buttons are used to tune radio). That was motivation to find a better solution.

Denon DRA-F109

Hacking remote connector

Remember, you may break your Raspberry or Denon receiver. Try at own risk!

At present, nobody wants to reinvent the wheel. So expected that they must have used standard bus for data transmission in Remote Connector. The initial guesses were: IR receiver (TSOP4838-like output), RS232 and I2C. I expected that bus requires two way communication for Network Player, so serial connection seemed the most possible as UART is present in most µC. First of all, I needed to determine pinout – I took the multimeter and when buttons were pressed there was voltage drop on ring of TRS plug. I took 3.3V USB-to-Serial adapter, two resistors (1.8kΩ and 3.2kΩ in my case) to make voltage divider (Denon outputs signal in 5V logic) and started to experiment. Suprisingly, it worked! The data is transmitted at standard 115.2 kbps. The next step was to connect it to Raspberry Pi UART RX pin.

Wiring diagram Wiring diagram

For now, it is enough just to receive data from the receiver – it is also the easier part to implement as it requires only voltage divider and the protocol may be reverse engineered from data we receive. Unfortuanetly, tip of the connector which is supposed to be RX of the receiver is at 5V when floating. I don’t have 5V USB-to-Serial adapter and definetly don’t want to fry my Raspberry Pi, so for now, we will keep on receiving data from DRA-F109.

Note: It is important to disable TTY and kgdb at serial port in /boot/cmdline.txt and in /etc/inittab. Otherwise your Raspberry Pi will crash (or at least will be halted by kgdb via serial).

Denon RC-1163 Remote Control

The protocol

The next challenge was to decode the incoming data. Stream is organized in packets. The packet format is BRK 0xff 0x55 [payload length] 0x00 0x00 [id] [destination] [payload] [checksum]. Sometimes, but not always there is one or two more bytes sent by amp, but they don't seem to be important – possibly it is some kind of padding. BRK stands for serial port break condition, by default it is represented as 0x00 on POSIX systems. The last byte is simple checksum: sum of all bytes but checksum itsef modulo 256. Strangely, it is not always present. Specifically, I observe that when checksum value should be 0x19 it is not transmitted. This is definitely sth that may be reproduced e.g. with SITUNER message or with specific radio station name. The reason is unknown, but it prevents from effectively implementing checksum verification as we don’t know whether we will get it. Fortuanetly, in practice it is not a big deal. I also noticed that header is sometimes wrong (e.g. 0x00 0x00 0x55 or even 0x00 0x00 0x00), but it happens rarely.

Denon AVR serial protocol

The receiver implements two message formats. If the id is set to 0x80 and destination is 0x00 then payload follows the Denon AVR serial protocol present in Home Theater receivers in form of standard RS232 port and it has official documentation. Commands are ASCII with trailing \r. DRA-F109 implements a small subset of the protocol as it is only stereo amp, but still any documentation is better than nothing. Till now I identified the following commands (in regular expression notation), the list for sure lacks DAB+ messages as I don't have DAB+ broadcast at my place yet:

I don’t have DNP-F109 player to see what are possibilities for controling the receiver. Probalby, the same packet format will work for controlling the receiver.

Binary protocol

For the other packets, payload length is usually 1. If three bytes are given below in this section consider it as [id] [destination] [payload].

Source and function selection

When function selection button in pressed on the remote the receiver sends:

These are to turn on the device:

It also sends when source is changed (also by mechanical button on the receiver) – these are less interesting, as the same data is also sent using AVR protocol:

Control of input devices

Depending on selected source the destination field is:

The payload is always 0x00. The button presses are mapped to ids as follows:

For example, packet of BRK/0x00 0xff 0x55 0x01 0x00 0x00 0x32 0x26 0x00 0xad (checksum omited) means Play/pause Network Player.

Special functions

The dimmer function sends 0x43 0x00 [brightness] where brightness may be 0, 1, 2 or 3 which means bright, dim, dark, display off respectively.

The receiver also sends the following commands:

What is missing?

The receiver does not send anything if Add, Call, Search and Network Setup buttons are pressed on the remote. These buttons are used exclusively by network player. TSOP receiver is still needed at Raspberry Pi to handle these buttons. Unfortuanetly, it seems to have a little worse reception than receiver one.

The code

The ruby code is available under MIT license at GitHub repository. The demo.rb is example of receiving data from Denon – it is not Rasbperry Pi specific. The repository includes my setup that is described in second post

Update: 22.07.2014

Receiver also sends button codes for analog and optical input. That means it is possible to control e.g. CD player or Raspberry Pi connected via analog input. Nice!

Update: 07.01.2015

I’ve finally tried transmitting data to Denon. The tip of the connector indeed is RX pin for Denon. The data transmitted to it is also echoed back on TX (I suspect that it is done by simple circuit, not uC, as it works with any baud rate). I also discovered that the extra byte of data is actually simple checksum, but it is not always present. Unfortuanetly, amp does not respond to commands that it sends. I suspect that there needs to be flag in header that marks the messages sent to amp. I don’t think that any progress can be made without access to original network player.

Update: 27.05.2015

@Slawa got hold of an osciloscope and found that initial 0x00 byte recieved from denon is not actually 0x00, but serial port break condition. I updated the post to include that information.

comments powered by Disqus