## Polarization in Voyager signal from Green Bank Telescope

A few days ago I read the paper about the Breakthrough Listen experiment. This experiment consists in doing many wideband recordings of different stars using the Green Bank Telescope, and (in the future) Parkes Observatory and then trying to find signals from extraterrestrial intelligent life in the recordings. The Breakthrough Listen project has a nice Github repository with some documentation and an analysis of a recording they did of Voyager 1 to test their setup.

I have also been thinking about how to study the polarization of signals in a dual polarization recording (two coherent channels with orthogonal polarizations). My main goal for this is to study the polarization of the signals of Amateur satellites in low Earth orbit. It seems that there are many myths regarding polarization and the rotation of cubesats, and these myths eventually pop up whenever anyone tries to discuss whether linearly polarized or circularly polarized Yagis are any good for receiving cubesats.

Through the Breakthrough Listen paper I’ve learned of the Stokes parameters. These are a set of parameters to describe polarization which are very popular in optics, since they are easy to measure physically. I have immediately noticed that they are also easy to compute from a dual polarization recording. In comparison with Jones vectors, Stokes parameters disregard all the information about phase, but instead they are computed from the averaged power in different polarizations. This makes their computation less affected by noise and other factors.

As I also wanted to get my hands on the Breakthrough Listen raw recordings, I have been computing the Stokes parameters of the Voyager 1 signal in their recording. Since the Voyager 1 signal is left hand circularly polarized, the results are not particularly interesting. It would be better to use a signal with changing polarization or some form of elliptical polarization.

I have started to use Jupyter notebook. This is something I had been wanting to try since a while ago, and I’ve realised that a Jupyter notebook serves better to document my experiments in Python than a Python script in a gist, which is what I was doing before. I have started a Github repo for my experiments using Jupyter notebooks. The experiment about polarization in the Voyager 1 signal is the first of them. Incidentally, this experiment has been done near Voyager 1’s 40th anniversary.

## A tour of QB50

The QB50 project consists in a constellation of cubesats with the goal of studying the thermosphere. The cubesats are built by different universities around the world and each of them carries one of three different scientific instruments. A total of 36 cubesats have been built for the QB50 project. All of them transmit on the 70cm Amateur satellite band. A total of 28 were launched to the ISS on April 18th on the Cygnus CRS-7 resupply ship. Over the last two weeks, they have been released from the ISS. The complete launch schedule and radio information can be found here (note that the launches on May 23rd were delayed due to an unforeseen EVA). Several other non-QB50 cubesats, some of them transmitting in the Amateur bands, have also been released together with the QB50 satellites. This is probably the time that more Amateur satellite have been released at the same time. The satellites have not separated much yet, giving a great opportunity to record a single pass and analyse the telemetry of all the satellites.

A few days after the release of all the 28 QB50 cubesats, on May 29th at 18:25:29 UTC, I made an SDR recording of the complete pass of all the cubesats. The recording spans the 3MHz of the 70cm Amateur satellite band (435-438MHz) and lasts 23 minutes and 08 seconds. It was made from locator IN80do using a 7 element handheld yagi (the Arrow satellite yagi) held in the vertical polarization and a LimeSDR. The gain of the LimeSDR was set to maximum, but no external LNA was used. Here I look at the recording, list the satellites heard, and decode their telemetry.

## Quick fixes for some bugs in LimeSDR drivers

These days I have been experimenting with my LimeSDR board. This is an SDR board based on the LMS7002M transceiver chip. The drivers for the LimeSDR are called LimeSuite. This bundle contains a SoapySDR driver called `SoapyLMS7`, which makes the LimeSDR accessible through SoapySDR and also in GNU Radio through gr-osmosdr; some lower level drivers for the LMS7002M chip; and a GUI called `LimeSuiteGUI` that allows one to play with all the settings and parameters of the LMS7002M by hand.

In my tests I have come across a couple of driver-related bugs which I find quite annoying. This is not surprising, as the LMS7002M is a very complex piece of hardware and the LimeSDR drivers must control a huge number of settings and parameters and provide different interfaces to access the SDR hardware. I have reported them in the GitHub issues page of LimeSuite, but there are many other bugs open and LimeSuite is still seeing heavy development, so it doesn’t look likely that they will be fixed very soon.

To overcome this bugs, I have done some workarounds. Rather than trying to find the root cause of the problem, these disable the part of the software that is not working as it should. These workarounds are in the dirtyfixes branch of my LimeSuite fork.

The first bug I found was related to the baseband filter. This filter has a selectable bandwidth. Some bandwidths didn’t work properly, because the passband was far from flat or the cut-off frequency was way off. Moreover, just changing the bandwidth slightly sometimes produced a very different filter shape. I have been tweeting some pictures showing this effect (see also my replies to this tweet). I’ve found that the reason for this is that the parameters to tune the filter are usually cached by the drivers in order to save computations, but this cache system doesn’t work properly. My workaround is to disable the cache and always compute the filter parameters.

The second bug is related to DC spur hardware removal. We are used to the fact that many IQ SDR hardware have a (sometimes huge) DC spur in the centre of the passband, due to several hardware imperfections. This is also the case for the LimeSDR, but the LMS7002M has a hardware system (called RX DC correction) which is quite effective at removing the DC spur. I noted that DC spur removal was much better in LimeSuiteGUI than in GNU Radio or SoapySDR based applications. You can see the difference here. At first, I thought that this was an issue with the IQ calibration. However, it turns out that the RX DC correction was always being disabled by the SoapyLMS7 driver, even though it was supposed to be enabled by default. The reason for this is that a lower-level function from the LMS7002M seems to lie and says that the RX DC correction is disabled, even though it is not. I have bypassed this lower-level function in my workaround. You can see the effects of RX DC correction here.

Update: The second bug has just been fixed. It seems that the `DC_BY_RXTSP` bit that controls the RX DC correction was being overwritten somewhere else in the TX setup code because of a typo. I have reverted the workaround in my “dirtyfixes” branch and merged the proper fix. This branch still contains the workaround for the lowpass filter calibration.

During the last few days I’ve been experimenting with feeding signals from GNU Radio into Linrad using Linrad’s network protocol. Linrad has several network protocols designed to share data between different instances of Linrad, but generally these protocols are only supported by Linrad itself. The only other example I know of is MAP65, which can receive noise-blanked data from Linrad using the timf2 format.

Another possible use of gr-linrad is as an instrumentation for any kind of GNU Radio flowgraph. It is very easy to stream data into Linrad, so it can be used as a very nice waterfall display or to do any sort of signal processing, such as noise blanking or adaptive polarization. Here I describe how to get the test flowgraph in gr-linrad working and some aspects of the network protocol.

## Testing a simple pulse generator for Linrad calibration

Lately, I’ve being talking with Juan Antonio EA4CYQ and Pedro EA4ADJ about performing Linrad calibration to enable the use of the smart noise blanker. They pointed me to the SIGP-1 by Alex HB9DRI, which is a 144MHz pulse generator with which I was already familiar, and a simpler pulse generator by Leif SM5BSZ which I hadn’t seen before.

Leif’s generator is very simple. It uses a 555 timer to generate a square wave, a 74AC74 flip-flop to divide the frequency of the square wave by 2 and obtain a precise 50% duty cycle, a 74AC04 inverter as a driver, and capacitive coupling to turn the edges of the square wave into RF pulses. Alex’s SIGP-1 is an improvement over Leif’s design. It generates the square wave in the same manner, but then it uses a helical bandpass filter for 144MHz with around 5MHz bandwidth to convert the square wave into 144MHz pulses, and a PGA-103+ MMIC RF amplifier and a BFR91 RF NPN transistor as a class A amplifier to increase the output level. The SIGP-1 has two main advantages over Leif design. The output is stronger, so the S/N of the pulses is higher, and the filtering helps prevent saturation in the receiver. However, Leif’s design uses only simple components and it’s adequate in many cases.

I have built and tested Leif’s generator and used it to calibrate my FUNcube Dongle Pro+ at 144MHz. I’ve also tried doing the calibration at other frequencies and it also works well, but the pulses are not very strong at 432MHz and above.

## Testing Opera sensitivity with GNU Radio

Some fellow Spanish Amateur Operators were talking about the use of the Opera mode as a weak signal mode for the VHF and higher bands. I have little experience with this mode, but I asked them what is the advantage of this mode and how it compares in sensitivity with the JT modes available in WSJT-X. I haven’t found many serious tests of what is the sensitivity of Opera over AWGN, so I’ve done some tests using GNU Radio to generate signals with a known SNR. Here I’ll talk about how to use GNU Radio for this purpose and the results I’ve obtained with Opera. Probably the most interesting part of the post is how to use GNU Radio, because it turns out that Opera is much less sensitive than comparable JT modes.

## Reverse engineering Outernet: modulation, coding and framing

Outernet is a company whose goal is to ease worldwide access to internet content. They aim to provide a downlink of selected internet content via geostationary satellites. Currently, they provide data streams from three Inmarsat satellites on the L-band (roughly around 1.5GHz). This gives them almost worldwide coverage. The downlink bitrate is about 2kbps or 20MB of content per day.

The downlink is used to stream files, mostly of educational or informational content, and recently it also streams some APRS data. As this is a new radio technology to play with, it is starting to get the attention of some Amateur Radio operators and other tech-savvy people.

Most of the Outernet software is open-source, except for some key parts of the receiver, which are closed-source and distributed as freeware binaries only. The details of the format of the signal are not publicly known, so the only way to receive the content is to use the Outernet closed-source binaries. Why Outernet has decided to do this escapes me. I find that this is contrary to the principles of broadcasting internet content. The protocol specifications should be public. Also, as an Amateur Radio operator, I find that it is not acceptable to work with a black box receiver of which I can’t know what kind of signal receives and how it does it. Indeed, the Amateur Radio spirit is quite related in some aspects to the Free Software movement philosophy.

For this reason, I have decided to reverse engineer the Outernet signal and protocol with the goal of publishing the details and building an open-source receiver. During the last few days, I’ve managed to reverse engineer all the specifications of the modulation, coding and framing. I’ve being posting all the development updates to my Twitter account. I’ve built a GNUradio Outernet receiver that is able to get Outernet frames from the L-band signal. The protocols used in these frames is still unknown, so there is still much reverse engineering work to do.

Published
Categorised as Software

## Introducing gr-satellites

This post is to present my gr-satellites project. The goal of this project is to make a collection of GNUradio decoders for the telemetry of different satellites. The decoders support submitting telemetry in real time to the PE0SAT telemetry server. Another goal is that the decoders are as easy to use as possible, to try to make more people interested in receiving digital telemetry from satellites and collaborating in online telemetry submission.

The decoders can be used with the Gqrx SDR software, using its UDP audio streaming capabilities. This is the easiest way to use the decoders. It is also possible to use the GNUradio frontends in the companion project gr-frontends. These support several different SDR hardware, WAV and IQ recordings, and conventional receivers connected through a soundcard. They are design to be flexible and to allow its use in headless and automated receiving configurations.

The long-term goal of this project is to provide an alternative software chain to the UZ7HO soundmodem, AGW packet engine and DK3WN telemetry forwarder. The use of GNUradio makes these decoders more configurable and flexible and eases programming decoders for non-AX.25 satellites, which usually employ strong forward error correction.

Currently, the satellites supported by gr-satellites are 3CAT-2, AAUSAT-4 and GOMX-3. I plan to continue adding support for more satellites in the future.