Many of the SDR projects we see use a cheap USB dongle. They are great, but sometimes you want more and — especially — sometimes you want to transmit. The Analog Devices ADALM-Pluto SDR is easily available for $200 and sometimes as low as $100 and it both transmits and receives using an Analog AD9363 and a Zynq FPGA. Although you normally use the device to pipe IQ signals to a host computer, you can run SDR applications on the device itself. That requires you to dig into the Zynq tools, which is fun but a topic for another time. In this post, I’m going to show you how you can use GNU Radio to make a simple Morse code beacon in the 2m ham band.
I’ve had one on my bench for quite a while and I’ve played with it a bit. There are several ways to use it with GNU Radio and it seems to work very well. You have to hack it to get the frequency range down a bit. Sure, it might not be “to spec” once you broaden the frequency range, but it seems to work fine. Instead of working from 325 MHz to 3,800 MHz with a 20 MHz bandwidth, the hacked device transceives 70 MHz to 6,000 MHz with 56 MHz bandwidth. It is a simple hack you only have to do once. It tells the device that it has a slightly better chip onboard and our guess is the chips are the same but sorted by performance. So while the specs might be a little off, you probably won’t notice.
The Pluto has several different ways you can communicate with it. For one, it looks like a drive plugged into your PC. That’s handy for updating firmware and things like that. There’s also a network connection that uses USB for the physical layer. This lets you move data back and forth or even get a command prompt.
Of course, if you want to use it with GNU Radio, you’ll need blocks to talk to the input and output. There are a few choices there, as well. Analog Devices maintains two different sets of blocks. The one that appears older is the PlutoSDR block but the IIO blocks seem newer and support a bunch of devices.
Unfortunately, building these blocks can be painful. I didn’t have any problem using the released version along with the GNURadio in the Ubuntu repos. But when I switched to the new release candidate, I couldn’t get it to build. It looked like I would need to manually build some libraries to get it all to work so I just stuck with the older version in the repos.
Changed the Same
For the receiver, if you have the IIO or Pluto blocks built, it is pretty much the same as you would do with any other SDR receiver. Sure, there are a few oddities. For example, since the device is connected via a network, you have to provide a connect string. If you can ping
pluto.local, you can use “ip:pluto.local” as the name. If you don’t have mDNS set up, you might need to use the IP address of the box.
Everything else is the same. You’ll want to respect the minimum and maximum sample rates, of course (have a look at the detailed specs). If you set the gain to auto, you’ll get errors trying to set the gain manually. You’ll also get them if you set the gain over the limit, around 70 dB.
Of course, the difference between the Pluto and your garden variety SDR dongle is that it has a transmitter, but if you know a little bit about radio, you won’t find transmission very confusing. IQ goes in and very low level RF comes out.
A Beacon for Pluto
I decided to put together a Morse code beacon for the two meter band. I’m a ham radio operator and the beacon will send my call sign, that’s perfectly legal. It turned out to show quite a few nuances of how GNURadio works.
You can find the
grc file on GitHub. You’ll notice that the transmit part is pretty simple. There’s the RF sink, of course, and a rational resampler to convert the CW tone from a 32 kHz sample rate to the higher sample rate used by the sink. The Pluto can only accept certain sample rates, and there’s no use generating a sidetone at high sample rates, so the resampler converts the lower sample rate to the higher rate. You can think of the new sample rate as
The real trick is how to get the Morse code you want to send to modulate the sine wave. There are probably many ways to do it, but I used a vector source. I have to confess I lifted this idea from [argilo] who has a lot of SDR examples on GitHub.
Even though newer versions of GNURadio have other mechanisms, in general, everything in GNURadio is a stream. So I needed a stream that looks like the code I want to send. The source has a stream where a 0 represents silence and a 1 represents tone. So a single 1 is a dit and three in a row make a dah or dash. The 0’s combine to make different size spaces. Now there are two problems. Getting the rate right and coming up with the vector data which is surprisingly tedious.
Fixing the rate is easy. The vector source gets you one sample each time someone gets one, which amounts to the sample rate. However, a dit at 1/32000 gives you about 31 µs, which is pretty fast. The repeat block interpolates the samples. All that means is that for each sample it repeats it a certain number of times before it gets another sample from the vector. You can adjust the speed by tweaking the interpolation.
The formula for the length of a code element in seconds is about
1.2/speed where the speed is in words per minute. There is a GUI widget to select the speed. The formula in the repeat block is:
int( samp_rate*(1.2/speed)). Just remember that slowing down the speed also increases the delay at the end of the message.
What that means is that a single 1 in the vector turns into a bunch of 1s at the output of the repeat block. You multiply the sine wave by these 0s and 1s, and you are good to go. That still leaves getting the data together.
True, you could just do it by hand, but that’s surprisingly tedious. I decided to take the time it would take me to get it right and write a little C program to generate the vector. Truth is, you could do the interpolation in the C code, but that would make very long vectors and it would also make it harder to change the speed at run time.
The C code does let you tweak what you put in for the code elements and the spaces. It is a simple program with no frills, but it gets the job done. You can redirect a file in and redirect the output file since there are no command line options.
I manually added a bunch of zeros at the end to space out the beacon. It might be a nice idea to add that to the program so you could specify a gap in seconds and the sample rate and it would add the right number of zeros. If you make that modification, don’t forget that the sample rate is divided by the repeat block’s rate.
I decided I wanted to have audio come out of the speakers when transmitting. There are at least two ways to do that. I could use another signal source to generate the tone and gate it with the stream of 1s and 0s. However, since the modulating tone is already at 1 kHz, it made sense to just pipe it to the audio. A complex to real block gets things set up to go to an audio sink that connects to the soundcard. I put a fast multiply constant in that multiplies the tone by 1. This would allow you to control the volume, but I only wanted to mute it, so a GUI widget can change the constant between 0 and 1.
If you want to try this, you should change my callsign on the beacon. You’ll also want to pick a good frequency that isn’t in use in your area, although the output from the Pluto is pretty weak and unlikely to interfere with a repeater that isn’t within walking distance.
If you run the flowgraph, you’ll hear the beacon’s sidetone from your computer speakers. If you have an FM receiver you should also be able to hear the beacon on the radio if you get the antennas close together. Because the audio tone is on and off, you may want to turn your squelch all the way down to hear the entire dot or dash since the squelch will usually cut a little off at the front end.
The user interface is ugly, but it could be made nicer with the GUI Hint fields and some attention. If you haven’t used those before, check out our GNURadio tutorial series.
I got tired of the beacon always transmitting when I just wanted to work on the code portion of it, so I added another multiply and a widget as an on-off switch so the output to the transmitter can be forced to zero without stopping the sidetone.
The truth is, the beacon would be better if I did a little waveshaping on the modulating pulses but for this low power beacon, it isn’t a big deal. You may also want to tweak the CW spacing to be more to your preference which is easy to do with the C program.
For experimenting, the Pluto is great. I sure wish it was able to tune below 30 MHz, though. However, if you have plans to use it for ham radio operations, you’ll probably want some filtering on the output and definitely some amplification. The little antennas provided are not going to do anything practical, either.
The photos of the hardware in this post are all from the Analog Devices Wiki.