Open telecommand for BY70-1

Recently, Wei BG2BHC has published instructions for the use of BY70-1’s camera by Amateurs. Essentially, there are three commands that can be used: 0x00 to take a picture and send it, 0x55 to take a picture and store it in memory, and 0xaa to send the picture stored in memory. He also gives the modulation and coding details for the commands. They use AX.25 with 1000baud FM-AFSK with tones at 1000Hz and 1833.33Hz. The AX.25 frames are UI frames containing a single byte with the command (0x00, 0x55 or 0xaa as described above). For ease of use, he also gives WAV recordings of the three commands, so they can be played back easily into an FM transmitter by any Amateur. Here I look at the contents of these WAV files and how to process and create this kind of packets.

The first thing to note is that there seems to be some problem with the header of the WAV files produced Wei. They are 48kHz WAV files containing uint8_t samples. However, several tools such as Audacity refuse to open the files. Others, such as mpv work. You can use sox to fix the WAV header:

tail -c +45 open_cam_cmd_00.wav | sox -t u8 -r 48000 -c 1 - -t wav open_cam_cmd_00_fixed.wav

The tail command here is used to skip the WAV header, which is 44 bytes long. It is no big deal if you omit tail. The WAV header will be interpreted as sound samples, but this doesn’t really disturb anything.

The modulation and coding used by the commands is very similar to the standard 1k2 Amateur packet radio. The only differences are that the baudrate is 1000baud instead of 1200baud and the AFSK tones are 1000Hz and 1833.33Hz instead of the standard 1200Hz and 2200Hz. One of my favourite tools for packet radio is direwolf. It is an open source modem with a superb decoder and many other functionalities, such as APRS and digipeater.

We will use the following configuration file for direwolf:

ARATE 48000
MODEM 1000 1000 1833 ABC

The ARATE sets the audio rate to 48kHz, matching the rate of the WAV files. The MODEM line declares a 1000baud modem using tones at 1000Hz and 1833Hz with three different decoding algorithms (A, B and C) running in parallel.

We can play the WAV files into direwolf to decode them. For simplicity, I omit the tail command to skip the header. Note that I use the configuration above (I’ve called it by701.conf).

sox -t u8 -r 48000 -c 1 open_cam_cmd_00.wav -t s16 - | direwolf -c by701.conf -d p -

This produces the following output.

BG2BHC-9 audio level = 180(184/184)   [NONE]   |||
Audio input level is too high.  Reduce so most stations are around 50.
[0.1] BG2BHC-9>BJ1SI-5:
U frame UI: p/f=0, No layer 3 protocol implemented., length = 17
 dest    BJ1SI   5 c/r=0 res=3 last=0
 source  BG2BHC  9 c/r=0 res=3 last=1
  000:  84 94 62 a6 92 40 6a 84 8e 64 84 90 86 73 03 f0  ..b..@j..d...s..
  010:  00                                               .
Unknown message type , normal car (side view)

We can see that the packet is an UI frame from BG2BHC-9 to BJ1SI-5 and the content is the byte 0x00. The other WAV files have similar frames with their contents varying accordingly.

We can also use direwolf to transmit our own packets. This has the advantage that we can replace BG2BHC’s callsign with our own callsign. This is not only cool but it is also better to comply with regulations regarding identification of the transmissions. The only important thing when commanding BY70-1 is that the frames are addressed to BJ1SI-5 (the source doesn’t matter) and that the contents of the UI frames are a single byte with the corresponding command. To this end, we include the following lines in our direwolf configuration:


These set a preamble of 600ms and a postamble of 1200ms. I don’t claim that these values are optimal. It is what is used in the WAV files. These parameters probably allow for some experimentation. In particular, it is usually not important that the postamble is long, and a short postamble will usually do the job fine. However, a long preamble can help the receiver get a lock on the signal.

There are many ways to generate the AX.25 frames that we want to transmit. A simple way is to use the following Python script. It generates a UI frame with the specified source and destination callsigns and content and writes it to the standard output in KISS format. The output can be sent to direwolf to make it transmit the packet.

We run direwolf as

direwolf -c by701.conf -p

and then we can send a packet with the command 0x00 in the following way:

./ BJ1SI-5 N0CALL 00 > /tmp/kisstnc

With the same instance of direwolf running, the script can be run as many times as necessary to send several packets.

Direwolf also supports several methods to control the PTT, so probably you also want to include some form of PTT control in your configuration. For instance, I use

PTT RIG 2 localhost:4532

to control the PTT of my radio via CAT using rigctld.

The Python script above can also be useful in other situations where you need to generate AX.25 UI frames. You can specify several bytes of content in hex. For instance, this command

./ CQ EA4GPZ "68 65 6c 6c 6f 20 77 6f 72 6c 64" > /tmp/kisstnc

sends the following packet:

[0.1] EA4GPZ>CQ:hello world
U frame UI: p/f=0, No layer 3 protocol implemented., length = 27
 dest    CQ      0 c/r=0 res=3 last=0
 source  EA4GPZ  0 c/r=0 res=3 last=1
  000:  86 a2 40 40 40 40 60 8a 82 68 8e a0 b4 61 03 f0  ..@@@@`..h...a..
  010:  68 65 6c 6c 6f 20 77 6f 72 6c 64                 hello world


Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.