20 meters, 200mW & 12,000 miles: WSPR magic!

Weak Signal Propagation Reporter is a global radio propagation monitoring and reporting network comprised of thousands of low power beacons operating on the amateur radio bands. WSPR beacons can be detected from the lowest of Medium Wave frequencies (137kHz) all the way through the HF spectrum (all the bands from 160m to 10m are popular) to the VHF bands, 50 and 144MHz. WSPR receivers decode the tiny beacon packets and upload them to a central database, at WSPRNet.org, where anyone can literally ‘see’ the propagation paths that are currently open.

Equally, you can go back and revisit the radio frequency propagation conditions during any previous time window. Running a WSPR beacon from your home allows you to ‘watch’ the propagation paths open, peak, and close each day under the influences of solar radiation, sunspots, and other ionospheric conditions. Arduinos and a few common accessory boards that can be had for tens of dollars make a beacon accessible to just about any experimenter (with an amateur radio license).

WSPR beacon in an Arduino Uno prototype case.

I’m late to the WSPR party. I’ve wanted to try a beacon project for a few years. A while back, I took a copy of the ZachTeck script and experimented with it and a Ublox GPS, but after getting the NMEA strings decoded from the GPS unit at roughly one second intervals, the rest of my code was over-engineered and bloated, and did not fit into the small memory constraints of the Arduino Nano. I put is aside.

Recently, I did a much needed upgrade to my Arduino IDE and libraries. The thought occurred to me that improvements to both IDE and libraries may give me a fighting chance of getting that old WSPR script fitting. When I opened it up, and started to work through it, I saw some obvious ways of reducing memory usage. I had too many String objects (memory-hungry). And my code was writrten to parse each NMEA message string and tokenise it. This allowed me to get to discrete data fields a long way down the messages, like the number of detected satellites. In a simple WSPR beacon, all you really need is the UTC timestamp at the very start of a number of the NMEA messages. I ditched the superfluous stuff and got it uploading, and more to the point, not hanging!

WSPR dataset applications

WSPR is brilliant for teaching you about rare and exotic places that you feel compelled to Google when they turn up on your map in the morning, places like Orlygshafnarvegur (TF4AH, Iceland) or Fuerteventura (EA8BFK on the Canary Islands).

The database of historical propagation across the HF spectrum is widely used by amateur researchers to learn about propagation and has some more serious applications as well. Experimenters have used the data to support ideas or research questions about how symmetrical propagation is at opposite sides of the globe in the same period, and to test antennas. More seriously, a theory was proposed that impressions in the WSPR dataset may indicate the path of the lost flight, Malaysian Airlines flight MH370.


The script is here: https://github.com/prt459/WSPR_GPS_Beacon


The schematic is so simple it really doesn’t need a kicad. The Ublox 6M GPS connects to Arduino D2 and D3 for serial data transfer. It also needs GND and +5V. The si5351 breakout board uses I2C and so goes to Arduino A4 (SDA) and A5 (SCK). Connect the si5351’s CLK0 to whatever low power HF amp you like. Mine is from Experimental Methods in RF Design (EMRFD), Fig 12.32, but I could have chosen any number of similar two-transistor stages.

WSPR works on truly tiny power levels. If you connect the bare si5351 clock output to an antenna, you will get decodes! (You should add a Low Pass Filter if this is anything more than a quick test). So use a single 2N3904, or anything with gain, up to a full 5 watt QRP PA with an IRF510 or Mitsubishi RF FET, which is a ‘big gun’ in the WSPR world. Mine uses a 2N3904 and 2N4427 in common emitter feedback configuration, delivering around 10 volts peak to peak into 50 ohms, followed by a W3NQN Low Pass Filter for the band of interest.

200mW QRP PA.


20 meter European WSPR decodes from the beacon in Melbourne Australia. 12,000 miles on 200milliWatts!
More European decodes, and a spot from Auld Blighty!
And a decode in the USA in the same timeslot, about an hour before sunset.


Thanks to Harry from ZachTek for making his code open source. And to Jason Milldrum NT7s for his si5351 and JTEncode libraries.

SPRAT #192

After publication of this project in the RSGBs SPRAT #192 Autumn 2022 a number of builders commented below the post or contacted me with build reports and questions.

First, the 12v DC series decoupling resistor was not labeled in the published schematic, it can be anything between 47 and 100 ohms (see corrected scheatic below).  

Schematic errata.

Secondly, Ian McCrum did an LTSpice model of the PA which revealed that I omitted  a resistor from the original design in EMRFD (in parallel with the 100n coupling capacitor between the stages) which forms part of the biasing of the PA transistor. If omitted, the PA works, but with reduced power.  Adding the resistor increases the RF power output to around 0.5W, although this will vary depending on drive level, the PA transistor, and the DC supply voltage. Thanks Ian for taking the time to LTSpice this QRP PA.
Steve K8SDK got more power out of his PA by increasing the si5351 drive level from 2MA (my value) to 4, 6 or 8MA.  There is a general understanding and some analyses that report the si5351 clock phase noise gets dirtier as you go up in drive level, and for this reason I left it at 2MA.  But with sub 1 watt power levels and a LPF on the output I don’t think it would make any practical difference.

On the question of WSPR beacon power, I don’t think 0.5W is preferable to 0.2W under curent band conditions. With 0.2W the decodes at DX WSPR receivers get marginal and the spread of the band opening can be seen as the grey line moves across the globe. Higher beacon powers can result in saturation which looks like a more rapid ‘lighting-up’ of the remote receivers on the map, and the subtleties of propagation can be lost. This is another way of saying that you should really use a minimum power necessary to get decodes at the far end. However my preference for low power is a personal preference, and some may need slightly higher power to overcome antenna losses.

Several people reporting having to use the set_correction() call with the second parameter (around line 320). I added a comment note immediately above the call in question:

// NOTE: There was a library change to the signature of this method. If you get a compiler error, try this:
// si5351.set_correction(19100, SI5351_PLL_INPUT_XO);

I did it this way to allow for compatibility with subsequent versions of the NT7S si5351 library. But a few people got the compile error and did not trace it back to the offending source line, or perhaps read the comment. I should have just made this change in the repo code to make it foolproof for all comers.

Neil G0ORG emailed with a question about si5351 calibration, his calibration attempt resulted in a value of 149850 for the call to set_correction().  I personally have not seen a calibration offset that large, however, the tiny crystals on the Adafuit and clone breakout boards must vary considerably. Neil reported that this offset pulled his si5351 outside the WSPR passband — we are not sure what went wrong with the usual calibration process for this to happen, bit Neil got his beacon back on the spot by experimentally reducing this large offset value.

Stephen G3ZNG had problems compiling the sketch, and after a bit of investigation discovered he had a previously installed JTEncode library. Upgrading the library fixed the problems and Stephen reported his beacon was working.

Chris G4BMW had the same problem. When he installed JTEncode v1.3.1 and Si5352 v2.1.4 it worked. Chris then discovered that GPS units do not always work inside, and had to move his unit next to a window to give the GPS receiver a sniff of the overhead statellite’s signals.

John G8CHP emailed me a photo of his completed WSPR beacon in a sandwich box. John reports spots in western Canada from his QTH on the east coast of the UK. John used a QRP Labs QLG1 GPS unit, mainly because it was on hand, and a 2N3866 for the PA.

Jonathan G5LUX got his beacon working on a breadboard, and it worked first time.

Aaron K5ATG emailed to discuss his build options, saying that most commercial WSPR beacon products are reasonably pricey for what they are, and my design is made from just a handful of commonly available components, most of which he already had.

Nigel, G4ZA emailed me to say that he had also come up with his own homebrew WSPR beacon, and that Harry’s code (Zachtek) saved him a ton of work too.

Steve K8SDK used three FETs (presumably in the conventional Class E PA configuration as used in many QRP CW PAs) (see comments below post).

And finally, Dave AA7EE has done a superlative job of building his own WSPR beacon using my script, and of course, his blog write-up is amusing, informative and a celebration of the finest amateur radio homebrew spirit. Dave set up his beacon on 10m but had si5351 stability issues which he describes in detail. He solved the drift problems with patience and experimentation, eventually settling on 20m. His post shows remarkable QRPp WSPR results. Thanks Dave for the acknowledgments peppered throughout your post. (See also Dave’s comments below).

A number of builders commented below the post, please read for further discussion. As well, I did receive other emails so if I have missed you please leave a comment below.

Beautiful and thoroughly photographed and documented build by Dave AA7EE.

Working beacon by G5LUX

Nicely packaged beacon built by John G8CHP.
Tagged , , , , , , ,

26 thoughts on “20 meters, 200mW & 12,000 miles: WSPR magic!

  1. Andrew VK1DA says:

    Great job with the WSPR tx. I’ve used WSPR a few times, usually at about 1w or 2.5w from the 817. But I prefer to use my antenna for making other types of contacts. I am very dubious about the proposal that a tiny plane at 12 km above ground level will make any detectable dent in the signal strength of a dx WSPR signal on HF, that is mainly reflected by a relatively huge ionospheric layer at 120-150km agl. In addition to the level of reflection or interruption of an HF signal, there is the problem that WSPR logs signals over a 110 second integration time, recording only one signal level for the entire reception period. Studying WSPR logs from a typical HF transmission shows signal levels varying over sometimes more than 10 db in successive time periods, so to my mind it is not even valid to use WSPR signal levels over dx paths to make antenna comparisons, unless simultaneous transmissions and common receiving sites were used. Successive transmissions within 2 to 10 minutes vary so much on a single antenna that any meaning attributed to signal differences is unfortunately, illusory, IMO. 73 Andrew vk1da


    • Paul Taylor says:

      G’day Andrew. Thanks for commenting. I think I read somewhere the same scepticism re use of WSPR data to track an aircraft. Just way too many unrelated variables. We can dig into the analysis piece on the linked site if we wish, I note the WSPR data is correlated with other data to some claimed utility.
      The spots I’ve been getting on 0.2W 20m WSPR hint at improving propagation. It bodes well for /P CW DX on 20m!
      Cheers Paul VK3HN.


  2. Andrew VK1AD says:

    I’m operating WSPR on 30m @200mW. Getting EU decodes during the last 90 min before VK east coast sunset. Good sign for late afternoon SOTA activations during grey line propagation.

    Liked by 1 person

    • Paul Taylor says:

      Gday Andrew, thanks for that report. Similar to my experience on 20m over the past week for the same power level, 5.30pm DST for about an hour for EU. Its impressive the way they just suddenly appear within minutes. USA west coast around sunset to 8pm. As you say, a good sign!


  3. Loren Moline says:

    Paul, I can not get your sketch to compile.


  4. Steve Kaatz says:

    Hi Paul, thanks for posting this and the video. Great work. I’ve been tiptoeing up to building a WSPR beacon and have been looking at the project in the Jan 2022 QST, or duplicating the project by Harry from Zachtech. Your simplification is exactly what I want to do with it!. So far I’ve played around quite a bit with a 5351 breakout board and am bedeviled by a problem with mains frequency and 1st harmonic on the SI 5351 output. But I have a question which is how do you tune or correct inaccuracies in the Si5351? I have 2 units and they’re both slightly off frequency. I suppose any offset could be hard coded in each band frequency setting, but I’m wondering if there is a way to set it universally? Thanks again & best 73’s. Steve K8SDK


    • Paul Taylor says:

      Hi Steve, thanks for your comment.
      A WSPR beacon can be quite simple. You don’t even need the GPS unit, you can manually synchronise a software clock, but I want to just turn it on and let it work. The uBlox GPS receiver is cheap, connects with 4 wires and automates the transmission timing.
      I have never had si5351 problems related to mains frequency. However, every one of these si5351 breakout boards comes up on a slightly different frequency. You need to do a one-time calibration, which will deliver you the calibration offset to be passed into:

      si5351.set_correction(19100, SI5351_PLL_INPUT_XO);

      In this case, the 19100 is a fixed offset that you determine by running a calibration script, which you should find in the src/ dir of your installed si5351 library. Load this script and run it, it will generate 10MHz. Measure this on a reliable oscilloscope or frequency counter. Then use the console to key in menu options to shift the offset, which will shift the 10MHz clock#0 output. Keep doing this until you get as close as you can to spot on 10MHz. You should then be able to read off the numeric offset number. It will most likely be in the 15000 to 30000 range. Put this value into the si5351.set_correction(,offset>, SI5351_PLL_INPUT_XO) call. This will usnure your si5351 clocks are all on the mark. Read up on the calibration approach for your particular library. I use the one by Jason NT7S.
      Good luck with your beacon project, let me know here if you get it working, or, have problems with my script.
      73 Paul VK3HN.

      Liked by 1 person

      • Anonymous says:

        Hi Paul, I had to set the project aside for a while but your script works really well now. I’m using a very simple PA with 3 MOSFETs, getting about a watt out on 20M. I added a line to your script to increase the Si5351 output level, which helps drive my amp. Thanks again and best 73’s Steve

        Liked by 1 person

      • Steve says:

        Hi Paul, I had to set the project aside for a while but your script works really well now. I’m using a very simple PA with 3 MOSFETs, getting about a watt out on 20M. I added a line to your script to increase the Si5351 output level, which helps drive my amp. Thanks again and best 73’s Steve

        Liked by 1 person

  5. Ian McCrum says:

    Hi Paul, I just put your circuit through LTSpice, I wonder if there should be a 2k2 resistor across the capacitor that goes from the stage 1’s transformer and the base of the second transistor. Wes has one in EMRFD, Fig 12.32. I get more output with it in.

    I just read your article in SPRAT, inspiring, thank you.
    Best regards, Ian MI5AFL.


    • Paul Taylor says:

      Hi Ian, thanks for your comments. That’s interesting, I’m on my way to work now but will check EMRFD when I can. I don’t normally parallel inter-stage coupling capacitors with a resistor, and I did not notice it on the original schematic. But if Wes did it, it must be right! The capacitive reactance of the coupling capacitor at HF is small, so the resistor must be contributing to the second stage’s DC base biasing. I wonder if Wes mentions it in the text.
      How much power change do you see in your LTSpice model with it in? Might be time to build it and see 🤔?
      73 Paul VK3HN.


      • Ian McCrum says:

        I get 360mW across a 50 Ohm load on the output with a 2k2 across the inter-stage cap and almost nothing without it – using a 224mV square wave input with a series resistance of 50 Ohms (1mW). The standing current is 30+mA and the standing dissipation in Q2 about a third of a watt. I initially put a 1k2 from the second base to its collector (across the AC feedback RC) which also gave an output but I then checked EMRFD and removed it and used the 2k2. Now, I know little about designing Class-C amplifiers and I am in a little doubt as to an Si5351’s output impedance. Since you are driving the amp with a single frequency (albeit a squarewave) I suppose the filter removes all distortion and you can overdrive the second stage. I have used LTSpice a lot but you’re right, I should build it. The map is not the territory.


  6. Anonymous says:

    I just read your article on SPRAT thanks.


  7. Ian says:

    As regards LTspice simulations and whether or not a 2k2 resistor is needed across the interstage capacitor (as per Wes’s original fig 12.32 in EMRFD). You do NOT need the resistor if the input is above half a volt. This is enough to have the output stage conduct and generate power. At 300mV pk input you get 375mW output with the 2k2 and less than 200mW without it. If the input is strong enough then the output is high and the overall DC power consumption is lower. I must learn more about class C, or at least non class A amplifiers…


    • Paul Taylor says:

      Thanks for your detailed analysis Ian. My amplifier is driven directly from an si5351 clock. I have observed the amplitude of such clocks to vary quite a bit, with load, and frequency. Without scoping it, which i will do when I can, I suspect my clock’ s drive is 3 to 500mV peak, as I excluded the 2k2 resistor, and measured around 200mW at the dummy load and antenna. I’ll add in the 2k2 and report the improvement. Best regards, Paul VK3HN.


  8. AA7EE says:

    Hi Paul, and thank you for such an inspiring SPRAT article and blog post! I’m not sure how I missed this post the first time around, but your article in SPRAT tickled my fancy, and sent me to this post. I’m putting together this project, though with the PA used by Hans Summers in the QRP Labs Ultimate 3S QSPR transmitter. It’s a single BS170 MOSFET in a very simple circuit, and puts out 250mW when driven with the maximum output from the Si5351, though I think I will set the bias so as to produce something less than the absolute maximum output power.

    On first firing it up, it took me a while to figure out why I was only getting 30mW from the rig. I realized that the code didn’t include a line to set the output power of the Si5351, and guessed that it was probably producing the default drive strength of 2mA. After the line –

    si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);

    I inserted the following line –

    si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);

    and suddenly, my little TX was producing anything up to 250mW on 10M, depending on where I set the PA bias. I’m curious as to why you used a slightly more complex PA, when setting the drive from the Si5351 higher, could have resulted in being able to employ a simpler PA stage?

    On the other hand, I was happily getting spotted all over the US today with just 30mW of output power. QRP really is king with these low power digital modes. Once again, thanks for all the great information and inspiration!



    • Paul Taylor says:

      Hi Dave,

      Good to hear from you. You’re right about the si5351 drive strength, I let it default to 2MA, the lowest drive level, and this PLL’s drive is limiting the beacon’s RF output power. When the IC emerged about 5 years ago there was a lot of discussion about jitter and signal quality. One of the conclusions was that the signal quality decreased slightly as you set higher drive levels (4MA, 6MA, 8MA). This thought lodged in my brain and I have rarely used the 8MA setting in any of my projects. I tend to not worry about a little bit of additional circuit complexity, as I enjoy building as much as anything.

      I didn’t think of your idea and perhaps if I had I would have gone with a much simpler PA. I don’t think any increased jitter would be noticeable in a WSPR beacon. Maybe someone reading this with a better grounding in the practical application of si5351s might like to comment. As your 8MA beacon is WSPRing happily, I think we have our answer.

      I hope others who are interested in this project read your comment and choose to experiment with a higher drive level and a much simpler PA, or a similar PA with a higher output. At some point I’ll set the drive to 8MA setting and see what that does to my little 250mW two-transistor PA. I don’t think it makes much sense to push a WSPR beacon above a watt at this point in the cycle, because you end up getting spotted by the same receivers across the globe each 24 hour cycle and as a result you lose any information about propagation changes. Others may disagree. Perhaps at 200mW I am missing out on the second tier of WSPR receivers that I am currently too weak to be detecetd by.

      Thanks for the kind comments, but remember that my beacon is a simple variant of the Zachtek beacon, and stands on the shoulders of Arduino library giants like Jason NT7S, and for the PA, Wes W7ZOI and radio friends.

      Keep building your amazing projects Dave, 73 Paul VK3HN.


      • AA7EE says:

        I had a feeling that’s what it might have been Paul. I too read the reports that jitter (and perhaps phase noise too?) suffered a little at higher drive levels, and wondered whether that had something to do with your decision. I got it into my head that I wanted to use the class E amp that Hans uses in his Ultimate 3S and QCX transceivers, so I needed the higher drive. The simplicity appealed. It’s hard to argue with a W7ZOI-designed amp though!

        I agree with you that much more than a watt is not needed, and even missing the point of this weak signal mode. I was getting plenty of spots on 10M with 30mW, so perhaps even 200mW when that band is open, is too much. I’d be interested to connect the output of the Si5351 directly to an LPF and watch the fun. My bigger issue on 10M is the presence of many reports with drifts of -4. That suggests to me that there may be more potential spots that weren’t recorded, due to higher drift. than that. I think it is my main issue rather than power. WSPR, and it’s close cousins, are such elegant modes, that benefit from finesse in their delivery, rather than the brute force of power. My next experiment may well be using an Si5351 board with a TCXO to see if that helps any.

        Your increasingly complex transceiver projects have been a joy to read about.

        Cheers for now, and I agree about the debt we owe to those whose work we greatly benefit from.



  9. AA7EE says:

    Ooops, I meant Ultimate 3S WSPR transmitter, and not QSPR.


  10. […] Back to radio. The Autumn 2022 issue of SPRAT contained an article by Paul VK3HN, detailing the WSPR beacon he had built using modified open source code from Harry at ZachTek and, of course, the JTEncode and Si5351 libraries from Jason NT7S (Jason’s libraries pop up everywhere). If you don’t have access to SPRAT, and even if you do, Paul describes his beacon on his blog here. […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Shack of VK2KMI

Ham Radio Blog of VK2KMI

Ham Historian

A passionate amateur looks at Melbourne history


My journey of repairing and recycling anything I put my hands on that I believe is still useful. Not just hardware, but including software with relevant content and issues in the field of Cyber Security, Vulnerability Scanning and Penetration Testing.

G4YDM Ham-Radio and SWL news

Radio craft, homebrew, QRP/SOTA, AM


Amateur radio experiences with VK1DA

Tj Lab


The Microscopic New Yankee Make Shop

Bits of technology and illogic by WA2MZE

Paul Gacek


NewURL: https://dk7ih.de

This blog is no longer in use!

%d bloggers like this: