part 1, part 2, part 3

Turn the receiver off between messages

To save power and cpu, I wanted to turn the RTL-SDR off between messages.  Because the next message comes at a set interval, I can just turn the RTL-SDR off while I wait for it.  It should lead to around 97% reduction in CPU and power usage.  I changed the code to kill the gnuradio process after the message was decoded, and start it again before the next message came.  Gnuradio takes some time to start, so I needed to measure exactly how long so it would be ready in time of the next message.  On my platform, it takes around 1.8 seconds.  The code to measure that:

It worked at first, but there was a problem somewhere.  After around 1-2 days, it would fail.  It would fail in such a way that the RTL-SDR would stop sending any data at all.  The RTL-SDR module wouldn't even output for other tools like rtl_fm.  The only way to get it working again was to either unplug the RTL-SDR and plug it back in, or use sysfs to reset my whole USB controller (which would reset all the USB devices connected to it):

cd /sys/bus/pci/drivers/ehci-pci
sudo sh -c 'echo 0000:00:1d.0 >unbind'
sudo sh -c 'echo 0000:00:1d.0 >bind'

I suspect there's a race condition with the RTL-SDR drivers, maybe it's the setup of the PLL is the part that is going wrong.  It's not a problem when letting it run without stopping for weeks at a time, only when stopping and starting frequently.  So I left it running all the time.

Include a measurement of signal strength and frequency

To estimate how strong the received signal is compared to the noise, I took the ratio of unexpected data to expected data in dB.  This is roughly a month's worth of data.

sync messages SNR:
lines: 50813
mean: 30 dB
std dev: 10
min: -16 dB
max: 36 dB

data messages SNR:
lines: 57981
mean: 14 dB
std dev: 5
min: -1 dB
max: 21 dB

Raspberry Pi

I wanted to try running this on a Raspberry Pi 3 B+ (1.4GHz).  In theory, it should be significantly less power usage than the x86 server I have it running on now.  The x86 server I have uses around 50 watts when it is idle.  The Raspberry Pi 3 B+ uses under 2 watts when idle.

I put the latest raspbian on it, installed the gnuradio (version and gr-osmosdr (version 0.1.4-12) packages, and tried running my decoder.

pi3:~/git/weather-station$ ./
linux; GNU C++ version 6.2.0 20161010; Boost_106100; UHD_003.009.005-0-unknown

gr-osmosdr 0.1.4 (0.1.4) gnuradio 3.7.10
built-in source types: file osmosdr fcd rtl rtl_tcp uhd miri hackrf bladerf rfspace > airspy soapy redpitaya
*** Error in `python2': corrupted double-linked list: 0x01064620 ***

this does not work :(

Sidetrack: IO performance

Unrelated to all of this stuff, the SD card I'm using is pretty terrible: Read 960Kb  Written 640Kb  Total transferred 1.5625Mb  (71.566Kb/sec)

Writing 4kb and sync'ing it:

pi3:~$ ./file-ping
took 0.020604s
took 0.027076s
took 0.016936s
took 0.023964s
took 0.022712s
took 0.018760s
took 0.018634s
took 0.026094s
took 0.019508s
took 0.019513s

So I setup a network block device (nbd) so the Raspberry Pi could use the disks of a proper server.  It's much faster: Read 93.75Mb  Written 62.5Mb  Total transferred 156.25Mb  (31.96Mb/sec).  It's nice to see the new gigabit adapter resulting in faster IO.

4kb writes are also faster:

pi3:/mnt/nbd$ ./file-ping
took 0.004718s
took 0.004930s
took 0.052793s
took 0.004633s
took 0.004485s
took 0.004580s
took 0.004379s
took 0.054900s
took 0.004705s
took 0.004538s

So I installed the testing version of Raspbian and ran it under a schroot.

Testing version of Raspbian

Testing has newer package versions.  Gnuradio version and gr-osmosdr version 0.1.4-14+b5.

It works!  It took a lot longer to start up compared to my x86 machine though, 1.8 seconds vs 7.1 seconds.

Let's see what happens when I run the full decoding system:

All those extra letter O's are a problem.  They are from gnuradio, signaling that it's losing data (Overrun).  It can still receive enough data to work, so it's not a total loss.  But it is a sign that things aren't working as well as they could be.

Raspberry Pi CPU usage for gnuradio

Core 2 at 0% idle

From this, you can see core 2 is just at 100% usage.  It's not keeping up.  It's also a sign of the code not distributing the load over multiple cores, so it must not be threaded.

Checking atop to verify the cpu frequency:

atop shows the CPU is running at 1.4GHz

The average cpu frequency (avgf) is at 1.4GHz, so that looks fine.

However, I believe it's possible to do this work on as Raspberry Pi.  As a comparison of CPU usage, I ran rtl_fm -f 917.185MHz -s 22050 (receive 917.185MHz at 22050 samples per second).

And the CPU usage was around 3-5% of a core:

So I still have some work to do if I want to run this on a Pi3 B+.