An Improved Classie WSPR Controller

When I first put together the Classie WSPR transceiver my primary concern was the transmit/receive circuitry. I only concerned myself with the controller in so far as confirming it was putting out the correct waveform with the proper timing. But once I had the transceiver on the air for a while it was time to start working on improvements to the controller.

The Updated Classie WSPR Controller

The schematic for the updated controller is shown below but most of the changes are in the software (available in the GitHub repository).

Updated Controller Schematic

Some of the improvements that’ve been made include:

VOX Controlled Transmit/Receive Timing – The original controller had no provision for aligning the WSPR transmit/receive cycle with real time. Correct timing was achieved by resetting the controller at the top of an even numbered minute. After that, all timing was done in software and depended on the controller crystal’s accuracy.

The updated controller software uses a software voice-operated switch (VOX) based on the Goertzel tone detection algorithm to put transmit and receive timing under control of the WSPR software.

Calibration Mode – The controller still uses an Si5351 to generate the transmitted signal and receiver local oscillator. The accuracy of these signals depends directly on the accuracy of the Si5351 crystal. To compensate for any innacuracies, NT7S’s Si5351 library (which I use in the controller software) has a provision to specify a correction factor that’s applied to the crystal frequency.

With the updated controller software, if you reset the Arduino with pin 2 grounded the transceiver will go into receive mode at a specified calibration frequency. Used in conjunction with a known reference frequency, you can calculate the required correction factor for use in the software.

For example, using WWV’s 10 MHz signal as the reference with the calibration frequency set to 9985 kHz, WWV’s carrier is beat down to around 15 kHz, plus/minus some error. Using Spectrum Lab or similar software to measure the actual beat frequency, the calibration factor can be calculated as:

corr=\frac{f_{expected}-f_{measured}}{f_{cal}}\times 10^{7}


fexpected = expected frequency
fmeasured = measured frequency
fcal = calibration frequency

Integrated Sound Card – The original Classie WSPR transceiver was designed for use with a separate sound card. Since the USB port was used to power the controller, this meant there were two cables connecting the PC to the controller (USB and audio). To minimize the number of cables I included a PCM2904 audio codec in the controller. This allows for operation with only a single USB connection between the controller and PC.

Setting Things Up

Like the original, the WSPR message, transmit frequency, and receive local oscillator frequency are hardcoded in the controller software. Keeping with this motif, the calibration frequency and correction factor are hardcoded as well. All of these values need to be updated as appropriate and the resulting binary loaded into the controller. To make this easier, these values have been moved to a separate include file.

Proper operation of the VOX requires the difference between the receive local oscillator and WSPR band center to be less than approximately 19 kHz. The VOX bandwidth is set to 196 Hz to match the width of the WSPR band and ideally the WSPR software transmitted tone will fall at or near the center of that bandwidth. If for some reason the VOX appears to be operating intermittently, try varying the transmitted frequency from within the WSPR software to move the transmitted tone more toward the center of the VOX bandwidth.

Connections between the controller and the rest of the Classie WSPR transceiver haven’t changed. Once they’ve been made just plug the controller into the PC via USB. The PCM2904 requires no special drives and should be recognized with no difficulty.

The WSPR software is configured as described in the original post. To enable the VOX select the Setup->Station Parameters menu item and on the displayed form change the PTT method to VOX. You can set the transmit percentage on the WSPR main form.

What’s Next?

I’ve been using the updated controller for a few weeks now and haven’t run into any problems. In the future I may add a serial connection to set the various constants and transmit message but that hasn’t been a priority because once they’re set there’s no need to change them.

Finally, while the original transceiver was designed for WSPR operation I’ve since realized there’s no reason other modes compatible with class E operation (e.g., RTTY) couldn’t be added, which may be the next area for improvement.


  1. Dear Joseph,

    I have been following your blog for the SI5351 WSPR transmitter. Thanks for putting it together on the blog for others to follow!

    I have homebrewed a si5351 module using a chip received as a sample. It outputs around 20mW. I wish to club it with a BITX PA (3-4W @12v), which takes around the same drive of 10-30mW from the BITX as the Si5351.

    Please advise if I can drive the BITX PA directly from a SI5351. I ONLY wish to use it for transmit. What exactly does the NOT gate does in your circuit ?? can i eliminate the not gate and drive my PA directly from the SI5351 as a tx only wspr beacon ?? Do I need to change anything in the arduino code ?


    • joesugar

      Thank you for the kind words. I have no experience with the BITX PA but have no reason to think you couldn’t drive it from an Si5351 with proper coupling. Depending on the match between the Si5351 and the BITX PA you may get a lower than expected output power.

      The NOT gate in the Classie circuit is actually part of the PA. It acts as an Si5351 level shifter. The Classie PA is Class E and requires a 5V level on the BS170 gate for proper operation. Since the BITX PA is a linear amplifier the NOT gate will not be needed. In fact, I originally drove the BS170 directly from the Si5351 but the output power was much lower than expected. For an explanation, see the writeup at

      You will not need to change anything in the Arudino code beyond what’s mentioned in the blog but you will need some way to key the amplifier.

      Good luck running WSPR.

      Joseph (KC3XM)

      • Ok. Can you advise in the circuit here:

        Which pin is used as a KEY on the arduino ?? does it go high on RX or TX ? If it goes high on TX I can use a transistor as a switch to turn the PTT on my PA to ON state.

        I also did not find a reference to the KEY/ PTT switch in the code here:


      • joesugar

        Pin 9 is used to key the transmitter (check out the #defines from line 61 – 67). Goes low to transmit but you can easily change that (lines 64/66). Also, don’t forget there is still a signal from the Si5351 on receive. In the transceiver it’s used as the local oscillator. If that’s a problem you can disable the Si5351 clock during receive.

DuWayne's Place

Computers, Electronics, and Amateur Radio from KC3XM

QRP HomeBuilder - QRPHB -

Computers, Electronics, and Amateur Radio from KC3XM

Open Emitter

Computers, Electronics, and Amateur Radio from KC3XM

Ripples in the Ether

Emanations from Amateur Radio Station NT7S

m0xpd's 'Shack Nasties'

Computers, Electronics, and Amateur Radio from KC3XM

%d bloggers like this: