Skip to main content

Reverse Engineering a Serial Protocol

· 4 min read

This is an older reverse engineering project I did. I wrote about it for Rana Makerspace, and decided to make another post with more of the technical details.


I was involved in building a repeater system for my ham radio club, and this particular repeater used off-the-shelf transceivers for use in mobile applications. These radios are made for manipulating via the control panel, and there is no way to remotely control them beyond switching TX and sending and receiving audio.

In an application where the radio is placed in a remote location, such as a mountain top, you may want to change the frequency or do other disgnostics without travelling to the repeater site.

As it happens, these radios have detachable front panels, and between the main unit and the front panel there is a 6 pinned cable. Fortunately, there is also a service manual available for the unit, so the pinout of the connectors was not a secret in this scenario.

Beyond that point, however, there is no description of how the system works. As we will see, it is completely possible to work this out and describe it.

Power on/off

There is one pin for power on/off which I think is pulled high by the main unit as long as it is powered. The power button on the front panel pulls this pin to ground to signal power on. When the power switch has been active for about a second, the radio powers up the main unit and sends power to the front panel through the dedicated pin.

However, if you just do this without the front panel, the radio will quickly detect that something is not right, and power back off.

Serial communication

Between the main unit and the front panel there is TTL serial communication at 19200 bps. The service manual revealed the description and directions of the various signals, the baud rate and UART configuration was determined using an oscilloscope.

Both the main unit and the front panel send status packets many times per second, and if the main unit stops receiving these, it will power down. Presumably this is a safety precaution.

As soon as I knew the UART configuration, I connected a USB TTL serial adapter to the pin going from the front panel to the main unit and write a Python-program that let me analyze the bit stream.

The stream turned out to be static as long as no buttons were pushed. It was also possible to play back a packet like this at an appropriate rate to keep the main unit powered on without the front panel.

Next step is to figure out the format of the packet, and it was quickly revealed that it contains bits that represent all the buttons on the panel and hand mike (which is connected to the front panel). It was not long until I could simulate key presses from my Python program instead of the front panel.

In the other direction the communication is similar. The packet is longer, which makes complete sense when you realize that the bits represent the different elements in the LCD display. Mainly, there are symbols that show the status of various functions, and a block of six 12-segment digits that show the frequency or memory position tag.

Python API

When enough about the communication is known, the display symbols can be mapped to status bits. I was also able to map the character set, and create a routine that converts the state of the 12-segment digits to ASCII, which in turn could be interpreted by the rest of my code.

In a few hours I could implement a working Python API that lets you control and configure the basic functionality from code. When the ft7800 object is instantiated it powers on the radio and you can start manipulating the radio like so:

import yaesu

radio = yaesu.ft7800('/dev/cu.usbserial')


print("Auto squelch...")



It turned out that other factors, such as TX frequency stability, made the radio unstable in this particular repeater application, and we ended up using another radio.

This was nevertheless an interesting project. A lot can be learned about product design this way, and we can demonstrate to others that hardware is not always just a black box that does only what the manufacturer intended.

The code and some project notes are still available for reference on my Github.