Enhancing Digital modes with Node Red

For a couple of weeks now I’ve been playing with Node Red to add functionality to my digital mode applications.

To get to know how it all works I initially used Node Red to create a series of dash boards for my servers and virtual machines to show realtime information on CPU temperature, CPU load, memory usage and storage etc.

Node Red Flow to collect information from a virtual machine (VM)

This worked very well and I was soon able to generate the information I needed in a palatable format. This was a great way to get to know Node Red flow building and introduced me to using gauge and graph nodes in flows.

The resultant Node Red Dashboard for one of my Virtual Machines

Once I had mastered creating dashboards for servers/virtual machines (VMs) I then started to investigate using Node Red to plot data from WSJT-X on a map.

I currently use the PSKReporter website to see stations that I hear on a map as WSJT-X sends the data to the site automatically however, this information is always 5mins or more old. For some time I’ve been wanting to see the information realtime as it is received and so I was hoping to be able to achieve this via Node Red.

Node Red has nodes available for a multitude of applications all easily installed via the Manage Palette menu in the flow editor.

I installed the WSJT-X Decode and World-Map nodes and set about building a flow to capture the data and plot it on a world map.

Building a Node Red Flow to decode WSJT-X data and plot it on a World Map

Putting the building blocks of the flow together is fairly straight forward and easily achieved using the excellent flow editor built into Node Red.

I configured WSJT-X to make the decode data available via UDP on port 2237 and then started the flow by creating a UDP node that connects to WSJT-X using the same port. The data immediately started flowing and I could see the information via a debug node.

I can’t stress enough how useful debug nodes are in Node Red. You can add debug nodes onto any output on any other node to capture the data as it flows. This gives you the ability to check what you’re getting is what you expected and also to see the format the data is in. The debug data is displayed in the debug panel on the right of the flow editor in realtime and gives you a great view of what is going on in your flow.

I decided to start with capturing the data for stations calling CQ as this was easily identifiable in the JSON object coming out from WSJT-X.

Passing the output from the WSJT-X-Decode node into a switch node I added a rule that filtered out data containing “type: “cq” and passed it onto the next switch node that created a payload consisting of the station callsign, maidenhead grid square and type so that it could be passed onto the next node for processing.

The next node in the flow is a function, this is where it gets a bit tricky. To be able to plot data on the map we need the Lat/Lon coordinates of the station making the CQ call. Since WSJT-X uses maidenhead locator data I needed to convert this to Lat/Lon coordinates before passing the data to the map node to be plotted.

Since Node Red is written in Java all the functions have to be written in javascript. The problem here is that I am not a javascript programmer and so this meant I’d need to learn yet another programming language. Unfortunately Node Red doesn’t allow functions to be written in C, Rust, Go or Python, all languages that I know well and after retiring from over 40 years in the UNIX/Linux/IT world my enthusiasm for learning yet another programming language has wained somewhat.

Being so close to having a working solution I pressed on and after much head scratching I finally put together some javascript that converts the maidenhead locator information in to good old fashioned Lat/Lon coordinates. I’m sure a seasoned Javascript developer wouldn’t be impressed with my code but, it works and does what I need and so I’m happy with it for the time being.

WSJT-X FT8 stations calling CQ on the 60m Band plotted on a Node Red World Map

Once I had the location information converted it was just a matter of passing the data to the world map node in the correct format for it to be plotted realtime.

As you can see on the screenshot of the map above, it worked extremely well with stations popping up as they were decoded by WSJT-X.

I now need to refine the data sent to the map so that it shows the frequency the station is calling on, the time they made the CQ call and the mode (FT8/FT4 etc) being used.. I would also like to add the distance from my QTH to the station calling CQ to round the information off however, this will mean writing another javascript function which, I’m not sure I want to dive into just yet.

I also need to add into the mix stations that aren’t calling CQ but, who’s callsign and grid square are passed on from WSJT-X. This will mean I will then be able to add to the map those stations that are actively working other stations and maybe I might even be able to show a line between the two stations that are in QSO.

This has been a fun but, steep learning curve however, it will certainly add some great functionality into my radio room and enhance my radio HAM addiction even further.

More soon …

Funcube Dongle Pro+ / GQRX / Kubuntu

Many years ago I purchased a Funcube Dongle Pro+ (FCD) SDR. Since it’s arrival it has just been stored in my “Get round too it” drawer.

It’s been many years but, today is the day it comes out into the light and finally gets powered up.

Funcube Dongle Pro+ USB SDR

I’m hoping to be able to use the FCD as the receiver in my QO-100 satellite ground station setup.

The output from the 10Ghz dish mounted LNB is around 739Mhz, well within the FCD receiver range of 150khz to 2Ghz. This will save me from having to transvert from 739Mhz to 430Mhz (70cm band) on the receive path.

This will also give me full duplex operation as I will use my Icom IC-705 on the 2m band (144-146Mhz) to drive the 2.4Ghz transverter for the satellite uplink whilst listening to my own signal via the 10Ghz downlink fed into the FCD.

Before I can even start to build the QO-100 satellite ground station I need to get to grips with the FCD, get the software installed, configured, resolve audio routing via virtual audio cables and get it decoding FT8/JS8/WSPR etc.

Talking to G0DUB in the General Amateur Radio Chat room on Matrix he recommended trying the GQRX software to drive the FCD. GQRX is open source which fits perfectly as I want to control the FCD from my Kubuntu PC.

Checking the Ubuntu repo’s I found that GQRX v2.12 is available for installation.

sudo apt install gqrx-sdr

Once installed I fired up GQRX and set about configuring it. Initially it appeared to have automatically detected and configured the FCD however, when I started the FCD the software ran for 5 seconds and then just hung.

Diving into the configuration settings I found that the FCD actually appears twice in the list of available devices and all I had to do was select the other one in the list and start the software again and all was well.

I connected my 20m Band EFHW Vertical antenna and trawled up and down the band. The receiver performed well even with fairly strong signals so, I spent some time listening to a few of the stations coming in from the USA.

Next I wanted to sort out the configuration for digital modes. I already have a couple of virtual audio cables in the form of loopback audio devices configured on my Kubuntu PC as this is how I connect the audio between WFView for the IC-705 and WSJT-X/JS8CALL.

Sadly, GQRX doesn’t recognise the loopback audio devices that already exist and so I had to do a little further research to get to the bottom of the issue.

Digging deeper I discovered that GQRX requires loopback audio devices created using Pulse Audio and not the kind I had already created at the O/S level. A quick read of the pactl man page and some further searching online I found all the info I needed to create the correct kind of loopback audio devices.

Two commands are required to create the pulse audio server audio loopback devices:

pactl load-module module-null-sink sink_name=gq2jt sink_properties=device.description="gq2jt"

pactl load-module module-loopback latency_msec=1

Once I’d created the loopback audio devices I was able to select the gq2jt devices in both GQRX and WSJT-X/JS8CALL so that the audio was routed correctly.

GQRX SDR and WSJT-X working with the Funcube Dongle Pro+

The overall solution works well and doesn’t put much load on the CPU of my Kubuntu PC, leaving plenty of horse power for me to do other things at the same time.

So I now have the Funcube Dongle Pro+ working perfectly on my Kubuntu PC, all I need now is a 1.2m dish, a 10Ghz LNB and some high quality coax cable.

UPDATE: I decided to leave the FCD connected to the 20m Band EFHW Vertical overnight and monitor FT8 on the 40m band. The EFHW antenna isn’t anywhere near resonant on the 40m band and so I thought it would be interesting to see how well the FCD performed on a completely non-resonant antenna.

To my surprise it did exceptionally well, stations from all over the world were heard with ease, the FCD really is an excellent little SDR receiver.

Map showing stations heard on 40m Band FT8 over night 16/17 Jan 2023

If you’re looking for a relatively cheap but, effective receiver for FT8/WSPR monitoring then I can highly recommend the FCD. If paired with a RaspberryPi then it would be a really cheap to purchase/operate solution for any HAM operator or short wave listener (SWL).

More soon …

WSPR update

For the last 24hrs I’ve had the RaspberryPi2 transmitting WSPR on 20m and 10m connected to my EFHW Vertical antenna. So far not a single spot on the 10m band, I’m assuming the band hasn’t opened in the UK over the test period.

WSPR 20m band reports over the last 24hrs

Results on 20m continue to impress with reports from the USA, West Africa coast and as far east as Georgia.

I’ll check the signal on 10m later today using my IC705 to ensure it is transmitting ok and then will leave it running for another 24hrs to see what happens.

UPDATE:

It appears there’s been a reliable opening on both 10m and 20m to the Canary Islands just off the west coast of Africa so far today.

The last 48hrs looks like this:

10mW WSPR from M0AWS JO02QC on 10m and 20m bands

More soon …

Whispering around the world

The Weak Signal Propagation Reporting Network (WSPR) known as “Whisper” in the HAM community is a QRP/QRPp beacon mode that is used by many HAMs around the world to see pretty much realtime propagation on the HF bands.

I first started using WSPR when I lived in France some years ago and it proved invaluable for assessing antenna performance and directivity. It’s not a new mode by any means and nowhere near as popular as it used to be as it’s really been superseded by FT4/8 these days that provides the same functionality but, with QSO capability too.

Having an old RaspberryPi hanging around and reading about the WSPR software that’s available for it now I decided to put the Raspi to good use and build a WSPR beacon for the 20m band that I could leave on 24/7.

Having the EFHW Vertical at the end of the garden means that I can connect it directly to the Raspi without the need for an ATU as it’s fully resonant. (It’s actually resonant on 20m and 10m)

I normally run both my RaspberryPi mini computers completely headless and then SSH in to them from my MacBook Pro and decided this was the best way to go with the WSPR beacon too since the WSPR software is command line based and doesn’t require a GUI.

First thing to do was to upgrade the OS from Debian Buster to Bullseye. It’s been a while since I used the Raspi but, it fired up perfectly and connected to the LAN without issue.

After a little time I had the O/S updated to Bullseye and the Raspi was ready for the software build.

The WSPR program comes in source code only so, this means you have to compile it yourself. This isn’t a big job as it comes complete with a makefile.

Using a terminal run the following commands to download and compile the WSPR source code.

So first thing to do is install git.

sudo apt-get install git

Once git is installed I downloaded the software from the git repository.

git clone https://github.com/JamesP6000/WsprryPi.git

It only takes a few seconds to download the software which is stored in a new directory called “WsprryPi”.

Before the code can be compiled there’s a small issue with the includes in one of the source code files that needs to be resolved so that the code compiles without error.

cd WsprryPi
vi mailbox.c

Using your favourite command line editor, ‘vi‘ in my case I added the following line into the include statement at the top of the code.

#include <sys/sysmacros.h>

Once added the full include statement looked like this:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>

#include "mailbox.h"

Once done, I saved the file ready for compilation.

Compiling the code is easy, just run the make command and sit back and watch all the compiler messages scroll across the screen.

make
Compiling the WSPR source code

Once compiled without errors, I just needed to install the binary.

make install

At this point the software is ready to go.

I quickly soldered up a lead to go from the RaspberryPi GPIO pins to the Coax cable that is connected to the EFHW vertical antenna in the garden and connected it all up ready to test.

RaspberryPi 2 WSPR Beacon connected to EFHW vertical for 20m/10m bands

Pins 7 and 9 on the Raspberry Pi’s GPIO pins are where the signal is output. Pin 9 is the Ground pin, and pin 7 is the Signal pin. Pin 7 goes to the inner of the coax and pin 9 to the ground side of the coax.

The purple cable is the ethernet cable connecting the Raspi to my local LAN so that I can access it remotely via SSH. I’ve powered the Raspi off of the USB port on the wifi access point in the radio shack which is always on.

Once it’s all connected it’s just a case of starting the WSPR program from the command line as user root.

wspr -s -r M0AWS JO02 10 20m > ./wspr.log &

I run the WSPR program as root user so that it has the correct privileges to access the devices to communicate with the GPIO headers, if you want too start it as your normal user then you’d need to use sudo to gain the root privileges.

The command line options I’ve used are as follows:

-s

Check NTP before every transmission to obtain the PPM error of the crystal

-r


Repeatedly, and in order, transmit on all the specified command line freqs.

M0AWS

My Callsign

JO02

My Locator Square

10

The power being used in dBm

> ./wspr.log &

Redirects all output to wspr.log in the current directory and then puts the program into the background so that it is left running when I log out.

Once the program is started you can monitor progress by using tail on the log file.

tail -f ./wspr.log

The output you will see will be something like this.

Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:06:01.015
  TX ended at:   UTC 2022-07-17 16:07:51.638 (110.623 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:08:01.015
  TX ended at:   UTC 2022-07-17 16:09:51.639 (110.624 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:10:01.015
  TX ended at:   UTC 2022-07-17 16:11:51.642 (110.627 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:12:01.015
  TX ended at:   UTC 2022-07-17 16:13:51.639 (110.624 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:14:01.015
  TX ended at:   UTC 2022-07-17 16:15:51.639 (110.624 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:16:01.014
  TX ended at:   UTC 2022-07-17 16:17:51.639 (110.624 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  Obtained new ppm value: 4.09996
  TX started at: UTC 2022-07-17 16:18:01.015
  TX ended at:   UTC 2022-07-17 16:19:51.640 (110.624 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:20:01.014
  TX ended at:   UTC 2022-07-17 16:21:51.638 (110.624 s)
Desired center frequency for WSPR transmission: 14.097100 MHz
  Waiting for next WSPR transmission window...
  TX started at: UTC 2022-07-17 16:22:01.004
  TX ended at:   UTC 2022-07-17 16:23:51.628 (110.624 s)

You can pass multiple bands on the command line if you want to hop around bands.

It’s also recommended that you add a low pass filter between the Raspi and coax connection to help suppress any harmonics that may be generated. You can make one easily enough using just a capacitor or there are a number of prebuilt low pass filters specifically made for the GPIO hat on the Raspi online.

With only 10dBm (10mW) output from the RaspberryPi it’s surprising the distances that the signal travels. In no time at all I had reports from all over Europe and as the day progressed reports started coming in from Iceland, the USA and Russia.

Map showing stations that heard M0AWS on WSPR

I used http://wspr.aprsinfo.com WSPR monitoring website to watch progress as the day went on and after 24hrs had been heard by a number of stations over 3000 miles away.

You can also get a more detailed view of reports from the WSPRnet website where you can query the database and create a detailed list of all decodes over a set period of time.

Detailed list of WSPR decodes

Since my EFHW Vertical is resonant on both 20m and 10m I’ll now run it for the next 24hrs on both bands to see what results I get.

More soon …