Building and Running WSJT-X on Raspberry Pi

Matt Roberts - matt-at-kk5jy-dot-net

Published: 2018-12-09

Updated: 2023-04-24


Raspberry Pi 3B+ Recent versions of the Raspberry Pi single-board computers have enough CPU power to run various digimodes, including many offered by Fldigi.  I recently wrote an article explaining how to build that package on current generation RasPis, but there are other radio software applications compatible with the RasPi.  In particular, the WSJT-X software can be used with the RasPi, which can be handy for operations that are running with limited power, or where the radio is controlled remotely.

As with fldigi, packages for WSJT-X on many OS platforms are either non-existent, or far behind the current releases.  As a result, being able to build current versions of WSJT-X can be very helpful for RasPi users.  This is a step-by-step guide on how to do this.

Recent releases of the WSJT-X on the official website include ready-made packages for Raspberry Pi OS.  For some users, this may be a better option than building from source.  I have not tried any of the installers from the WSJT-X website, but their team are trying to make it easier for RasPi users to install the software more easiliy.

If you really want to build WSJT-X from source, either on a RasPi or other Linux system, read on... ;-)

These steps should work with little or no modification on other RasPi distributions.  I have even used them for Ubuntu and Linux Mint, so they should work on most Linux distributions.  If there are differences, they will most likely be small changes in package names for prerequisites.

As of the the Version 2.x series of WSJT-X, the software is dependent on the modified version of hamlib included with the source tarball.  Because of this, the instructions below assume that you want to build against this version of hamlib, and not the stock version installed on your system.  While it is possible to build against your system's hamlib, I would not recommend this for newer releases.  If you want to run WSJT-X against your system's native hamlib, the best way to do this is to configure WSJT-X to connect to your system's native rigctld.

As of the most recent update to this article, the latest version of WSJT-X is 2.6.1.  These instructions have been tested for that version.  They should work for any of the recent versions of the software.

I still recommend 2.1.2 for RasPi users.  The reason is that after version 2.1.2, the FT8 decoder is much slower, even in Fast mode.  As a result, even the RasPi4 is unable to finish decodes on a busy channel before the next time slot begins.


The Basics

This guide assumes that you have a Raspberry Pi 3, running a recent version of the Raspberry Pi OS, and that you have already completed the installation process.  It also assumes that you have the graphical desktop running, which you will need to display the WSJT-X GUI.  To build WSJT-X, you will need the build-essential meta-package installed, but this is the default for recent versions of Raspberry Pi OS.


Getting the Source

The WSJT-X website has links to download the current source package.  The source file to download is:
wsjtx-2.5.4.tgz
Place the file in your home directory on the RasPi, which is probably /home/pi.

The development of WSJT-X is still active, so the newest versions may be higher than those shown here.  If you use a newer version, don't forget to use the newer version number in each of the steps below.


Preparing for the Build

One step that I like to perform before building software on Linux is to set some compiler optimization flags, so that the compiled code will be the most efficient for the RasPi.  In recent versions of Raspberry Pi OS, you can set the flags to select the best values automatically at runtime.  To do this, run these commands in the terminal before proceeding:
export CXXFLAGS='-O2 -march=native -mtune=native'
export CFLAGS='-O2 -march=native -mtune=native'
When the native architecture keyword is used, GCC will attempt to determine the best architecture flags dynamically at build time.  This prevents having to guess at the best target architecture.  This step works on PC-based and RasPi builds.

Note that the option -O2 is dash-oscar-two, not dash-zero-two.  The capital letter 'O' option tells GCC to generate optimized code whenever it can, and the number tells it how aggressive to be when finding things to optimize.  The -O2 option is considered safe on all production CPU targets, so that's what I use for my builds.


Prerequisite Packages

The build process also requires a number of additional packages to be installed on the system.  These include UI, image, and sound libraries, among others.  Most of these will be readily available from the Raspberry Pi OS repositories.  Installing the prerequisite packages should be done at a command prompt, most likely a terminal.

First we will install the needed system packages.  These are packages that are maintained by the Raspberry Pi OS team, and can be installed using apt-get.  The only requirement is that the RasPi needs to have some kind of Internet access, so it can download the packages from the Raspberry Pi OS repositories.

At a terminal prompt, run the following commands, one after another.
sudo apt-get update
sudo apt-get install -y git
sudo apt-get install -y cmake
sudo apt-get install -y automake
sudo apt-get install -y libtool
sudo apt-get install -y asciidoctor
sudo apt-get install -y asciidoc
sudo apt-get install -y gfortran
sudo apt-get install -y subversion
sudo apt-get install -y libwxgtk3.0-dev
sudo apt-get install -y libusb-dev
sudo apt-get install -y portaudio19-dev
sudo apt-get install -y libsamplerate0-dev
sudo apt-get install -y libasound2-dev
sudo apt-get install -y libao-dev
sudo apt-get install -y libfftw3-dev
sudo apt-get install -y libgsm1-dev
sudo apt-get install -y libjpeg9-dev
sudo apt-get install -y libxft-dev
sudo apt-get install -y libxinerama-dev
sudo apt-get install -y libxcursor-dev
sudo apt-get install -y libboost-all-dev
sudo apt-get install -y libqt5multimedia5
sudo apt-get install -y libqt5multimedia5-plugins
sudo apt-get install -y libqt5multimediawidgets5
sudo apt-get install -y libqt5serialport5-dev
sudo apt-get install -y libqt5svg5-dev
sudo apt-get install -y libqt5widgets5
sudo apt-get install -y libqt5sql5-sqlite
sudo apt-get install -y libqwt-qt5-dev
sudo apt-get install -y libsndfile1-dev
sudo apt-get install -y libudev-dev
sudo apt-get install -y qtmultimedia5-dev
sudo apt-get install -y texinfo
sudo apt-get install -y xsltproc
sudo apt-get install -y swig
To build WSJT-X version 2.1.0 or later, you will also need these:
sudo apt-get install -y qttools5-dev
sudo apt-get install -y qttools5-dev-tools
sudo apt-get install -y qtbase5-dev-tools
If you are building on a recent version of Ubuntu, Mint, Debian, or the Raspberry Pi OS, the libwxgtk3.0-dev package has been replaced with libwxgtk3.0-gtk3-dev, and the libjpg9-dev package has been replaced with libjpeg62-turbo-dev:
sudo apt-get install -y libwxgtk3.0-gtk3-dev
sudo apt-get install -y libjpeg62-turbo-dev
Some of these packages may already be installed on your system.  If any of these commands responds with "package is already the newest version," just skip to the next one.  Additionally, some of these packages may have other dependencies, so each command may install more than one package.  This is normal, so just sit back and watch it all install.

Not all of the above packages are required for all configurations of WSJT-X, but all of them should be safe to install, whether you use the associated features or not.


Building WSJT-X

To build WSJT-X:
tar -zxvf wsjtx-2.5.4.tgz 
mkdir build
cd build
cmake ../wsjtx-2.5.4/
make
sudo make install
That's it!  You should now be able to run the application directly:
wsjtx


Selecting a Decode Mode

Even with newer RasPi3 device, the Normal and Deep decode modes can incur significant delays on a busy channel.  This may not be a problem if you only plan to manually S&P other stations.  If you intend to run the channel, and especially if you run with Call 1st and/or Auto Seq. enabled, the deeper search modes may have too much delay to completely process all of the stations on the waterfall before your next transmission needs to start.  It might be best to start with the Fast mode (which I have found to be plenty fast on a RasPi3) and then try the deeper modes only if they are needed to find new, weak stations.


A Note on Serial Devices

Nearly all serial devices (used for radio control) on modern machines are USB-to-serial converters.  This includes radios that have a dedicated USB port for such purposes.  The serial drivers on most Linux distributions, including Raspberry Pi OS, tend to assign hot-plug USB devices to one of the /dev/ttyUSB* device nodes, and those devices are normally owned by root and the dialout group.  In order to access such devices for radio control, the user running WSJT-X needs to be a member of the dialout group.

Assuming you are logged in as the default user of pi, adding permissions to access serial devices is as simple as running:
sudo usermod -a -G dialout pi
...at a terminal prompt.  That tells Linux to add the user pi to the group dialout.  In order for that change to take effect, you need to either reboot, or logout and then login again.

In order to determine the USB port name assigned to your radio, I have found that the easiest thing is to start the machine with the USB device disconnected, then once you have logged in, connect the USB device, and then immediately run the command:
dmesg
This will produce a lot of output, but the serial port assigned to your radio should be one of the last things displayed.  For example, this is the output of dmesg when my Kenwood TS-590SG is connected:
usb 1-5: new high-speed USB device number 8 using xhci_hcd
usb 1-5: New USB device found, idVendor=0424, idProduct=2512
usb 1-5: New USB device strings: Mfr=0, Product=0, SerialNumber=0
hub 1-5:1.0: USB hub found
hub 1-5:1.0: 2 ports detected
usb 1-5.1: new full-speed USB device number 9 using xhci_hcd
usb 1-5.1: New USB device found, idVendor=08bb, idProduct=29b3
usb 1-5.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-5.1: Product: USB Audio CODEC 
usb 1-5.1: Manufacturer: Burr-Brown from TI              
usb 1-5.1: ep 0x85 - rounding interval to 64 microframes, ep desc says 80 microframes
input: Burr-Brown from TI USB Audio CODEC  as /devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.1/1-5.1:1.3/0003:08BB:29B3.0004/input/input21
hid-generic 0003:08BB:29B3.0004: input,hidraw3: USB HID v1.00 Device [Burr-Brown from TI USB Audio CODEC ] on usb-0000:00:14.0-5.1/input3
usbcore: registered new interface driver snd-usb-audio
usb 1-5.2: new full-speed USB device number 10 using xhci_hcd
usb 1-5.2: New USB device found, idVendor=10c4, idProduct=ea60
usb 1-5.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-5.2: Product: CP2102 USB to UART Bridge Controller
usb 1-5.2: Manufacturer: Silicon Labs
usb 1-5.2: SerialNumber: 05670041F5D2
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver cp210x
usbserial: USB Serial support registered for cp210x
cp210x 1-5.2:1.0: cp210x converter detected
usb 1-5.2: cp210x converter now attached to ttyUSB0
Note that the USB connection detects two devices.  One is the sound device used for digimodes, and the other is the serial device used for radio control.  The last line shows the name of the serial device, ttyUSB0.  When using this serial device in WSJT-X, the correct device name to use is /dev/ttyUSB0.

Have fun!

Copyright (C) 2018-2022 by Matt Roberts, KK5JY.
All Rights Reserved.