You are on page 1of 3

22-Jan-2009

Notes on the Yamaha RS-232 Protocol


The same protocol is used for at least the following models (and maybe some earlier ones too): RX-V1700
(same as HTR-6090), RX-V1800 (HTR-6190), RX-V1900 (HTR-6290), RX-V2700 and RX-V3800. Note
that a completely different protocol is used for the RX-V3900, RX-Z7 and RX-Z11.

The Yamaha documents describing the protocol are:


• RX-Vx700_RS232C_Standard.pdf This is the most useful document, and almost all it
also applies to the other models.
• RX-Vx700_RS232C_Extended.pdf Documents the more complex commands.
• RX-Vx800_RS232C_Standard.pdf A partial document which only documents the
1800/3800 Configuration command.
• RX-Vx800_RS232C_Extended.pdf Useful for a few items new to the 1800/3800.

The basics are described in RX-Vx700_RS232C_Standard.pdf. All commands and their replies are made
up of printable ASCII strings, except for the initial STX (ASCII code 2) and terminating ETX (code 3). For
example, if a command is listed as 07E7E, it must be sent as the ASCII string “07E7E”, not as the five
bytes that make up the hexadecimal number 0x07E7E.

It’s important to realize that the receiver not only sends replies to commands from the host, it may also
issue unsolicited playback status reports whenever its internal status changes (e.g. when the volume is
turned up or down via the remote control or the main volume knob). Some applications can ignore these
status reports, but others rely on them. For example, the VolumeControl application does not initiate
communication, it just waits for volume changed status reports and then acts on them.

The VolumeControl and PEQedit applications were written with VB .NET 2008, and I assume they can
easily be ported to C#. All RS-232 communication uses the .NET SerialPort control.

Synchronous Model
An application like PEQedit waits for user input through its GUI before sending a command to the
receiver, and immediately after sending each command it reads the serial port synchronously to wait for the
associated reply. In this type of application, extra playback status reports are unwanted and can get in the
way. When reading a string from the serial port you need to make sure the string you just read was actually
the reply that you expected.

Asynchronous Model
An application that needs to monitor the current state of the receiver should use an asynchronous model and
listen for playback status reports (this is the way VolumeControl works). It uses the SerialPort
DataReceived event to read and buffer characters as they arrive, and when it sees the ETX character it
knows that a complete report has been received.

Many different reports are possible, and not all are relevant. So the event handler function just looks for the
reports it needs to, and ignores the rest. The relevant part of the code is shown below.

For debugging, PortMon can be very useful. This is a free download from Microsoft that lets you monitor
all serial port activity. You can also use VolumeControl with the /debug switch to display all the bytes it’s
receiving (see http://www.avsforum.com/avs-vb/showthread.php?p=14748684#post14748684), but you
won’t be able to run VolumeControl at the same time as another application that opens the serial port.

1
22-Jan-2009

SerialPort DataReceived Event Handler


Dim Report(1000) As Byte
Dim ReportSize As Integer = 0

Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As


System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim NumBytes, HexVolume, Value As Integer
Dim Val As Byte
Dim Ch As Char
Dim Volume As Double

NumBytes = SerialPort1.BytesToRead ' The number of bytes currently received

For I = 1 To NumBytes
Val = SerialPort1.ReadByte()
Ch = Chr(Val)

If Val = 2 Or Val = &H11 Or Val = &H12 Or Val = &H14 Then 'STX, DC1, DC2 or DC4
Report(0) = Val
ReportSize = 1 ' Start of a new report
Else
Report(ReportSize) = Val
ReportSize = ReportSize + 1 ' Continuation of the current report
End If

If Val = 3 Then ' ETX (complete report now received)

' Check for a volume changed playback status report


If Report(0) = 2 And Report(2) = Asc("0") And Report(3) = Asc("2") And
Report(4) = Asc("6") Then
If Report(5) < Asc("A") Then
HexVolume = (Report(5) - Asc("0")) * 16
Else
HexVolume = (Report(5) - Asc("A") + 10) * 16
End If
If Report(6) < Asc("A") Then
HexVolume = HexVolume + Report(6) - Asc("0")
Else
HexVolume = HexVolume + Report(6) - Asc("A") + 10
End If

Volume = (HexVolume - &H27) / 2 - 80.0 ' Convert to dB


'
' GUI can be updated here with the new volume
'
End If

' Check for a "Volume report as text" report


If Report(0) = &H11 And Report(1) = Asc("0") And Report(2) = Asc("1") Then
Volume = (Report(5) - Asc("0")) * 10 + (Report(6) - Asc("0")) +
(Report(8) - Asc("0")) / 10
If Report(4) = Asc("-") Then
Volume = -Volume
End If
'
' GUI can be updated here with the new volume
'
End If

'
' Add other cases here to handle different reports (signal type, etc.)
'

End If
Next
End Sub

2
22-Jan-2009

Note that the volume may be reported in two different ways. The first case applies when the user changes
volume using the receiver’s remote control or volume knob. The second case applies when your application
explicitly requested a volume report by sending the “main volume text request” command (“22001”). The
latter case is useful when you need to force a volume report at the start of your application. The two
methods return the volume in different formats, and the above event handler recognizes both of them.

As soon as a new volume value has been received you might want to update your application’s GUI, but
remember that the serial port event handler is running in a different thread and you have to be careful to
synchronize things if your main application thread may also be updating the GUI.

Initialization Commands
It can be useful to automatically turn on the receiver when required. You also need to set a few other
things, such as making sure command reports are enabled. The typical initialization sequence is (neglecting
error checking):

SerialPort1.Open()

SendCommand("20000") ' Enable command reports


SendCommand("20100") ' Set report command delay to 0ms (use 50ms for the Vx700)
SendCommand("07E7E") ' Main power ON
SendCommand("07E7E") ' (must be sent twice in quick succession)

The function SendCommand() is defined as:

Sub SendCommand(ByVal Command As String)


If SerialPort1.IsOpen Then
SerialPort1.Write(Chr(2) & Command & Chr(3))
End If
End Sub

The above command sequence will generate several reports from the receiver, including the long
Configuration command which is almost 200 bytes. When synchronously reading back a single report from
the receiver, just read everything up to the next ETX character like this,

Function ReadReport() As String


Dim Report As String

If SerialPort1.IsOpen Then
Report = SerialPort1.ReadTo(Chr(3)) ' commands all end in ETX
Else
Report = Chr(3)
End If
Return Report
End Function

Remember that the receiver can generate extra playback status reports, so check the contents of the report
string carefully to make sure it’s the one you expected and not something else. If necessary read the next
report until you find the one you want.

The Yamaha documents describe the type of cable required (a null modem with some wires crossed), and
the RS-232 settings (9600 baud, 8 data bits, no parity, 1 stop bit, hardware handshaking).

You might also like