The Osmocom fan page

As you may have read on my dongle page I bought an SDR dongle. I like it so much I bought a second one since they're only $20. I had been using them in Windows with Sdrsharp, and RTL1090 with adsbSCOPE doing ADSB plane plotting. But I don't use Windows much or like it much, so I was tired of sitting around in Windows. It's only about 10% of my hard drive, and not anything I want to spend time on.

I've been trying to get rtl_fm working under OpenBSD for about 4 months, and somehow the project caught the interest of Stuart Henderson, who's one of the OpenBSD committers. He bought a dongle and it wasn't long after that before it was working. There will be an OpenBSD port coming out for rtlsdr in the standard OpenBSD ports/packages. As of now (4/25/2013) you have to go to http://www.openbsd.org/cgi-bin/cvsweb/ports/comms/rtl-sdr/ to get a copy. I edited the patches in manually, I didn't run them through the patch executable.

The Osmocom wiki page is at http://sdr.osmocom.org/trac/wiki/rtl-sdr and if you look on it you can find

git clone git://git.osmocom.org/rtl-sdr.git
which is how you grab the latest copy of the rtlsdr sources. Make an osmocom directory, cd into it, make another directory with the date, cd into that, then run git. I've been checking for changes every couple of weeks. Osmocom isn't some corporation, it's a non-profit, which is why it's a .org.

Getting it running without waiting for the port, well, loosely: You need a 1.x libusb and a recent cmake. Edit the files in the src directory to put in the patches. Patch will work, but I felt safer doing it by hand. Then cd .. out of the src directory and mkdir build (call it anything). cd into build and cmake ../ then gmake, and if there are no errors, gmake install. That's it. There's no 200 meg download like installing .net which you need for Sdr Sharp. It's all very small and fairly simple.

One thing you'll notice about the dongles is that they aren't exactly on frequency. There's a crystal in there, but no trimmer capacitor to get it spot on. What do you want for $20? You just have to live with it. One common feature in SDR Sharp (which uses an rtlsdr.dll from Osmocom) and rtl_fm, etc. is the ability to enter a ppm (Parts Per Million) frequency correction value. That works pretty well, but it only takes integers, so it's not entirely adequate. If you've got an HF upconverter and you want to specify a frequency like 6.33856 MHz to get WEFAX images tuned right in USB (upper sideband, not universal serial bus) mode you'll find integers aren't close enough. With the sideband modes, the audio frequency depends on the RF frequency, and most of the digital ham modes that transmit via audio depend on certain audio frequencies. You can always manually fine tune it, but that means you have to be there to do that, you can't script it.

Once you get a ppm figure and start using it you'll find it isn't too bad for some modes at least. One of my dongles needs a 102 ppm correction and the other needs 62 ppm. There is a tiny amount of drift but the ppm error is much greater.

There's a program called rtl_test in the Osmocom suite, which if you give it a -p on the command line is supposed to give you a parts per million error, but I calculated mine before I had that working. Being an Extra Class ham, and having held an FCC First Class Radiotelephone license, I'm supposed to know how to do such things.

Pick a few (2 - 5) on-air NBFM signal sources that you trust to be on frequency. They should be ones that are on most of the time so you can measure them. Go into Windows, start SDR Sharp using the dongle you want to calibrate. Be sure the ppm correction is empty or 0. Find one of your signals that you know the frequency of, click on it, and keep zooming in until you get the cursor line exactly on the peak.

In Sdr Sharp set your step size to about 100 hz or less. You can't click within your filter passband, but get close then click in the frequency box to give that the focus. Then use the up and down arrows on the keyboard to move the cursor line, which jumps ± the step size. I tune around that way sometimes.

I use the National Weather Service transmitters around 162.5 MHz as beacons sometimes so I used 2 of those and 2 ham repeaters to measure. They're all supposed to be checked at least yearly. In this example I'm looking at a ham repeater on a known frequency of 146.985 MHz, and I measure it as 146.970. I work entirely in Hz here, partly because that's what the dongles use:

    146985000
  - 146970000
   ----------
        15000    (15 KHz error)
        
15000/146985000 = 0.0001020512

0.0001020512 * 1000000 = 102.05 ppm        
Do this with several transmitters and calculate an average. This 102 is as close as I can get on this one, but my other one at 62 ppm seems to be closer to most transmitters. With only integers for correction values, you're likely to jump from one side of the right vaue to the other side. In narrow band FM, if you're off frequency by 5 KHz you can still understand what's being said but there's some distortion. If the frequency is in the 850 MHz range and you need to be within 5 KHz, that's a 0.005882 percent tolerance. Expensive crystals in ovens we don't have. These numbers are exactly what I use: don't put a minus sign in front of them. Test your ppm figure in Sdr Sharp first: your peaks should now appear at the right frequencies. It's at the bottom of the config window.

The higher the frequency you use the more accurate the result will be. I don't have much in the way of stable UHF signal generators, but I just (5/23/2013) redid my ppm estimate. I used a programmable scanner and my ham rig, but 2 scanners would work for this method. Use a calculator and keep notes until you're done, in a file is fine.

Every receiver has a 1st local oscillator, and scanner oscillators are usually accurate and stable. Being programmable makes it versatile. The oscillator runs at the input frequency +/- the 1st IF frequency. A common 1st IF is 10.7 MHz but 10.85 and other values are also used. Try 10.7, but look for a pdf on the scanner if that doesn't work. It's probably in the specs since it affects image rejection. If one of your scanners is usually distorted or you suspect it may be off frequency, use that one to just listen on (as the second scanner).

All you need the second scanner for is to confirm that the first is doing what you expect. I set my second one to 465 MHz. The first scanner has an IF of 10.85 MHz so I set that to 475.85 Mhz and heard a strong signal in the second one. They were a few feet apart, not connected at all.

Since you're working at the highest frequency you can, you need to find a frequency that's in range of all 3 pieces of equipment, and that putting scanner 1's oscillator at that frequency is still in range.

When you can get a stable signal in one scanner from the oscillator of the other you're ready to start working with the dongle. Turn off your second scanner and tune to the same frequency with the dongle. You probably want to turn off any existing ppm correction first. You need to tune either the dongle or the scanner until you hear a signal, then fine tune by going both sides of that until you lose the signal. You can assume that halfway between the frequencies where you lose the signal is the right spot. It doesn't matter whether you vary the dongle or the scanner tuning, whichever's easier.

You can either calculate the ppm value as above or just start changing the ppm correction to get the dongle so it hears the test signal at the right frequency. An initial calculation then a tweak or two usually works well.

If you're getting a really strong signal into the dongle it will probably make the tuning broader. Try to keep moving them apart or put one in a metal container.

The osmocom suite was designed to run on non-fancy single-board computers and it's all command-line based. This was my first nbfm test:
 rtl_fm -N -S -l 128 -p 102 -f 146985000 - | play -t raw -r 24k -e signed-integer -b 16 -c 1 -V1 -

To break that down, I'm running rtl_fm, the -N specifies narrow band FM (these are all case-sensitive). The -S specifies sync mode (async doesn't work under OpenBSD yet) transfers from the USB port. The -l 128 sets the squelch level. (that's a lower case L). The -p 102 is the ppm correcton for this dongle. The -f 146985000 specifies the frequency of the local 2-meter ham repeater (in Hz). The - | says to send the output to stdout (standard output) and pipe it into play.

Play is part of Sox, which isn't native to OpenBSD. aucat will also work, or aplay (Alsa Play) if you're under Linux. Or you can use nc (netcat) to send audio out a TCP/IP port to another machine. In short, what comes after the | is up to you. This is play/sox syntax. Here the -t raw says that this is raw audio data that doesn't have a tidy header like a wav file does. The -r 24k is the audio sample rate. The -e signed-integer specifies the data type as signed (±) integers, the -b 16 says that each sample is 16 bits. The -c 1 says 1 channel (not stereo), and -V 1 sets the verbosity level. At the end is another - that specifies that input comes from stdin (standard input).

You don't have to remember and type all that each time of course, you write a little script that does it for you. One advantage of rtl_fm over Sdr Sharp is that rtl_fm can scan. You use a -f <freq> for each frequency. I made a script called stpol that scans a bunch of Massachusetts State Police frequencies:

#!/bin/sh
rtl_fm -N -S -l 132 -p 102 -f 854040000 -f 854240000 -f 854315000 -f 854415000 -f \
854490000 -f 854540000 -f 855165000 -f 855240000 -f 858790000 -f 867350000 \
-f 867715000 - | play -t raw -r 24k -e signed-integer -b 16 -c 1 -V1 -
Most times of day or night this script will give you plenty to listen to. I found these frequencies with Sdr Sharp, clicking on peaks when somebody was talking, then carefully zooming in to get the exact frequency. I had to shut it off to write this because it chatters too much and I couldn't concentrate. The same frequencies may work in other parts of the US, because the FCC allocates them to police and re-uses them in different areas that are far enough apart geographically to avoid interference. 850 MHz doesn't travel very far.

The - at the end of the rtl_fm command line sends output to play, but it will also send to a file. A variation on the script above I called stpol1rec records to a file:

#!/bin/sh
rtl_fm -N -S -l 128 -p 102 -f 854040000 -f 854240000 -f 854315000 -f 854415000 -f \
854490000 -f 854540000 -f 855165000 -f 855240000 -f 858790000 -f 867350000 \
-f 867715000 /tmp/stpol.raw
It isn't a wav file, but there are ways to convert it to one if you want to. Sox will do conversions like that, or you can import into Audacity and write to a wav file from that. wav files are what's called self-describing, which means all the data like the sample rate is in the header. The problem with them is that the file length is also in the header (at the beginning). There's no official way to make a wav file without knowing at the start how long it's going to be. Truncating them usually works, depending on the playing software.

One neat thing about recording from rtl_fm is that it only records while the squelch is open. There are no pauses or silent periods in the recordings. You could start it in the morning, go to work, and come home at night to a condensed recording of everything that happened that day. Such things are often in police shows as logs. If you were monitoring a ham repeater you'd have a log of repeater traffic. Convert them to mp3 files, burn them to DVDs, and you've got a cheap permanent log. There are probably better choices than mp3. You could record, convert to wav files, burn onto rewriteable CDs, stick them in the player in your car and listen to a condensed day's audio traffic while you're driving. You could condense aircraft audio from the 120 MHz band to make it more interesting.

Here's a similar script that scans aircraft frequencies, air1:

#!/bin/sh
rtl_fm -M -S -l 132 -p 62 -f 123000000 -f 135675000 -f 123750000 -f 122700000 \
-f 125350000 -f 133600000 -f 118350000 -f 134850000 -f 119600000 -f 122950000 \
-f 121500000 -f 126450000 -f 121600000 -f 127800000 -f 126450000 -f 122800000 \
-f 135675000 -f 135875000 -f 119025000 - | \
play -t raw -r 24k -e signed-integer -b 16 -c 1 -V1 -
This one is set for 62 ppm correction for the other dongle. It works, but it isn't quite as nice. There's a note somewhere in the comments in the rtl_fm source code that the squelch needs more work. Squelch in a scanner is an odd thing: set it too high and you miss everything, too low and it locks onto a noisy channel and you don't hear anything else. Setting squelch in AM is tricky anyway.

Also, the volume varies with signal strength just because it's AM. Since the planes are at different distances and altitudes they're all different volume levels. I don't know if there's any standard transmitter power. I'm just using the default AGC setting.

I've got a fat dipole (vertical) cut for 125 MHz in the attic so there's plenty of signal. I hear some pilots talking on top of other pilots: I don't know if they really are or that's just because the filter bandwidth needs to be narrowed up a tad. I'm not real close to any airport, but I've got 3 at distances of about 80 miles in different directions so it's quite possible they are talking on the same frequency but don't hear each other.

One other thing about these programs is that there's no documentation to speak of yet. The ultimate reference of course is to poke around the source code to see what does what. It's changing too fast to be otherwise. Each program has a little "usage" function which is intended for a quick reminder. Anyone who adds a feature (usually) adds a line to usage that describes it. You can cause the usage output by anything on the command line that the program doesn't recognize, but a fairly standard way of triggering it is to use something like rtl_fm --help. It would do the same thing with rtl_fm --foo.

rtl_fm's usage as of 4/23/2012:

rtl_fm, a simple narrow band FM demodulator for RTL2832 based DVB-T receivers

Use:	rtl_fm -f freq [-options] [filename]
	-f frequency_to_tune_to [Hz]
	 (use multiple -f for scanning, requires squelch)
	 (ranges supported, -f 118M:137M:25k)
	[-s sample_rate (default: 24k)]
	[-d device_index (default: 0)]
	[-g tuner_gain (default: automatic)]
	[-l squelch_level (default: 0/off)]
	[-o oversampling (default: 1, 4 recommended)]
	[-p ppm_error (default: 0)]
	[-E sets lower edge tuning (default: center)]
	[-N enables NBFM mode (default: on)]
	[-W enables WBFM mode (default: off)]
	[-S force sync output (default: async)]
	 (-N -s 170k -o 4 -A fast -r 32k -l 0 -D)
	filename (a '-' dumps samples to stdout)
	 (omitting the filename also uses stdout)

Experimental options:
	[-r output_rate (default: same as -s)]
	[-t squelch_delay (default: 20)]
	 (+values will mute/scan, -values will exit)
	[-M enables AM mode (default: off)]
	[-L enables LSB mode (default: off)]
	[-U enables USB mode (default: off)]
	[-R enables raw mode (default: off, 2x16 bit output)]
	[-F enables high quality FIR (default: off/square)]
	[-D enables de-emphasis (default: off)]
	[-C enables DC blocking of output (default: off)]
	[-A std/fast/lut choose atan math (default: std)]

Produces signed 16 bit ints, use Sox or aplay to hear them.
	rtl_fm ... - | play -t raw -r 24k -e signed-integer -b 16 -c 1 -V1 -
	             | aplay -r 24k -f S16_LE -t raw -c 1
	  -s 22.5k - | multimon -t raw /dev/stdin
rtl_fm can also do AM or SSB as you can see above. With an upconverter to put HF within the tuning range of the dongle that can be useful.

The program called rtl_test:

rtl_test, a benchmark tool for RTL2832 based DVB-T receivers

Usage:
	[-s samplerate (default: 2048000 Hz)]
	[-d device_index (default: 0)]
	[-t enable Elonics E4000 tuner benchmark]
	[-p enable PPM error measurement]
	[-b output_block_size (default: 16 * 16384)]
	[-S force sync output (default: async)]

And another program called rtl_sdr:

rtl_sdr, an I/Q recorder for RTL2832 based DVB-T receivers

Usage:	 -f frequency_to_tune_to [Hz]
	[-s samplerate (default: 2048000 Hz)]
	[-d device_index (default: 0)]
	[-g gain (default: 0 for auto)]
	[-b output_block_size (default: 16 * 16384)]
	[-n number of samples to read (default: 0, infinite)]
	[-S force sync output (default: async)]
	filename (a '-' dumps samples to stdout)

There are a few other programs in the suite, but they all expect to do async USB bus transfers, so they don't work under OpenBSD yet.

If you happen to have fldigi installed on the same machine, it can see the audio from rtl_fm. That means that with an upconverter fldigi can decode the digital ham mode signals that the dongle and upconverter can tune. You'd want to use USB or LSB demodulation because they all work with certain audio frequencies.

The cpu usage is quite low. On my Dell Latitude D530 laptop with a Core2 Duo 2 GHz cpu (circa 2008), it runs close to 5% if there's audio coming in. When scanning, if nothing breaks squelch, it's under 1%. Memory usage is about 2.5 megs. It would coexist with something like Fldigi very well.

I started with this on my laptop under OpenBSD 5.2, but then I also installed it on a desktop machine with OpenBSD 5.0. 5.2 has major changes to pthreads, but they don't seem to be necessary.

5.0 doesn't have libusb 1.09 in ports, so I installed it from a libusb.org tarball. The only thing out of the ordinary I did was to run configure with --disable-timerfd on the commend line. Without that I got a "Library error -99" after playing a few minutes. Googling indicated that timerfd was the problem. It didn't cure it though. I tested with a local broadcast FM station for over an hour and didn't see it. But scanning it happens more often for some reason. It must be the extra traffic on the USB bus to change frequencies. That's only with OpenBSD 5.0 though, I've left 5.2 scanning overnight.

There is an odd noise like a squelch tail that happens possibly every scan cycle. I thought it was a particular frequency causing it, but I took them all out one at a time and couldn't find it. It might make sense to sort them by frequency so that the vco has an easier time of it, but I've already done that. Maybe it won't happen with another set of frequencies.

AB1JX / Toys