Sunday, 24 February 2013

Arduino Beacon

Here's the story of my new multi-mode QRP radio beacon built around the Arduino - or, more properly, around my homebrew clone, the WotduinoTM.

I ended the post on my Arduino DDS shield with the words "perhaps I'll use the wait to start writing some Wotduino beacon code". Well, despite more than the usual volume of traffic of distractions keeping me away from leisure activities over the past few weeks, I've managed to steal some moments to keep me (nearly) sane...

The beacon started with the usual lash-up on the bench, hooking the previously reported Wotduino and DDS Shield up to a driver and a transmitter module, as previously used for the Raspberry Pi beacon...

You can see that - in addition to the usual culprits - there is also some evidence of a receiver, a key interface and a tuning control in the picture above (so you can guess what will be appearing in future posts).

The experimental beacon was soon pumping out its tidings of great joy and getting rewarded by acknowledgements on QRSS Grabbers, such as this very first spot, seen at PA9QV...

(I've added the red text annotation to help those new to viewing these images - first to decode the Morse Code in my FSK-CW signal and then to emphasize the italicized text version of my "Hellschreiber" call).

Simultaneously (or, at least, at different points in its 10 minute operating cycle) the Arduino Beacon produces WSPR messages and these were decoded and reported automatically by reporting stations all over the place. Here, for example, is a map showing good performance to the US on 11 and 12 February...

In the spirit of work that elevated the humble eBay DDS module to a fancy Arduino "Shield", I wanted to formalize the Arduino Beacon and so I have produced a "Transmitter Shield", which takes my QRP Tx Module (with its "Ugly weekender" heritage) and places it in the familiar "Shield" format...

This new shield includes a driver stage to amplify and distribute the DDS signal, a power stage (mainly used to provide 5V for the rest of the system from the "12V" supply used for the Transmitter), a Keying Stage which allows the Arduino to turn the transmitter on and off to without switching transients (which radio folk call "keying" - from the action of the telegraph key) and the RF power stage itself.

The power stage is simply two 2n3904 transistors which are driven to produce 500mW. This involves dissipating a fair amount of energy in the little transistors - so I treated them to a homebrew heatsink, hewn out of a scrap of Aluminium (apologies to our North American readers for the spelling lesson)...

The similar power stage in my "Funster Plus" rig doesn't have a heatsink - but the beacon spends a lot more of its duty cycle transmitting, so I felt it had earned the luxury of more effective heat management!

The Transmitter Shield sits on top of the existing layers to make a nice "Beacon Sandwich" (pun intended)...

To celebrate the new hardware, I took the liberty (and bandwidth) to send a more lavish (or, at least, more verbose) sequential multi-tone "Hellschreiber" proclamation, here seen at g3vyz

The beacon is still multi-mode; in addition to the modes seen above it also sends "m0xpd/arduino" in (QRQ) Morse and participates in the WSPR mode, as seen here achieving my best-ever westward QRP beacon dx to nj6d in Arizona...

As the Arduino does not provide such a rich programming environment as the Raspberry Pi, there were a couple of points at which my attempts to get m0xpd beacon operations running on the new Arduino platform threw up some issues...

Firstly, readers may remember my delight on discovering "Associative Arrays" - or "Dictionaries" as they are called in Raspberry Python land. I used these to look up the Morse code equivalent of a character in my messages back on the RPi beacon.

Arduino does not offer native associative arrays. You can, of course, use C libraries to pull in this functionality, but I decided to take a different tack...

My code on the Arduino looks for the ASCII value of each character in a Morse message, then uses this ASCII value to point to the appropriate element of a "char" array of strings of 0s and 1s, which represent the Morse equivalent of the character (0 for a dit, 1 for a dah). I started the array at the ASCII value (decimal) 40, as there's no character send-able in Morse before that.

The process is shown here in my routine to send FSK-CW (the straight CW routine uses the same resources)...

As an example, the comma has ASCII value 44, so its the fifth element in my array (Arduino arrays start from index 0)...


The second little wrinkle in the Arduino Beacon code was unexpected. The RPi has the luxury of an internet-derived clock, so timing for a beacon is supremely easy. By contrast, Arduino only has a counter which runs from the instant the program is started and from which time relative to that start instant can be computed. The counter is ultimately derived from the 16MHz crystal-controlled oscillator. 

Once I had my beacon up-and-running, I noticed that it was running slow - it would lose a few seconds every six hours, indicating that my 16MHz crystal was actually 15-and-a-bit MHz! I fixed it by telling the Arduino that there are only 59995 milliseconds in a minute and that - to the level of accuracy required - has done the trick. You can see the lie in the code excerpt below, which shows the (start of the) main timing loop of the beacon...

Now its time to try to find space - amidst all the distractions - to do some more work on the receiver side. 

...-.- de m0xpd


  1. Hi
    Nice hack
    It would also be funny to "stack" several TX shields and switch the DDS frequency and the working TX shield in a kind of round robin mode. Thus to be able to have a multi frequency beacon.


    1. Yes - I thought of that (so I got several of the DDS modules). You'd only need the one transmitter, which could transmit the sum of the several frequency components - this would allow my "Hellschreiber" characters to be more intelligible. Maybe one day...

  2. Is the beacon currently active? If so what is the frequency?

    1. Yes - it is sending QRSS signals on 7000840 and WSPR on 7040190

  3. Hello, this is a great writeup! Would you be willing to share the source? I'd love to try a version out for myself.



    1. Thanks for your comment, Patrick.

      I'm currently trying to finalize some plans for publication of some of the material on the blog (scheduled to "go public" in the fall) and I can't release the code until those plans are completed.

      The code will be available - but I'm not yet sure where and how - watch this space!