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.