Transmitting (and Receiving) DVB-T on 1.2 GHz

What interesting stuff can you do with a wideband software-defined transceiver? This question started bugging me when I got access at work to an N200 USRP with a WBX daughter board. The N200 is a DAC/ADC motherboard that can stream up to 50M samples per second to/from a computer using a gigabit Ethernet cable, and the WBX is an up/down converter that covers 50 to 2200 MHz. Together, they can receive and transmit signals with bandwidth of up to about 25 MHz almost anywhere in the VHF and UHF bands.

The coolest thing I could think of is to transmit digital television in a standard format that could hopefully be received by normal televisions, set-top boxes, and USB TV dongles. I almost succeeded, and this post tells the story. (For the impatient, here is the summary: I managed to transmit digital TV to a standard dongle, but in order to do this both legally and ethically, I had to hack its driver a bit; the video is jumpy, but it’s there.)

Standard and Frequency Selection

Choosing a digital video standard to transmit was easy. The on-the-air TV stations here transmit DVB-T (a widely-used standard for terrestrial digital TV), and I already had a DVB-T USB donble (which I used as an SDR receiver up to now), so the obvious choice was DVB-T.

Selecting a frequency to transmit is more of a problem, because the easy choice is not a good choice. Terrestrial digital TV is transmitted in VHF and low-UHF channels, from 50 to 862 MHz. DVB-T channels are 6, 7, or 8 MHz wide. The only amateur band within this range that is wide enough is the 430-440 MHz band, and it’s only 10MHz wide here; in other parts of the world it covers 420-450 MHz. If I transmit DVB-T within these 10 MHz, I will transmit over many other signals, including satellites, repeaters, and simplex channels, so this band is really not an option. The next band up is 1240-1300 MHz, which is both wide enough and almost completely unused here, except for some EME usage near 1296 MHz. So the choice is easy; I have to transmit at 1.2 GHz. But DVB-T receivers won’t tune that high, given that all of the channels are at 862 MHz or below, so it’s a choice with a problem.

Still, I knew that my DVB-T dongle can physically tune up to 1700 MHz (this is also true for many other dongles, and I image also for many set-top boxes and built-in tuners in TVs). So I decided to transmit at 1.2 GHz and to try to force the dongle to tune.

I thought that it would be easier to convince the dongle to receive at 1.2 GHz on Linux than on Windows. I managed to do it on Linux and it was not hard; I still don’t know if this is possible at all on Windows, and if it’s possible how difficult it is. But the main thing for now is that it’s manageable on Linux.

Preparing for DVB-T Reception on Linux

My dongle is based on the Realtek RTL2832U demodulator chip (and on the Elonics E4000 tuner chip). I wanted to use it on a computer running Ubuntu 12.04; the Linux kernel in Ubuntu 12.04 does not support this dongle. This turned out to be a blessing in disguise, however.

Hubert Lin’s blog shows how to install the driver on Ubuntu 12.04 (and using a somewhat different procedure, on 12.10). I tried to follow the instructions but the processed failed at some point. Fortunately, Chris Merrett packaged the driver in an easier to install format called DKMS, and he explained how to install it in a comment in Hubert’s blog. I followed the instructions and everything worked just fine. A DKMS driver is installed in a source-code format and this source code is compiled for every version of the kernel that you use. This turned out to be very useful. Installing the driver is very easy:

$ sudo apt-add-repository ppa:chrisfu/rt2832u-dkms
$ sudo apt-get update
$ sudo apt-get install rtl2832u-dkms

With the driver installed, I installed an Ubuntu package called dvbt-apps, which contains a necessary channel-enumeration utility, and I was ready to try receiving the local on-the-air DVB-T transmissions.

The process starts with a utility called scan. It takes a file containing tuning information for local stations and tries to tune the dongle to them. The station information includes the center frequency, the modulation format, and a bunch of parameters that specify how the transmission is encoded. A DVB-T transmission (station) can transmit multiple channels (simultaneous programs), and scan lists all the channels that it finds within the transmission. I found a file listing the parameters for the local transmissions (at 514 and 538 MHz, transmitting the same channels), ran scan, and it found about 5 TV channels and more than 10 radio stations within the transmissions. Here is the input file to scan (for Israel):

# Initial scan config for Israel
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T  538000000 8MHz 2/3 NONE QAM16 8k 1/32 AUTO
T  514000000 8MHz 2/3 NONE QAM16 8k 1/32 AUTO

The output looks like this (chopped here for conciseness; the first two programs are TV and the other two are radio):


Next, I ran the vlc video viewer, providing it with the file that scan produced. I was able to view TV. I also recorded the video+audio stream of one of the channels using vlc in a format called a transport stream in order to try to transmit it later.

Tuning the Dongle to 1.2 GHz

At this point I created a copy of the scan input file and changed the center frequency to a frequency in the 1.2 GHz band. Scan failed; it could not tune the dongle to this frequency. I knew that the dongle can physically tune that high so I assumed that some piece of software was aware of the allocation of DVB-T frequencies and did not allow tuning any higher. I tried various frequencies until I realized that the dongle tunes up to 862 MHz. I searched for this number in the sources of the driver and found one C file that contained the number 3 or 4 times. It was the value for a field called frequency_max in structures that describe the capabilities of the dongle for several digital TV formats, including DVB-T.

I changed the value from 862000000 to 1700000000 and tried to get the driver to re-compile. It took me a while to figure out that the correct process is to remove the driver entirely and then to rebuild and install it.

$  sudo dkms remove -m rtl2832u/3.0.1 --all
$  sudo dkms add -m rtl2832u -v 3.0.1
$  sudo dkms build -m rtl2832u -v 3.0.1
$  sudo dkms install -m rtl2832u -v 3.0.1

Now the dongle tuned to 1.2 GHz. Scan obviously did not find any transmissions there, but I was now ready to receive my transmissions.

If somebody can figure out how to get these dongles to tune to 1.2 GHz under Windows, please let me know.

Producing the DVB-T Baseband Signal

There are several software packages on the web that produce a DVB-T baseband signal from an MPEG stream. I used a package called gbDVB written by Giuseppe Baruffa. It comes in binary format only for Windows and Linux, and it can produce (and decode) DVB-T in pretty much any format and modulation. It is fast: it works faster than real time on my desktop (with an i7 processor). I used version 3.3; the latest is 3.4, but it requires a somewhat complicated registration procedure. I did register it, but on Windows, not Linux; I plan to register on Linux and upgrade.

Another option I considered is OpenDVB by Gordon Cichon, which comes in source form and is written in Matlab. It is somewhat harder to use. I plan to try it out in the future.

Before you can use either of them, you need an MPEG (video or audio) file in a format called a transport stream. I generated several of these, always using vlc, a viewer that can also write the movie to a file in various formats. To save a transport stream, I used

vlc movie --sout=file/ts:movie.ts

I called dvbtenco (part of gbDVB) with options that told it to generate a DVB-T transmission using the same format and modulation as the local broadcasts, which I knew work with my dongle.

gbdvb/dvbtenco -i movie.ts -M 16 -m 2k -d t -l movie.log -o movie

This command generates a file called movie.bin with complex baseband samples at a sampling rate of 9.142857 M samples/s. The USRP cannot transmit at that rate (it needs a rate that divides 100 M samples/s), so I used a simple gnuradio-companion program to upsample the signal to by a 70/64 to 10 M samples/s, using a rational resampler.

Putting it all Together

That was basically it. I used a USRP utility to tx_samples_from_file to transmit the 10 M samples/s baseband file at 1.2GHz (actually near 1.3) and I called scan with an input file telling it to look for a DVB-T transmission there. Scan found my USRP transmission and produced an ouput that allowed vlc to tune and display the video I transmitted!

Actually, the video was very jumpy. I think this happened because tx_samples_from_file did not manage to read the baseband file and to send it to the USRP quickly enough. I managed to improve things a bit by converting the baseband file from a floating-point representation (8 bytes per sample) to short integers (4 bytes per sample), but it was still jumpy. Maybe the disk is not fast enough. I’ll try to transmit with a 6MHz bandwidth rather than 8 and hopefully the sampling rate can be reduced, which will shrink the rate at which the samples need to be read from the file and sent to the USRP. I need to investigate.

As I wrote above, dvbtenco runs faster than real time on my desktop, so in theory, I may be able to transmit live video with this setup. But the gnuradio resampler is very slow; maybe I can optimize it and run the whole thing live. But the first step should be to transmit a video from a file without jumps.

Another thing that is still missing is an identification of the program that is being transmitted. This information needs to be multiplexed into the transport stream. I am trying to learn how to do that.

A High-Performance Sound-Card AX.25 Modem

My APRS RF-to-internet gateway (iGate) had been running  a sound-card modem called soundmodem by Thomas Sailer. The software modem caused various problems and I have not found a suitable replacement. Eventually, I decided to try to implement my own sound-card-based software modem. The results have been very good, in spite of the fact that I do not have much background in digital signal processing.

I’ve been using the modem for many months now in my iGate. The modem is run is a component of javAPRSsrvr, not as a separate program. It’s working reliable non-stop.

An article that I wrote for QEX explains how the modem works and how I designed and optimized it. It is also available on my university web site.

Using the USRP with HDSDR

Balint Seeber developed a software library that links HDSDR, a software-radio receiver program (and a few other related programs) with USRPs, a family of FPGA-based radios. I have a USRP1, the original USB-based motherboard, a BasicTX and a BasicRX daughter boards (which are basically just transformers linking the input coax connectors to the amplifiers that feed the ADCs), and an RFX400 transceiver (up/down converter to 400-500Mhz).

The USRP radios are best supported by GNU Radio, an open-source signal-processing toolkit. I have already used GNU Radio. The software is very capable, but it is somewhat difficult to install and it does not come with complete sophisticated radios. There are also drivers that interface USRPs to Matlab/Simulink; I was unable to get them to work. Therefore, I was delighted to learn that Seeber wrote the library that allows USRPs to be used with HDSDR and decided to give it a try.

HDSDR is a radio program that was derived from earlier programs (Winrad and WinradHD). It supports a wide range of RF frontends through the use of software libraries called ExtIOs. Seeber wrote an ExtIO library that can control the USRP and can transfer RF samples from it.

Downloading and installing Seeber’s ExtIO library and HDSDR was easy, thanks to an installer that Seeber wrote. Seeber’s software can also switch the USB-based USRP between two different drivers, which is a very useful (my experience in trying to switch these drivers manually has not been good).

After installation, I gave the software a quick try by tuning to a UHF and checking that the RFX400 can receive a signal from a handheld transceiver; it did.

I decided to try to USRP on HF next. I connected one of my amplified receiving loop antennas to a bias tee, then from there to a low-pass filter, and from it to the input of the BasicRX board. The low-pass filter is a high-quality 39 MHz surplus unit. It’s role is to eliminate aliasing of VHF signals into the HF spectrum. Ideally, the stopband should have started at 32 MHz (since the USRP samples at 64M samples/second), but a 39 MHz unit was all I had. I was not sure whether I would receive many signals, since between the BasicRX input and the input of the ADC there are only 20dB of amplification. In the picture you can see the USRP (in the background, in a cardboard box), the filter, the bias tee, and the 12V supply that feeds the bias tee. The USRP and the antenna are shown at the bottom of the post.

It turned out that this is sufficient to receive a great number of interesting signals all over MF and HF. Here are some screenshots. In the first screenshot I was listening to BBC World at 1323 kHz, an AM medium-frequency station. The USRP digitally down-converts the high-rate RF samples and decimates the RF samples, in this screenshot to 250k complex samples per second, so we see 250kHz of RF spectrum.

In the next screenshot, the radio is tuned to a station at the low end of the AM range, but the decimation is set to a lower value. We now see a full MHz of spectrum, all of the AM range plus a bit to spare. Very neat; all the AM stations on one waterfall display.

Next, we see the entire 14MHz amateur band. The band is densely populated at this early-evening hour. On the left we see a bunch of CW stations, PSK stations near 14070 kHz, and a large number of SSB stations starting at 14100 kHz.

I was able to receive distant stations all over the HF range, all the way up to 28 MHz. Here is the antenna I used; it is mounted fairly low in an urban area.

A few days later I tried UHF reception with the RFX400 daughter board. Local FM stations were received well. Satellites proved to be more of a challenge. I was not initially able to receive satellites with fairly weak signals like FO-29 and CO-58 (which I can hear reasonably well with the FT-857D), but I was able to receive the CW beacon of RS-22, as you can see in the following screenshot. The Doppler shift is clearly visible both in the RF waterfall display and in the audio waterfall. You can also see the very narrow signal in the audio spectrum display. The signal was received with my small VHF/UHF Yagi.

A second attempt to receive FO-29 was more successful. I was able to hear both SSB and CW signals clearly enough to understand them. Linking HDSDR to the satellite tracking program of Ham Radio Deluxe via DDE provided automatic Doppler correction, which worked out very nicely. Still, the RFX400 is probably not ideal for receiving UHF satellites. Its noise figure is not documented but I don’t think it’s particularly good, and its response rolls off below 440 MHz and above 460 MHz (as reported by Patrik Eliardsson and others). An external preamplifier would probably help.

Seeber’s library also supports a low-cost USB dongle that can sample RF signals between 64 and 1700 MHz. The dongle is sold as a digital-TV and radio receiver, but somebody discovered a way to cause it to send to the PC unprocessed RF samples, which can then be processed in programs like HDSDR and GNU Radio. I ordered a such dongle for about $20 from eBay and I’m looking forward to trying it out. Its analog-to-digital converter provides only 8 bits per sample, a lot less resolution than the much more expensive FUNcube dongle, but it supports much higher sampling rates than the FUNcube dongle.

Building an APRS Tracker

I’ve been running an APRS RF-to-internet gateway for a few months now. It uses javAPRSSrvr as the gateway program and soundmodem as a soundcard modem, both running on a remote Linux machine. Both programs are very reliable, running for months without a fault. I spent a bit of time trying to get the two programs to communicate over a virtual serial port, but this did not work, so I eventually switched to AX25 kernel-mode support, which worked out of the box on Ubuntu Linux.

I want to track myself using APRS, so I needed a tracker.There are several published hardware and software designs on the Internet, and I originally considered building a tracker based on one of these designs. But I eventually decided to build a tracker that is not based directly on any existing design. Mostly, I wanted to end up with a high-quality and flexible code that could be easily ported to different hardware platforms and to different uses. I’m not yet there, but I’ve got a working prototype that’s running my own code.

One thing I knew I wanted to do was to avoid a modem chip. Some APRS trackers and digipeaters use a modem chip, normally the mx614. A modem microcontroller would be able to produce and decode a 1200b/s AX25 signal in software. There are several trackers that do that already, like Gary Dion’s WhereAVR and Byonics‘ TinyTrak3 and TinyTrak4.

The prototype is running on an microcontroller development board that I use at work for teaching a course on embedded computing. It has an LPC2148 microcontroller, which has an ARM processor, and lots of on-board peripherals. The tracker currently uses almost none of the on-board peripherals except for the LCD screen. The board is connected to a GPS module and to a VHF radio. The GPS is a NEO-5Q module from ublox; it’s mounted on a board that also has a microcontroller and a bunch of other components (a prototype from an old wifi-based tracker project I participated in), but I’m only powering and using the GPS module on this board. The GPS is connected to an external active patch antenna. The radio I’m using is a Baofeng UV-3R, which I bought mainly for this purpose. It cost less than $50 including shipping, considerably cheaper than some dedicated VHF tracker transmitters. The radio is connected to the microcontroller through a little interface board that I built. Both this interface board and the GPS module are currently stuck into a breadboard, with wires connecting the microcontroller board to the breadboard.

The interface board performs 3 functions. It connects the DAC output of the microcontroller to the microphone input of the radio. This signal is routed through a trimmer resistor, to adjust modulation in the radio (it needs a much smaller amplitude than the DAC produces), and though a DC blocking capacitor. The board also routes the audio output of the radio to an ADC pin of the microcontroller, but I haven’t tested this yet. Finally, an open-collector NPN transistor switches the radio to transmit. I had some trouble with this transmit-receive switch: RF would get into the circuit and would keep the radio transmitting long after the microcontroller tried to turn the transistor off. I solved this with two 0.01μF decoupling capacitors on both the base and the collector of the switching transistor.

I used my own software drivers for the microcontroller (for it’s UARTs, DAC, etc.), but I used code from other APRS open-source projects for building up packets and for producing the audio output of the modem. I will release the software once it is more or less stable. I used three codes: Tracker2’s code by Scott Miller of Argent Data, the AX25 code in BeRTOS (a real-time operating system), and soundmodem. I have a lot of positive experience with soundmodem running on the Linux box, so hopefully it will work well on an embedded system. Fortunately, it uses fixed-point arithmetic, rather than floating point which is not supported in hardware on small microcontrollers, so it should work. But I have not tested the demodulator yet. The parts of soundmodem that I’m already using required quite a bit of hacking, unfortunately. I initially tried to keep the modem code as is, but I gave up after a while; the over structure does not work too well in an embedded setting.

I’ve been working on the tracker for a few days, and yesterday it got to the point where it was working on the bench: parsing GPS data, producing packets, and sending them to the radio. The packets were well-formed and my gateway decoded them (actually just some of them;  I’m not sure if the 2W signal from the radio was too weak, or the transmitted audio is not good for some reason). It was time to take the tracker for a ride. I took it to the car and hooked it to the cigarette-ligher’s socket. The LPC2148 board can be powered by up to 15V, and it can produces enough 3.3V power for the GPS, so I assumed everything would work. It did for a while (you can see some position spots in the map on the right), but after a few minutes the tracker started rebooting itself every second or so. I touched the regulators on the board and they were pretty warm, so I’m assuming that one of them overheated, shut down, and caused the system to reset. I guess I can’t power this unit directly from the car’s battery; I’ll need to drop the voltage with an off-board regulator first.

Next, I’m going to work on the AX25 demodulator, hopefully producing a tracker that can also decode packets.

HF Email using Winlink 2000

So far I’ve used three digital modes on the HF bands: PSK (mostly PSK31), WSPR, and JT65A. PSK is fun, in that you see signal phenomena in real time, and you see them both visually and in the ability or inability to decode the signal. If the signal fades, you see it fade; if two stations transmit on the same frequency, you can see that too. It allows you to chat with other stations and write whatever you want. But because PSK31 does not have any error correction or automatic acknowledgements, you sometimes receive only part of a transmission. To me, this feels low-tech. I expect digital transmissions to be almost perfect when communication is possible. PSK31 is not.

WSPR and JT65A incorporate strong error correcting codes, so transmissions are usually error free (not always, but almost). But neither of these is good at actually sending information. In WSPR the only information transmitted is station identification and location; you can’t say anything other than who and where you are. JT65A allows you to send a bit of free text, but it’s cumbersome; mostly, it’s also just for establishing the ability to communicate, not for actually communicating information.

Yesterday I finally succeeded in using another digital mode called WINMOR, which really feels like high-tech on HF. WINMOR is part of Winlink 2000, a system that is mostly designed to send and receive regular internet email through HF, VHF, and UHF radios.  It is used by radio amateurs, emergency organizations, and NGOs to communicate by email from places that do not have internet connections (like yachts, jungles, etc.). Winlink initially used an HF digital mode called PACTOR, which is very adaptive and efficient. PACTOR requires a dedicated hardware modem; the protocol is proprietary and the modems are expensive. A couple years ago Rick Muething designed WINMOR, an HF sound-card protocol for Winlink 2000 (on VHF and UHF Winlink uses AX25). I downloaded the software a while back but didn’t manage to connect to an HF radio gateway, and forgot about it.

Yesterday I decided to give it another try. The software uses a propagation prediction program and a list of active gateways to suggest gateways that are likely reachable. I tried to connect to the one that was supposed to be best, in southern Russia (on 14MHz). I heard the gateway respond and got a message that I was connected, but when the software tried to deliver an email message I sent, the gateway failed to respond and the connection was broken. I tried a few times and gave up. I also tried gateways in the Netherlands and Germany, but they did not even respond to me. In the afternoon conditions on 14MHz seemed to have improved, so I tried again. It worked! I received the mail I sent myself via HF! I replied and connected again to the radio gateway, and the response was delivered to me over the radio. Very cool.

I was later able to also connect to the radio gateway in the Netherlands, and to upload position reports to Winlink 2000, not just email. The Winlink web site shows the position of all the stations that uploaded position reports recently, and you can also view all the recent positions of particular stations. It’s quite interesting; many stations upload position reports from the middle of the ocean, as you can see here.

Winlink and WINMOR are really interesting. They deliver a useful service. Most of the time, sending email via WiFi, cellular, or wired networks makes much more sense than sending email over HF or VHF radios. But in emergencies and when you’re in the middle of the ocean, Winlink is a really useful service.  The protocol is very sophisticated, but you can sort of see some of what it is doing. You hear and see acknowledgements, retransmissions, and other protocol actions. But the biggest difference between WINMOR and many other HF digital modes is that it is an all-or-nothing protocol; it either delivers the data perfectly with no errors, or it fails completely. You don’t get garbled text. This is how modern communication works.

It’s not easy to set up radio gateways; the Winlink 2000 folks want gateways to run continuously (24 hours a day, every day), so setting up a gateway is not something to just experiment with, like I did with WSPR and APRS.

But WINMOR also has a peer-to-peer mode that allows you to communicate outside the Winlink system; perhaps I’ll try that.

First Steps with GNU Radio

GNU Radio is a package of DSP building blocks for constructing software radios. It is also the support software for a range of radio front ends from Ettus Research. You can also use GNU Radio with other radio front ends; I was able to easily use it with a Softrock receiver.

These radio front ends are a modular system containing motherboards and daughter boards. The motherboards have high speed ADCs, high speed DACs, and an FPGA for high-speed DSP. In most cases the FPGA does relatively little (but at high sample rates): decimation and digital down conversion on receive, and digital up conversion and interpolation on transmit. The rest of the signal processing is done in software on a PC (some motherboards have an embedded PC running Linux). The daughter boards typically contain transceivers or receivers that move the baseband signals produces or consumed by the motherboard to higher frequencies. I have the oldest motherboard, a USRP1, and a few daughter boards: BasicTX and BasicRX, which are just transformers that allow you to access the baseband signals directly, and an RFX400, which is an old transceiver for 400-500MHz. Newer transceiver boards cover much wider frequency ranges. Obviously, GNU Radio contains signal blocks that transfer samples to/from the hardware front ends (actually there are two versions of these blocks; I used the newer ones, called UHD).

GNU Radio (the software) consists of three main parts. One is a library of signal processing blocks (filters, demodulators, etc) written in C++. The second part is Python wrappers for these blocks. The Python wrappers allow you to connect the DSP blocks into a signal flow graph in Python, which is easier than connecting them in C++. The third part is GNU Radio Companion (GRC), a graphical environment for constructing these signal flow graphs. It allows you to construct interesting and working radios visually, without writing a single line of code. Very cool.

First, you need to install GNU Radio. The software has many dependencies, so installing it is definitely not easy. I installed it several times, on both Linux and Wiindows. Each time, some of the software worked but some did not. I don’t bore you with all the details. What worked best eventually was installing on Windows using Josh Blum’s detailed instructions. Even after I completed the install, GRC would not start; a dialog box suggested that I need to set two environment variables, PYTHONPATH and LD_LIBRARY_PATH. This turned out to be misleading, because on Windows you need to set PATH, not LD_LIBRARY_PATH. Once I figured this out and how to set the variables (by digging the sources to see what they were supposed to point to), GRC worked.

There are some blocks (some important) that do not work or do not fully work under Windows: The WX GUI blocks (which many GNU Radio example codes use), and the audio source and sink. As far as I can tell, the audio source does not work at all. The audio sink does work, but you can’t specify an audio device (which is possible in Linux). Also, in the other set of GUI blocks, the Qt blocks (which Josh added to GNU Radio), the slider does not work, which is fairly annoying.

On Ubuntu Linux, you can install GNU Radio and GRC from existing packages, but then the installation contains neither the UHD driver and blocks nor the Qt blocks. I tried to live with this, but the WX blocks did not work well, so I switched to an alternative installation method. In this method, you run a script that installs everything. The script worked well for me, installing a version with both UHD and Qt support.

With the software installed, I started experimenting with GRC (I actually started by trying to run the Python examples that came with GNU Radio, but they did not work because of some problem with the WX GUI blocks, so I switched to GRC experiments). To get started, I mostly used the tutorials by Sharlene Katz and the GRC examples by Alexandru Csete. Sharlene’s examples use the old USRP driver, not UHD, and they use the WX GUI blocks, so I could not use them as it, but her tutorials were very helpful. Alexandru’s examples are available for both the old USRP driver and for UHD, so they were mostly usable as is.

Here is a simple SSB/CW receiver that uses a Softrock as a front end. There is no tuning control (I controlled the center frequency of the Softrock from another application), but the receiver works and I was able to hear some CW signals on 14MHz. I think that writing a controller that would be able to tune the Softrock should not be that hard (since another Python program, Quisk, already knows how to do that).

My second GRC radio is a bit more complex: a narrow-band FM transceiver. I use it with the RFX400 transceiver, connected to the 430-440MHz home built Yagi. I can hear many FM voice signals, some from quite a distance. I was also able to communicate with Avishay Ginzburg, who lives about 4km away. It’s not that far, but the RFX400 only puts out about 100mW. Avishay complained that my audio was pretty bad, but he was able to understand me. There is also some problem with switching from transmit back to receive which I still have to investigate. In theory, when the USRP has no outgoing samples to send, it switches off the transmitter in the daughter board, allowing the daughter board to receive from the same antenna connector. I stop the samples from going out during receive using a signal processing block called a valve. In practice, the transmitter sometimes stays on, preventing the receiver from functioning properly. I don’t know if it’s a bug in my GRC radio or a bug in the valve or on the UHD driver. Anyway, here is one version of this transceiver (I keep modifying it).

My next plan is to see if I can hear satellites using this radio. I’m basically waiting for a satellite pass with a strong signal that I can easily hear using the FT-875D; once I hear one, I’ll switch the antenna to this software radio and see if I can see the signal on the spectrum display and hear the audio.

Soundcard now Decodes APRS

The comments by Julian and Marc on my previous post on APRS have been extremely useful. Julian pointed me to a writeup by John Ackermann that explains that APRS decoder do not work well when the 2200Hz tone is much weaker than the 1200Hz tone. I recorded a few packets and looked at the signal in Audacity, an open-source sound editor. Sure enough, the amplitude of the 2200Hz tone was much smaller than that of the 1200Hz tone:

John Ackermann’s article discusses one reason for this phenomenon: a modem that overdrives the transmitter. APRS packets are sent on VHF using audio tone that modulates an FM transmitter. FM voice transmitters pre-emphasize high audio frequencies and then clip the audio to limit deviation. If the modem overdrives the transmitter, low and high frequencies have the same amplitude. This seems fine, but the receiver de-emphasizes high frequencies, leading to the 2200Hz tone being too weak.

Initially I suspected that this problem caused my problems. I asked Avishay Ginzburg to send a few packets at his normal setup and then to reduce the drive from the modem. With a reduced drive, the overall amplitude of the received audio on my side was lower (both by ear and in Audacity), but the 2200Hz tone was still much weaker than the 1200Hz tone. So overdrive was not the problem.

Avishay’s signal is very strong in my home, so the signal-to-noise ratio that I initially suspected was not the issue either. Time to look for other suspects.

Marc’s comment on my earlier post suggested that the same problem could be caused on the receive side, by the interface to the modem or by the modem itself. I use a soundcard, not a hardware modem, but the sound-card interface certainly could be the problem. For the APRS experiments (or at least for most of them), I used a galvanically-isolated soundcard interface, not the simple interface that I described here a while ago. I switched to the simple interface; problem solved. I could now decode packets from a couple of stations, both stationary and mobile.

I also switched from the FM mode of the FT-857D transceiver to the packet mode. That may have made a difference too. The reason that I did not use the packet mode earlier is that the Windows software modems switch from receive to transmit using the RTS or DTS signals of a serial port, which is a mode that I don’t like to use. The packet mode on the FT-857D does not support sound-activated transmission (VOX), so I used the FM mode. Soundmodem, the Linux soundcard modem, supports receive/transmit switching using serial CAT commands, so I could use the packet mode.

Why was I able to decode ISS packets but not local packets? Perhaps I used the simple interface and not the isolated one, but perhaps I used the packet mode. The main conclusion here is that I should have kept notes on the setups that did work and on the setups that did not work, but I didn’t keep any notes. Big mistake.

Why does the galvanically-isolated interface act as a low-pass filter? I still don’t know. I should probably test the frequency response of the audio isolation transformers. The interface also includes resistors to drop the signal to a level that’s good for the microphone input of a sound card; perhaps the resistors formed an RC filter with some capacitance, or an LC filter with the transformers. The interface works fine for narrowband modes like PSK31 and JT65A, so I assumed it would also work for APRS, but this assumption is wrong; an interface with a non-flat frequency response may work fine for narrow-band modes but may fail for wider-bandwidth modes.

Soundcard APRS

Warning (added on June 14): the conclusions at the end of this post are wrong; see a followup post for a more likely reason for the failure to decode packets.

Over the past few weeks I’ve been trying out APRS, a digital communication mode that is popular mostly on the 144Mhz band. APRS mostly consists of short location announcements that are sent over radio. These are displayed on nearby radios that receive them, and if one of the receivers is connected the internet, which is often the case, they are uploaded to internet servers. Websites like and can display the information on a map. You can also use APRS to send email and announcements over radio, but the main use appears to be dissemination of location information.

Some high-end VHF radios have built-in APRS capabilities: they can transmit APRS packets (using a built-in or attached GPS to determine the location) and they can display received APRS packets. With less capable radios, you connect the radio to a computer via a specialized modem called a TNC, or you connect the radio to the computer’s sound card and use a software modem. Either way, an APRS client program running on the computer sends messages and displays received messages. I don’t have a TNC, so I experimented with software modems.

I started with a software modem program called AGWPE, which runs under Windows. Several APRS client programs can use it; the one I like best is APRSISCE32, but I’ve also used UI-View32. I set up the software and was quickly able to send location packets to nearby stations. In the screenshot on the right you can see my location, as received by a station about 30km away (interestingly, this station did not upload my position to the internet; it retransmitted it, and the retransmitted packet was picked up and uploaded by a station in Cyprus that is 350km away from here). Decoding packets was another matter. I heard packets on the radio, but the software did not decode a single packets. I decided to try another software modem, AX.25-SCS, also running on Windows (Thanks to Julian for the link). Same thing; I can send packets but I can’t receive.

I decided to see if I can send or receive APRS packets from the international space station (ISS). The ISS has a radio that is used for APRS most of the time, but not all the time. I waited for a convenient pass, tuned the radio, and heard packets being send from the ISS. The software, AGWPE, was able to decode some of them! Not all, but at least some. I don’t know if my packets were received by the ISS (they were not gated to the internet and I did not decode them being retransmitted, so perhaps the ISS did not decode my packets). Here is one: “UR3QLZ>CQ,RS0ISS-4*:Hello To All!  op. Grigorij qth Zaporozhye Ukraine KN77MT”.

I still could not figure out why the software was not decoding local packets, which I could hear pretty well. I disconnected the computer from the radio, and told APRSISCE/32 to transmit a packet. I could hear it in the laptop’s speaker. I recorded it with an iPod Touch. Then played it back, expecting the software to pick it up though the laptops microphone and to decode it. Nothing.

I got pretty desperate, but decided to try one more thing. I downloaded soundmodem, a software modem that comes with sources and which can be compiled under both Linux and Windows. On Windows, it depends on a lot more software, so I decided to use it on Linux instead. Same thing; I can transmit packets (send from Xastir, a Linux APRS client), but the modem won’t decode packets I hear on the radio. However, soundmodem has a diagnostic mode in which it will print out corrupt packets. Running it in this mode, I could see that the software decoded the packets, but very poorly (there were mistakes every few characters).

At that point I decided that the only possible explanation is that the signal-to-noise ratio (SNR) of the packets I’m receiving is just not good enough for the demodulator. That could explain why the software decoded packets from the ISS ,which is pretty far (several hundred kilometers) but within a line of site, but could not decode packets from terrestrial stations that I can’t see directly from my balcony (where the antenna is).

To test this hypothesis, I ran the software on the computer-radio setup that I normally use to stream VHF voice traffic to the internet. That radio is connected to antenna on a high roof, with good reception of repeaters up to 100km away. I installed soundmodem on it and waited for packets. It decoded them without any problem.

The main conclusion: APRS needs a really good signal-to-noise ratio to decode packets. I am not sure if hardware modems can do a better job than the software modems; I don’t see why they would.

Some technical comments on soundmodem:

  • Until the APRS client connects to it, it consumes 100% of the CPU; once it is connected, CPU usage drops dramatically. Seems like a bug that’s probably not hard to fix.
  • The software chooses a sampling rate, starting from 5000 samples per second and going up until it finds a rate that the sound card supports. This often leads to 9600s/s. I modified the code to start at 11025, as suggested in some forums. Not sure if it made any difference, but it still works 🙂
  • To get soundmodem to compile on Ubuntu 10.04, I had to install libxml2-dev, libgtk2.0-dev, and libaudiofile-dev. It is probably possible to install binaries from a package, but I didn’t try.

Controlling an Si570 from Java and Matlab

I am experimenting with software-defined radio (SDR) code in Matlab. One of the things I wanted was to be able to do is set the frequency of the Si570 that clocks the Softrock Ensemble from Matlab. Rather than write Matlab code to do that, I wrote a Java code to do that; it’s trivial to call Java from Matlab.

The Si570 is controlled through I2C by an AVR microcontroller, which is controlled in turn by a PC through a USB connection. The AVR’s firmware was written by Fred Krom (based on earlier code by Tom Baier). To communicate with the AVR from PC programs, Fred uses libusb, a portable kernel driver and a library that allows user-mode programs to communicate with USB devices.,  Fortunately, there is a Java interface to libusb. All of this software is open source.

I downloaded the library and installed it on Windows XP. This included a jar file (Java library) and a Windows DLL that needs to be copied to c:\windows\system32. Libusb consists of a couple of other drivers that need to be in c:\windows\system32, but they were already there. The test program that comes with Java libusb worked and listed the Softrock’s USB device. I wrote a small class that tries to open the device and read the frequency it is set to. It failed.

The code failed to open the device because Java libusb complained that the device has no endpoints (endpoints are logical USB communication channels). The trouble was that Fred and Tom’s firmware communicate only through the control endpoint, the one endpoint that always exists. The Java library assumes that the device would define at least more endpoint, which is true for most devices. But not for the Softrock’s AVR. I downloaded the sources of Java libusb, found the spot where it checks for the existence of endpoints (other than the control endpoint), and removed this check. Now the code works. Andreas Schläpfer, the developer who wrote the code, wrote to me that he’s fix the library.

Calling my Java code from Matlab was a bit tricky. I had to do two things to get it to work. I had to add the location of the Java binaries to Matlab’s Java class path using the javaclasspath function, and to add c:\windows\system32 to Matlab’s binary search path, which is listed in $matlabroot/toolbox/local/librarypath.txt.

That was it. Now I can set and read the Si570’s frequency directly from Matlab (and from Java code). The firmware has many other features that can be controlled by the PC, but they are less important to me now so my code does not support them.

The Matlab code to receive signals is coming along. By carefully reading part 3 of Gerald Youngblood’s article Software Defined Radio for the Masses and the corresponding text in Steven Smith’s book The Scientist and Engineer’s Guide to Digital Signal Processing (the corresponding text consists of most of this book:-), I was able to implement code that demodulates an SSB signal in the passband of the Softrock. Both sources are available freely on the web.