Server

My OpenWebRX Radio Receiver (48 kHz) (opens in new tab)

Note that you will need a recent version of Firefox, Chrome or Opera. for this to work. Other browsers may or may not work, no guarantees given!

Receiver setup September 2016.
Raspberry Pi to the left, tipped vertically for better cooling, Soundblaster soundcard in the middle, and the Softrock Ensemble II to the right.

What and wherefrom

OpenWebRX is a program or system that allows us to look at the received radio signal from an SDR on a webpage. The project location is at http://sdr.hu/openwebrx/ where the installation and download information is to be found.

A while back I bought and assembled a Softrock Ensemble RX, HF receiver. These are sold by Five Dash Inc . This also has lots of useful info at WB5RVZ

Since then I have made some investigations into how to put the receiver online. The Softrock has a usb control channel and outputs analog signals (I and Q) to a sound-card or other ADC, for processing by a computer. The first attempts at making some system working on the RTP (Real-time Transport Protocol) as per RFC3550 were so-so succesful, as this does nothing for the GUI parts. Relegating all the hard work here to a browser seems a good option.

And OpenWebRX does that. It also has all the filters and FFTs and suchlike. There is another system available but that code is non-open and one would have to register to a central server in the Netherlands. OpenWebRX is open, GPL, so it is possible to figure out how it works internally.

Talking to the Softrock device

The Softrock connects as an USB device, so the main thing is to get the communications to work. There is a package that does all the hard work here, this is the code in the tarball usbsoftrock-1.0.2.tar.gz from https://code.google.com/p/usbsoftrock/downloads/list.

This requires the ncurses and libusb development packages, with the Debian and derivatives (Raspbian, Ubuntu) the commands are: (# indicates you have to be root, $ indicates you can be a regular user. I made a regular user named radio for this, so it would be easy to copy to other machines. (just zip or make a tarball of the whole /home/radio directory tree)

# apt-get install libncurses5-dev ncurses-doc 
# apt-get install libusb-dev

unpack, configure, and compile the usbsoftrock-1.0.2.tar.gz file:

$ cd src
$ tar -xvzf ../Downloads/usbsoftrock-1.0.2.tar.gz
$ cd usbsoftrock-1.0.2
$ ./configure
$ make

Installation requires root. The default is to put this into /usr/local/bin

# make install

In order for the device to be available, make the radio user part of the dialout group, and put a new rules file in /etc/udev/rules.d, something like:

# vi /etc/udev/rules.d/51-libusb.rules

This file should contain the following all on one line:

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="16c0", ATTR{idProduct}=="05dc", MODE="0666", GROUP="dialout", SYMLINK="softrock"

This tells the usb subsystem that there is, or may be, a device with vendor identifier 0x16c0, a product identifier 0x05dc, which should be made available through a device file symlink /dev/softrock. The actual device is something like /dev/usb/001/005 but that can change between reboots, so this makes it work as /dev/softrock no matter what. The /dev/usb/001/005 has the group permission digit 6, so it allows everyone in the dialout group to access it. Thus no need for setuid or elevation to root.

Once having rebooted, the usbsoftrock program should be available and try its status command:

radio@trident:~ $ usbsoftrock status
Version     : 15.15
USB SerialID: PE0FKO-0
Startup Freq: 7.050000 (x 4.00)
Xtall Freq  : 114.285000
Smooth Tune : 3500 PPM
Si570 I2C   : 55 Hex
  BPF Enabled: 1
    Band    BPF      Si570
----------  ---  -----------------
 0.0..16.0   0   (F - 0.00) * 1.00000
16.0..32.0   1   (F - 0.00) * 1.00000
32.0..64.0   2   (F - 0.00) * 1.00000
64.0..       3   (F - 0.00) * 1.00000
radio@trident:~ $

Typical commands, in order to set and read the tuning frequency are:

$ ./usbsoftrock set freq 8.192
$ ./usbsoftrock getfreq

The utility can be run in the background as a daemon, where it listens on an UDP port, default being 19004, in which case, a separate program can be made to set and request the center frequency of the Softrock tuner. The following invocation in /etc/rc.local will do:

/usr/local/bin/usbsoftrock -d &

I made a simple udp client program, named tunea, for this, which allows for frequency to be set specified in Hz, kHz, or MHz, and to be read and reported in similar units. The openwebrx program can use this to read setting for the center-frequency on startup, so there is no need to have to keep editing its configuration file for this.

The two small utilities, tunea and rloop, are in this tarball: sdrutils-161007.tar.gz

RTL-SDR

This is the small, commonly seen, tv tuner that has been found useful as a higher-frequency SDR. It contains the tuner and the digitizer and can work from around 24MHz to 1800 MHz and emit I and Q data at up to 2.4 MHz. Centered at 145.0 MHz and with sample rate of 2.048 MHz it covers the entire 2m band. The OpenWebRx program as it comes in the package is set-up to work off this right away. Like the Softrock device, there is a necessary udev setting for this as well, which gets created on installation of OpenWebRx

The relevant file is /etc/udev/rules.d/45-rtl-sdr.rules and it contains something like

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="0bda", ATTR{idProduct}=="2838", MODE="0666", GROUP="dialout", SYMLINK="rtl_sdr"

Which soundcard?

Here be the biggest dragons.

C-media soundcards at 48000 kHz sampling rate worked reasonably well, and once I had a sufficiently strong power supply to the Raspberry Pi, I could get good output from a Soundblaster card. This card supports 96000 Hz sampling so that means the client can tune over that bandwidth. At first the pulseaudio subsystem seemed to get in the way, but with blacklisting the in-build sound subsystem on the Raspberry Pi or Pine A64+, then using the driver for the sound-card, at least gave something useful.

In contrast, the in-built soundcard on an older PC that I had here, would not seem to work at all. As the soundblaster card had the best specs (the C-media device has a low-pass filter that removes everything below about 20 kHz) it has been chosen. This is also an USB-connected unit and it requires more power, so a hefty 5V supply on the Raspberry Pi 3 is needed.

It will also be necessary to make sure the alsa-utils package is installed,

# apt-get install alsa-utils

OpenWebRx documentation indicated that the standard arecord program could be used to feed the data from the soundcard to the server, and while this would work for a while, it did stop working after a few hours.

I made another simpler program, rloop, that just reads the soundcard and emits the data to stdout (where openwebrx knows to pick it up) and that has kept working right now for about a week and counting.

rloop is to be found inside this tarball: sdrutils-161007.tar.gz

Note that for this to be compiled successfully, we need to have the alsa-utils and libasound2-dev packages installed:

# apt-get install alsa-utils libasound2-dev

Installing OpenWebRX

Follow the instructions at http://blog.sdr.hu/2015/06/30/quick-setup-openwebrx.html basically

There are several components, including one for rtl-sdr that we won't be using here with the softrock and soundcard. After this, the csdr library is installed an then finally the openwebrx code itself. All the sources go into directories in /home/radio/src.

After installing I changed the values in the file config_webrx.py to reflect call-sign and location. Initial center frequency and initial modulation type can also be set here, away from the default fm at the center frequency.

For the 80m receiver, LSB and start frequency of 3560 kHz are the more useful starting values.

I also changed google.hu to google.no in the openwebrx/htdocs/index.wrx so that map-info would show in Norwegian and not Hungarian.

Modifying OpenWebRX for reception from the Softrock

There is a configuration and startup file, config_webrx.py, and the way OpenWebRX is made out of communicating parts, one of these is a program that feeds it data from an RTL-SDR, sound-card, or some other ADC. Thus once I can get working a program that reads the ADC and returns the sample data in one of the commonly found and supported formats, then all is good.

As mentioned, using arecord for the sound-card wouldn't work reliably so I have made the rloop replacement program. The following statements in the config_webrx.py file will start it using this:

# Softrock SDR behind a sound-card (needs ALSA)

samp_rate = 96000

start_rtl_command="rloop -r {samp_rate} -".format(samp_rate=samp_rate)
format_conversion="csdr convert_s16_f | csdr gain_ff 30"

I also made the OpenWebRx program read the setting from the Softrock, the code for this went into config_webrx.py, at the point where the center frequency value, center_freq, is defined, and it looks like this:

# Read and use whatever frequency has been set into the Softrock device
import os
cftext = os.popen("tunea -s").read()
print "cftext = >", cftext, "<"
center_freq = int(cftext)
print "center_freq = >", center_freq, "<"

The -s argument to tunea makes it return the minimal text of the frequency in Hz, so that can be picked up, converted to integer, and used as the value of center_freq in openwebrx.

Which machine?

For the proof-of-concept it made sense to try a PC with internal sound card, but as mentioned, the sticky point is to get anything worthwhile out of the sound-card. The PC was abandoned for a couple of recent Single-board computers.

Pine A64 was the first successful attempt. It has a wide-bandwidth wired network port, and it is a 64-bit, 4-core machine. However, it thus far only runs an older 3.10 kernel, though much of the standard ARM packages for Debian Jessie are available.

The 64-bit architecture means that the csdr subsystem, (libcsdr.so) threw forth a lot of errors at the first attempts at compilation. Turning off the optimizations made it work, and the CPU is fast enough for the job anyways. I also deinstalled the whole PulseAudio subsystem and reverted to plain and predictable ALSA there.

With the C-media simple input unit (Plexgear Soundsaver, from Kjell&Co, item # 98-627) things worked quite good, for a while. I noticed that the sound-card reading function would stop and require the server to be restarted after a few hours. For something out in the field somewhere with no quick access this will not be so great. Even though a log-in via ssh was sufficient and only the openwebrx program had to be restarted. This has been fixed by replacing arecord with the rloop program.

Raspberry Pi 3 has also been tested. It has a weaker wired network sharing bandwith with the USB bus, but it comes with wireless networking out of the box, and this wireless channel runs on its own hardware. With a sufficient power supply it supports the Soundblaster card and the Softrock USB channel directly on two of its 4 USB channels. The same stoppage problem with arecord was seen here, but the replacement, rloop, keeps going.

References

USB definition file

These are the entries that go into files in /etc/udev/rules.d

Note that there will be error messages on startup if these USB devices are not plugged in at that time.

Softrock control channel:

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="16c0", 
ATTR{idProduct}=="05dc", MODE="0666", GROUP="dialout", SYMLINK="softrock"

RTL-SDR unit:

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="0bda", 
ATTR{idProduct}=="2832", MODE="0666", GROUP="dialout", SYMLINK="rtl_sdr"

Necessary packages

# apt-get install build-essential git libfftw3-dev cmake libusb-1.0-0-dev nmap 
# apt-get install libncurses5-dev ncurses-doc 
# apt-get install libusb-dev
# apt-get install alsa-utils libasound2-dev

May also need

# apt-get install libi2c-dev i2c-tools

Read-only filesystem tricks

To make the installation more reliable, by making the root file systems read-only

Recipe from info at: https://hallard.me/raspberry-pi-read-only/ and https://petr.io/en/blog/2015/11/09/read-only-raspberry-pi-with-jessie/

Start with a freshly written SD card.

Enable i2c, spi, ssh etc. as desired.

# raspi-config
# apt-get update
# apt-get upgrade
# apt-get dist-upgrade
# apt-get autoremove

Clean out unwanted packages

# apt-get remove --purge wolfram-engine triggerhappy cron logrotate 
# apt-get remove --purge dbus dphys-swapfile xserver-common lightdm fake-hwclock
# apt-get autoremove --purge

Replace log management with busybox

# apt-get install busybox-syslogd
# dpkg --purge rsyslog

Disable swap, fsck, and make the file-system read-only.

Add fastboot noswap ro at the end of the line in /boot/cmdline.txt

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=678bb471-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fastboot noswap ro

Move spool

# rm -rf /var/spool
# ln -s /tmp /var/spool

Edit /etc/ssh/sshd_config, change from yes to no

UsePrivilegeSeparation no

Edit fstab, make the /boot and / systems ro, and put /var/log, /var/tmp, and /tmp as tmpfs

proc            /proc           proc    defaults          0       0
PARTUUID=678bb471-01  /boot           vfat    defaults,ro          0       2
PARTUUID=678bb471-02  /               ext4    defaults,noatime,ro  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
tmpfs   /var/log    tmpfs   nodev,nosuid    0   0
tmpfs   /var/tmp    tmpfs   nodev,nosuid    0   0
tmpfs   /tmp        tmpfs   nodev,nosuid    0   0

Move dhcpd.resolv.conf to tmpfs

# touch /tmp/dhcpcd.resolv.conf
# rm /etc/resolv.conf
# ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf

Create files /bin/ro and /bin/rw, to make it easy to turn the read-only flag on the root fs on and off, when edting things

/bin/ro

mount -o remount,ro /

/bin/rw

mount -o remount,rw /

Then chmod 744 these, so only root gets to run them.

Since we killed cron, we may want to fake the loop, as was needed for the info-server.

#!/bin/sh
while true; do
sleep 60
/home/radio/src/infoclient/infoclient synfare.com 8071
done

This is called from /etc/rc.local. This is also where gpios for buttons and display are allocated in sysfs.


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

 # GPIOs
# 17 is the next button
echo 17 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio17/direction
echo rising > /sys/class/gpio/gpio17/edge
chmod 666 /sys/class/gpio/gpio17/value

# 27 is the shutdown request button
echo 27 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio27/direction
echo rising > /sys/class/gpio/gpio27/edge
chmod 666 /sys/class/gpio/gpio27/value

# 18 backlight
echo 18 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio18/direction
chmod 666 /sys/class/gpio/gpio18/value

# 21 Blue LED
echo 21 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio21/direction
chmod 666 /sys/class/gpio/gpio21/value

# 22 Red LED
echo 22 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio22/direction
chmod 666 /sys/class/gpio/gpio22/value

# 23 Green LED
echo 23 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio23/direction
chmod 666 /sys/class/gpio/gpio23/value

# 24 Display Reset
echo 24 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio24/direction
chmod 666 /sys/class/gpio/gpio24/value

# 25 Display D/C
echo 25 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio25/direction
chmod 666 /sys/class/gpio/gpio25/value

/usr/local/bin/rpiinfoserv &

/home/radio/src/sdrsuperv/superv &

/usr/local/bin/usbsoftrock -d &

sleep 3

/usr/local/bin/tunea -fk 3670

/home/radio/bin/openwr & 

/home/radio/src/infoclient/fakecron-infoclient.sh &


exit 0




Powered by Apache

Valid XHTML 1.0!