Hello community - Dave here (radio callsign G7IYK),
I have very pleased to publish details of my latest project which is a WSPR or Weak Signal Propagation Reporter beacon. I can hear people saying "that sounds great", but what the dickens is a WSPR beacon ?
OK - what is this WSPR all about ....
A WSPR (pronounced 'whisper') beacon is a low power radio transmitter operating on amateur bands from 2m to 160m or approximately 144MHz to 1.8MHz respectively. The implementation presented here can support 5 bands of which I concentrate on 2 bands - 20m and 40m. My particular antenna is best suited to 20m and 40m.
The WSPR protocol was developed by Dr Joe Taylor, a Nobel Prize-winning Princeton physicist. This resulted in a PC computer-based application first released in April 2008. The computer (often a PC) takes some basic user information and encodes it using the WSPR protocol resulting in 162 four level FSK (Frequency Shift Keying) symbols. These symbols,and then transmitted slowly over a 110.6 second period starting at the top of an even minute. The information encoded consists of the users radio callsign (mine - G7IYK), the users locator code (mine - IO81) and the power level in dBm. So the basic information looks like:
WSPR input information example : G7IYK IO81 30
In this example 30dBm equates to 1W into a 50ohm matched antenna.
Following encoding, the resultant FSK signal fits into only 6Hz and the WSPR band is only 200Hz wide. So the PC will output the modulated data as a series of four FSK tones. These audio tones are then input to an amateur radio rig set to the appropriate band frequency. The amateur radio rig subsequently transmits the data out into the world .....
OK - great, so what is the point ?
The world is literally peppered with WSPR beacons and receivers. My project presented here is a transmit only beacon but many (most) WSPR setups receive and transmit - they are transceivers.
Here is the cool part(s) ...
WSPR receivers can decode all of the messages in the 200Hz band simultaneously resulting in possibly dozens of decoded messages per two minute window. Also, the WSPR protocol can be decoded at S/N (Signal to Noise) levels of around -28dB - hence the whisper description. Often the decoder can pull out and successfully decode signals from the noise that are inaudible to the human ear. This means that your low power signal can be decoded at very great distances depending on propagation conditions.
Ok, so how do you know who has decoded your signal ?
There is a very cool website called WSPRnet (wsprnet.org). This website displays all the WSPR decode activity per band across the planet. The WSPR receiver software running on all the thousands of stations across the world push the decoded callsign marked data up to the wsprnet.org website where it is displayed for anyone to look at. You can enter your own or anyone else's callsign into the map page and the site will filter the information showing where on the planet that callsign was decoded, the decode time, by whom it was decoded, what the true received power level was and the distance from the transmission source.
You could do this just for fun (and it is fun) or you could use it for something serious like antenna development, after all WSPR is a propagation reporter. You can design and model an antenna all you like but WSPR allows you to actually SEE how well the antenna is working by showing you where from your location other stations were able to decode your signal.
You can also use your own decoded transmissions or the decodes of others on the website to see at any particular time which bands are open and propagating well and which, due to atmospheric conditions, are closed.
I have attached images showing the kind of information available on the WSPR website.
So what is this project all about ?
As I previously mentioned, most WSPR stations consist of a personal computer and amateur radio transceiver coupled together with an interface cable. The interface cable sends and receives audio information to/from the PC and also allows the PC to switch the radio between transmit and receive.
Most people have a PC but amateur radios are generally very expensive and have far more features than is required for WSPR. You may have an amateur radio licence or are thinking of applying for one and want to have a play with a digital mode like WSPR but not spend £££ on a radio transceiver.
This project is a stand alone WSPR beacon complete with data encoder, display, GPS receiver and a radio transmitter including low pass filters. The beacon, once configured, will run stand alone transmitting a WSPR sequence GPS locked to the top of each even minute. The beacon can also be connected to a PC via a radio serial interface, fully configured and downloaded using a dedicated control application program. The beacon is also preloaded with a bootloader allowing the embedded firmware to be reprogrammed over the same PC serial radio connection.
Here is a list of the main project features ...
- Stand alone beacon requiring no PC connection to operate
- PIC microprocessor for data encoding and control
- GPS receiver to provide accurate transmission timing
- LCD displaying transmission data, time, mode etc ...
- Integrated bootloader for PIC firmware re-flash
- Frequency synthesis from 1MHz to 40MHz
- Radio transmitter with an output power of 35dBm or ~3.2W
- Radio transmitter per band switched output low pass filtering
- Radio based 57600 baud serial link to PC for configuration and bootload
- PC based control and configuration application
- PC based serial bootloader application
So WHY have I designed and built this WSPR beacon ?
Considering I have a PC based WSPR station and Yaesu radio transceiver this is a very good question. The main reason is just for fun, it was a great project and I learned new skills in
The hardware and software: I generally pick projects that contain features which maybe new to me. As examples in this project, I developed the serial bootloader - invaluable for future projects, got to integrate some RF into the project and used a GPS receiver ... not to mention the WSPR software encoder and other challenging embedded firmware tasks.
Also, I like the fun of writing the project up; it gives it a sense of completeness - not quite a commercial product but a well advanced prototype. Sharing a project with a wider community forces one to aspire to a higher level of quality compared with just a simple bench lash-up. Often the very act of documenting the project and explaining decisions leads to the realisation that maybe there was a better way of doing something.
Releasing a project to the wider community often results in others wanting to 'have a go' at building the design and I like providing the support where possible. It is very rewarding to pass on skills to others and see what they do with their new skillset.
Sometimes a project proves very popular and a low volume product may briefly emerge to produce a bit of beer money to fund the next mad project !
Finally, the community generally provides feedback both good and bad. Often, when constructive, this feedback enhances my knowledge and is often the source of cool new ideas - so pleased feel free to provide feedback :)
Step 1: More Information on the WSPR Protocol
Important : To avoid any possible confusion I stress here the WSPR protocol is not my design and I had no input into the design process. As has been mentioned in the introduction the WSPR protocol was designed by Dr Joe Taylor of Princeton university.
The WSPR protocol has a couple of modes of operation. The first mode generates the encoded data in a single pass and is designed for a single transmission interval. The second extended mode generates data designed for a two interval transmission. My beacon project and the following description only details the first single pass approach for transmission within one two minute interval.
There are very detailed descriptions of the WSPR protocol, here I present a brief description designed to help clarify subsequent design steps.
1. Data to be encoded (non extended mode)
- Callsign with a maximum of six characters A-Z, 0-9 and [space]
- Standard 4 digit Maidenhead locator
- Power level from 0 to 60dBm
Example sequence : G7IYK IO81 30
Why encode in the first place ....
Good question - why encode in the first place, why not just transmit the characters using say Morse code ?
In a nut shell we encode the data to greatly improve the chances of our message being decoded at very low SNR levels. This improvement in recovery performance is called coding gain. Where an un-coded signal might be recoverable at some SNR -XdB by coding the sequence we might be able to recover the signal at say -(X+C)dB where C is the coding gain. In the case of WSPR this coding gain is achieved by encoding the data using a non-recursive convolutional code with a long constraint length.
WSPR transmissions can be decoded at SNR levels as low as -28dB.
A brief walk through of the encoding process
- So we start with our input data, example G7IYK IO81 30.
- Lossless coding of input components results in 28-bits for callsign, 15-bits for locator and 7-bits for power level so a total of 50-bits.
- Bit packing the 50-bits into array of eleven 8-bit bytes and truncated results in 81-bits.
- The 81-bits are encoded (FEC, forward error correction added) using a constraint length 32, rate 1/2 convolutional code resulting in a 162-bit sequence.
- In order to provide protection from burst errors the 162-bits are interleaved.
- The interleaved 162-bit sequence is merged with a 162-bit pseudo random synchronisation sequence resulting in 162 two bit values.
Each of the 162 two bit symbols represents a frequency shift of 12000 / 8192, or approximately 1.46Hz, per symbol value giving four-level FSK modulation. The transmitted symbol length is the reciprocal of the tone spacing, or approximately 0.683 seconds, so the complete message sequence of 162 symbols takes approximately 110.6 seconds to send and occupies a bandwidth of approximately 6Hz.
Transmission is started no later than one second after the top of an even minute.
Step 2: WSPR Functionality and Interface
I thought I would start by describing the PC application interface and Graphical User Interface or GUI. Although the WSPR beacon runs stand alone it still requires the PC application to initially configure and initiate a transmission sequence.
Consider the first image in this step. This image shows the WSPR control panel after it is first invoked and we have the following fields:
- COM Port - a drop down menu displaying all the current serial COM ports attached to the PC. Once a COM port has been selected the application will remember this when the application is opened in the future.
- Open Port - this button opens and closes the COM port. The button alternates between displaying Open Port and Close Port depending on the port status.
- Tx message - these are the three fields that make up the user message. First is the callsign, then the Maidenhead locator and finally the power. The power is chosen from a drop down list of legal powers. Both the callsign and locator are parsed for legal format and will turn red if the format is not correct.
- Band/Frequency control - the 'Frequency in Hz' field is the offset from the start of the WSPR 200Hz band. The legal range of values is 0 to 194Hz (200Hz including the transmission bandwidth of 6Hz). Next are checkboxes indicating which bands are to be covered. If multiple bands are checked transmissions will occur by band order in ascending wavelength order.
So if both '20m' and '40m' are checked and the 'Step Hz' field is zero transmission will occur at an offset given by the 'Frequency in Hz' field on band 20 for one two minute period and then automatically switch to a similar transmission on band 40 for one two minute period. The cycle will continue until the user stops the transmission via the WSPR control application or by hitting the stop/start hardware button.
If the 'Step Hz' field is non zero different behavior takes place. In this case transmission starts at a frequency offset of 0Hz and proceeds up the band for two minute transmission periods at frequency intervals given by the 'Step Hz' field. Once the end of the current band is reached the next band is selected if selected by checkbox. With the 'Step Hz' field non zero the 'Frequency Hz' field is ignored.
- Debug window - this checkbox opens and closes the debug console window. The debug window shows all the uplink and downlink traffic between the PC application and the hardware over the radio serial interface. In additional many software states and other useful debug data is displayed.
- Send - this button causes the WSPR control application to send the Tx message and other fields to the hardware. A send operation is only permitted once the COM port has been opened. As each field is sent and the hardware acknowledges receipt of the data each field changes from a white to a green background.
- Current Tx status reported by hardware - these fields represent direct feedback from the hardware. The echoed Tx message is displayed. The transmission current band and frequency offset are also displayed.
- Symbol progress bar - this bar displays the progress of the current 162 FSK symbol transmission.
- GPS status - displays the status of the GPS receiver locked or unlocked.
- GPS time - displays the current time as reported by the GPS module.
- Current time - this is the current time displayed by the GPS module. This may be different to the time displayed by the PC as often the PC clock is not accurate.
- Tx Enable - once the COM port has been opened and the hardware has successfully been configured this button initiates a transmission at the top of the next even minute as given by the GPS module. Transmission will only start once the GPS module lock has been detected and still terminate if lock is lost. The user can terminate a transmission by pressing the 'Tx enable' button or by pressing the start/stop hardware button.
The second image shows the WSPR control panel once the Send button has been pressed and the debug console is open. The GPS is locked and the time displayed. Once the 'Tx Enable' button is pressed a transmission will start at the top of the next even minute.
The third image show the Band Frequency Calibration panel which has the following fields:
- Frequency offset per band - this is the offset in +/-Hz that will be applied to the DDS module to correct for any absolute output frequency error caused by an inaccurate 125MHz reference clock.
- Filter position per band - this is the physical hardware position 1-5 where the LPF filter for the respective band is installed.
Video showing the WSPR control panel in use
Step 3: WSPR Beacon Hardware Operation
The attached video shows the WSPR hardware operation.
Step 4: Results From the Beacon
Before we get into all the design detail I thought it would be fun to detail the results from the beacon. I think it is always easier to appreciate the design detail if you have had a look at the design capabilities first.
So I set the beacon up to transmit my information on both 20m and 40m. The beacon was operating in what I call band-scan mode. In this mode the beacon starts transmitting at the bottom of the 20m band and after each two minute transmission interval automatically moves up the band, in this case in 10Hz steps. Therefore, within band 20 there will be twenty transmissions and so it takes forty minutes to complete. After traversing band 20 the beacon automatically switches to band 40 and scans the band before automatically returning to band 20 and starting again. This operation could be performed over five bands in total.
The images attached and data below were taken from the WSPRnet website :
The following three images show dozens of successful decodes all across Europe and over the Atlantic into the USA.
Full control of the beacon is maintained via the radio serial connection and using the PC based WSPR Control Panel.
Furthest decode was : KD6RF at a distance of 7392km or 4620miles with SNR of -19dB
Step 5: Decode Map Showing Europe
Step 6: Decode Map Showing the USA
Step 7: The Design, a Top Level Hardware Overview
In this step I will look at the hardware aspects of the design from a top level and explain what each component is and why it is required.
I always start a design by looking at the problems that need to be solved. This generally involves sitting down with a piece of paper, a pencil and a nice bottle of red wine (essential) with maybe some cheese and biscuits. At this stage we are trying to scope out the problem and arrive at a set of top level options. From the options we make design decisions and arrive at a design solution. This is top level stuff so the list may not be very long or complicated but making a wrong decision at this stage can result in a lot of wasted time further down the design process.
Top level scope of design list and decision process:
- Completed solution must operate stand alone with no external computer connection
Design decision: The design could implement the entire WSPR encoding process stand alone or it could be configured with a pre-calculated sequence and simply modulate the sequence. Pre-loading the sequence would mean that no changes could be made to the user callsign, locator or power without re-connecting the beacon to a host computer to calculate the new sequence. However, computing the WSPR sequence stand alone would require more micro processing power and memory.
I first wrote an encoder using Microsoft visual C++ just to get it working. I then migrated to encoder to C and compiled using the Microchip C18 compiler. My 28 pin PIC microprocessor of choice is generally the PIC18F25K22 device running with an internal clock frequency FOSC of 64MHz resulting in an instruction execution rate of 16 mega instructions per second. The encoder execution time on this processor is ~88us and the memory overhead was low.
So the decision was make to implement the WSPR encoder in the PIC microprocessor.
Design decision: The WSPR transmission must start no later than one second after the top of the even minute. Therefore, some mechanism must be present to keep accurate track of real time. There are two possible ways of doing this. The first solution is to use a real time clock module (RTC). A RTC module is programmed up with the correct time and then free runs. The time can be read back and interrupt based alarms programmed up. Some RTC modules are very accurate with only a drift of a few PPM but they will drift and so at some point the accurate start point of the transmission will be violated. The second option is to use a GPS module to provide accurate timing information. GPS modules are now very cheap and readily available coming supplied with a passive embedded antenna or external antenna connection.
The decision was made to use an external GPS module accessed via a serial link.
- The user must be able to view key information stand alone
Design decision: The simplest solution to this problem was to use a LCD display.
I chose to use 20 character by 4 line display connected via an IIC interface to the PIC.
- The user must be able to easily reprogram the WSPR beacon from a host computer
Design decision: To write a PC based Windows GUI to provide all the required configuration functions .
I wrote the Windows GUI application in C# with a user selectable debug console window.
- The PC application requires a connection to the PIC firmware
Design decision: The two obvious connection choices are USB or Serial. The PIC18F25K22 I had chosen has two serial interface ports but does not have a USB controller.
I chose to use a radio based serial connection allowing the WSPR beacon to be remotely reconfigured and monitored with no cabling required.
The serial radio modules I used are APC220 devices.
- The user must be able to update (re-flash) the PIC firmware without the need for a specialised programmer
Design decision: In order to update or re-flash PIC firmware without the need for a specialised PIC programmer you need a bootloader. A bootloader is a small piece of firmware running on the PIC which, once enabled, communicates with the host computer and orchestrates the download of the new application firmware and flashes it into PIC program memory.
I already had a Microchip USB bootloader which I had modified and used for other projects using PIC devices with embedded USB controllers. However the PIC18F25K22 has no embedded USB controller.
Having looked around I could not find a serial bootloader that either worked properly or I was happy with. So I took the Microchip USB bootloader firmware and PC based application and re-wrote them to support the serial radio link connection I had chosen to use.
- The beacon must be able to generate it's own RF modulated signal
Design decision: In order to generate the required frequency range to cover most of the HF band and also the required modulation I used a AD9850 DDS (Direct Digital Synthesis) module capable of a frequency range of 0 - 40MHz and accurate enough to resolve the WSPR tone separation.
- The stand alone WSPR beacon must be able to generate it's own RF power output
Design decision: I decided early on to initially source and RF PA module rather than layout my own solution. There were many available of varying bandwidths and powers. In the end I went for a PA module with a specification of 1MHz - 700MHz and a RF gain of 35dB.
Following the RF PA is it necessary to provide low pass filtering in order to suppress the second harmonic and other high frequency undesirable components. Initially I was going to make me own switched low pass filter. However I found a really great solution from QPR labs so for the initial prototype to save time went with this solution.
The following steps address each of the main hardware components in turn giving design detail where necessary - the hardware section is then concluded with a schematic
Step 8: Microchip PIC18F25K22 PIC Microcontroller
I have been working as an electronics engineer in telecommunications for almost 30 years and working on home projects for over 40 years. Most of my working life I have worked on FPGA and ASIC technology but in later years increasingly on software.
Without a doubt the biggest impact on home hobby electronics has been the availability of cheap powerful microprocessor like the Microchip series PIC parts and the ATMEGA series used on the Arduino boards. Years ago boards would be built using numerous discrete chips such as the 4000 and 7400 series parts. Then came along simple programmable CPLDs to mop up logic and later FPGA technology. Later again some FPGA technology had soft microprocessors available like the Xilinx MicroBlaze.
The primary advantage of microcontroller technology is the huge number of available parts - literally hundreds. Each part has a microprocessor at its core with a varying array of peripherals bolted on. It is pointless me even trying to describe the range of devices available - I would suggest going to the Microchip website and looking through the device options - it can be bewildering. I would say if you can conceive of a project it will be difficult not to be able to find a suitable part.
A lot of guys use the Arduino platform for project work and it is a splendid platform. However, for me I prefer the Microchip PIC technology. It is personal preference but I like to be as close to the hardware as possible with absolute control of what is going on down to the clock cycle if required. A PIC solution is possibly not the quickest route as the Arduino libraries make for fast coding. However, for me PIC is best ....
What tends to happen is one ends of with favourite parts that you get to know and love. For example if I need a USB solution I generally so for a PIC18F2550 or 18F4550. However, if I don't need USB I generally go for the PIC18F25K22 or variant.
The PIC18F25K22 data sheet runs into some 500 pages so I am not going into too much detail here - download the datasheet and have a look. It is staggering how much functionality is packed into a little 28 pin package and with a 1 off price tag of less than five pounds (pint of beer and some nibbles).
However, here are just a few of the PIC18F25K22 features, those that I am using:
- High performance RISC CPU
- 32 Kbyte program memory
- 1536 bytes data memory
- 256 bytes EEPROM
- On board 64MHz oscillator
- 16 MIPS operation
- Multiple hardware interrupts
- 25 pins of GPIO
- IIC interface
- EUSART interface x 2
- Multiple timer modules
I have attached the front sheet of the data sheet to give a better idea of what this device is capable of.
PIC microprocessor software development and programming
For programming the PIC I use a PICKIT3. I find this an excellent programmer and have never had an issue. The one I use is actually a clone I picked up from eBay for about £15 and works really well.
The PIC firmware is all written in C and I use the MPLAB IDE version 8. This is an old version but I am very familiar with it and see no reason to upgrade. I use the Microchip C18 compiler with optimisation, again an old version but if it ain't broke don't fix it ....
Step 9: PIC Microcontroller Development Board
I am a big fan of these PIC microcontroller development boards. They are quite cheap at around £10 and have everything you need to get going with a project prototype. The board has the following main features which reduce the amount donkey work necessary to get things going:
- Socketed 28 pin PIC socket
- 5V and 3V voltage regulators
- Power connector
- USB connector
- Programming header
- Power indicator LEDs
- Master reset button
- Two general purpose buttons
- Power switch
- Reverse polarity protection
- Prototyping area
Generally for projects I buy a prototyping board and then if necessary piggyback the prototyping board onto a second larger board using 2.54mm headers. In the case of the WSPR project I managed to fit the APC220 radio serial interface module and NEO-7M GPS module onto the prototyping board and then fitted all the remaining modules to the base board. All the control, clock, data and power pins for the base board are accessed via the 2.54mm headers. The prototyping board can be unplugged at any time for modification or to add further parts. Everything is wired up using standard single core mod wire with a few decoupling capacitors here and there for good measure.
Step 10: WSPR Beacon Design Schematic
Attached to this step is my project schematic.
The great thing about PIC microprocessor based projects is the hardware is generally quite simple and this project is no exception. In "the old days" the hardware would have been most of the work. If this project would have been possible say forty years ago the hardware would have taken up half my workshop and would have taken months to build. Now everything is so highly integrated that the hardware design just consists of hooking modules to microprocessor and all the work is in the software.
Regarding the schematic, there are a few things to note:
The AD9850 is quite a power hungry device, from memory it consumes around 300mW and gets quite hot. That and all the other stuff hanging off the 5V rail results in the LM7805 regulator requiring a heatsink. It doesn't need forced air cooling but a heatsink is needed. I found without a heatsink the regulator started to drop out due to thermal protection kicking in.
The FET based power switch for the RF PA could be replaced with a relay, I just happened to have the FET and opto-isolator knocking about in the workshop.
Note the 470R serial resistors on the GPS module UART port. These are required because the PIC UART port 2 shares it's pin with the PIC programming pins. If you want to have the GPS connected and still use the PIC programmer these resistors are required.
Note the 10K pull up resistors on the LCD display port. The LCD is controlled via an IIR interface and pull up resistors are required.
The schematic doesn't show some of the decoupling capacitors used. I tend to put a 100nF decoupling capacitor across each modules power rail just for good measure.
Step 11: NEO-7M GPS Satellite Positioning Module
This is a very cool little module ......
I have played with GPS modules before but this is the first time I have actually needed one in anger for integration into a project.
As has been mentioned earlier WSPR transmissions must be synchronised to the top of an even minute and therefore the PIC micro needs access to a real time clock source. I could have used a real time clock module pre-programmed and then free running. However, such a free running module would have drifted over time and eventually violated the required transmission time requirement. So the obvious solution to this was to use a GPS module - I didn't need too much of an excuse !
This little module has an integrated antenna and also an external antenna connection. The module is fully integrated with a serial and USB connection plus battery backup. It uses one of the latest NEO-7M GPS modules so it up to date and modern in functionality.
It is almost difficult to believe when you consider the technology involved but this module was £6 delivered !
The module is quite straightforward to use. I did not use the USB interface as my chosen interface method to the PIC microcontroller was serial. To have fun with this module you don't need a microprocessor ! To get raw data simply connect it to your PC via a cheap serial to USB adaptor and fire up a terminal program such as Putty. Set the baud rate to the module default of 9600 and the data will spew down the screen. There is also a very nice application program called u-center available on the u-blox website www.u-blox.com. This application is a great deal of fun as it turns all the data from the module into visual information. Even if you don't plan on integrating a GPS module into a project I would pick one up just to play about.
Back to the WSPR project ....
The GPS module produces a great deal of information in the form of what are termed sentences. A sentence is comprised of a message header plus a whole bunch of related information. Initially it looks like meaningless numbers and symbols but there is method in the madness.
Here is typical raw output from the GPS module just streamed to a Putty terminal.
$GPVTG,,T,,M,0.309,N,0.572,K,A*29 $GPGGA,185204.00,5126.44547,N,00228.20868,W,1,05,1.71,50.8,M,48.4,M,,*79 $GPGSA,A,3,31,25,26,14,23,,,,,,,,2.81,1.71,2.22*09 $GPGSV,2,1,07,04,44,284,33,14,24,239,34,21,12,172,18,23,06,338,29*72 $GPGSV,2,2,07,25,57,090,21,26,28,282,46,31,64,274,37*40 $GPGLL,5126.44547,N,00228.20868,W,185204.00,A,A*7B
A sentence starts with a $ symbol and terminates with a * symbol. The numeric value after the * symbol is the sentence checksum used to validate the sentence integrity.
The series of characters between the $ and the first comma is the message type for example GPRMC.
There are a lot of possible messages, above are just the default set produced. Here is a very simple description of the default sentences:
- GPRMC - Recommended minimum data
- GPVTG - Course over ground and ground speed
- GPGGA - Global positioning system fix data
- GPGSA - GNSS DOP and active satellites
- GPGSV - GNSS satellites in view
- GPGLL - Latitude and longitude, with time of position and status
Ok, well the good news is for this WSPR project we only need the time and that is contained within the GPRMC recommended minimum data sentence so lets break the sentence down and see what is in there ...
- GPRMC - we know is the sentence type
- First 185204.00 - this is the time 18:52 and 4 seconds universal time or UTC
- The next letter is either A (active, you have a good signal) or V (void, you have no signal)
- Next latitude 5130.44547 - 51 degrees and 30.44547 minutes
- Next hemisphere N (northern) S (southern)
- Next longitude 00230.20868 - 2 degrees and 30.20868 minutes
- Next east/west W (west) E (east)
- Next speed in knots 0.309
- Next track angle - I was stationary so no data given
- Next date 200218 - 20th Feb 2018
- Next repeat of position fix flag A (active)
- Next * end of sentence
- Next checksum
So all we need is this sentence and the first data field giving the time - easy right ?
The first thing I decided to do was turn off all the messages apart from the GPRMC message. I also wanted to run the module at 57600 baud and not the default 9600 baud.
This is very straight forward as you can use the u-center application I mentioned earlier. Once the GPS module is talking to the application over the serial interface you can go the application configuration screen and switch off messages you don't need and also reconfigure the serial port speed.
This worked perfectly .... for about 5 seconds. Unfortunately, one of the side effects of buying modules from China is that if they have a backup battery it is almost invariably knackered. This little cell was no exception and was only at about 2.1V and not the required 3V. Therefore, once disconnected it promptly forgot the new setup and reverted to the factory default.
Mmmmm - what to do .....
Tried to find an exact replacement battery, got bored looking. Could have strapped another battery onto the board but that would have looked rubbish and been a botch job.
Could just use the default setup and parsed all the messages and run at 9600 baud but I don't like to compromise once a design decision has been made - well not just because of a flat battery.
So the solution was to re-program the module at run time. By this I mean the module comes up in its default state and the PIC then sends the appropriate command messages to turn off the unwanted message trace and change the baud rate.
I could have trawled through the interface specification and generated the command messages and checksum by hand but fortunately the u-center software has a 'message view' mode that displays all the messages sent to the module in HEX format. So all I had to do was configure the module using the u-center application and then copy the command sequences into my PIC firmware initialisation code.
Here are the messages to turn off the sentences not required:
GPVTG : B5 62 06 01 08 00 F0 05 00 00 00 00 00 01 05 47
GPGGA : B5 62 06 01 08 00 F0 00 00 00 00 00 00 01 00 24
GPGSA : B5 62 06 01 08 00 F0 02 00 00 00 00 00 01 02 32
GPGSV : B5 62 06 01 08 00 F0 03 00 00 00 00 00 01 03 39
GPGLL : B5 62 06 01 08 00 F0 01 00 00 00 00 00 01 01 2B
The message to re-reprogram the baud rate to 57600
Port 57600 : B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 E1 00 00 07 00 03 00 00 00 00 00 DE C9
In order to reprogram the baud rate the PIC serial interface UART2 first comes up at 9600. All the reconfiguration messages are sent and the port is closed. The port is then reopened at 57600 to reestablish communication.
Messages are parsed by monitoring the receive data from the GPS module and waiting for a $ symbol. The various fields are then decoded by extracting the comma separated data being finally terminated by a * symbol.
Step 12: AD9850 Direct Digital Synthesis Module
The Analog Devices AD9850 DDS module is the key to the entire project. Everything else is basically window dressing to make the beacon work and be usable. However, in order to function as a WSPR beacon you need to generate the band frequency and required modulation - this is the function of the AD9850 module.
The interface to the AD9850 is a synchronous serial interface consisting of a clock, data and load strobe. In order to program the device you need to clock in a 40 bit data word which has frequency, control and phase information. So you can perform Frequency or Phase shift keying. The WSPR protocol uses a four tone Frequency Shift Keying (FSK) modulation scheme.
Here is some basic information on how to calculate the data required for a particular frequency.
Although we need to program a 40 bit data word it is built as follows:
- Frequency tuning data bits 0 - 31
- Control data bits 32 - 33
- Power down bit 34
- Phase data bits 35 - 39
In my implementation I only program data bits 0 - 31 and set bits 32 - 39 to zero.
- F is the desired frequency
- DDS reference frequency Fref which is 125MHz for our module
- Size of tuning word 32 bit
Resolution achievable = 125e6 / 2^32 = 0.0291Hz
Tuning word = F x (2^32 / 125e6)
So for example for a 14MHz output the tuning word = 14e6 x (2^32 / 125e6) = 0x1CAC0831
Ok, so how to calculate these values in the microprocessor. Obviously, there are some very big numbers here plus floating point divisions and multiplications. Therefore, I spent a glass or two of wine doing some experiments to see which was the best way of calculating the tuning word in terms of code space, execution time and accuracy.
Luckily, this is Ham radio and we deal in bands. So for all the relevant bands we have a bottom of band fixed base frequency which we can pre-calculate. This is the big number in potentially tens of MHz and therefore our really nasty big number calculation can be replaced with a simple lookup table as follows:
Base frequency values
10m 28.126MHz 0x399A1FD1
12m 24.926MHz 0x330C6716
15m 21.096MHz 0x2B346130
17m 18.106MHz 0x2514C22E
20m 14.097MHz 0x1CDEE34F
30m 10.1401MHz 0x14C4552F
40m 7.040MHz 0xE6AFCCE
80m 3.954MHz 0x81908E5
The WSPR band is 200Hz wide, the above base frequencies are the bottom of the 200Hz band.
Frequency offset into the 200Hz WSPR band
Now we need to calculate the offset into the 200Hz band.
Looking at out calculation above we have a factor (2^32 / 125000000) = 34.359738368. This value is stored as a floating point constant.
So our offset factor becomes (FoffsetHz x 34.359738368) rounded to an integer.
Finally we need to add in our WSPR modulation, four tones with a frequency separation of 1.464Hz.
WSPR tone 0 0Hz 0x0
WSPR tone 1 1.464Hz 0x32
WSPR tone 2 2.928Hz 0x64
WSPR tome 3 4.392Hz 0x96
Composite AD9850 tuning word
The final tuning word for the AD9850 = base frequency + band offset + modulation
Therefore, the only calculation to be carried out is one floating point multiplication to generate the band offset tuning data and the final addition of three terms two of which are derived from look up tables.
AD9850 DDS module output
The AD9850 module generates a variety of different outputs both sinusoidal and square wave. Obviously, we are only interested in the sinusoidal outputs of which there are two. The output of the AD9850 device is a current source and the first output is connected directly to the device with a 50ohm current sink. The second output is passed through a low pass filter. We will use the low pass filtered output labelled ZOUT2 to connect to the RF power amplifier.
Output frequency inaccuracy
The accuracy of the output is directly dependent on the accuracy of the AD9850 125MHz reference clock. These are cheap modules and the reference clock is not going to be perfect. As a result the absolute output frequency is likely to be off by some arbitrary amount. In the case of the module I used the error was consistently high by as much as 76Hz. I have therefore included a feature under the PC GUI calibration tab to allow the user to enter a compensation offset to pull the output frequency.
So in conclusion we only need connect power/ground, the four wire programming interface and the filtered sinusoidal output.
Step 13: AD9850 Output Spectrum
The attached spectrum analyser plot show the output directly from the AD9850 module prior to the RF power amplifier. We can see the 20m fundamental is sitting at a level of about -5.3dBm and the second harmonic at a relative level of approximately -47.2dBc.
Obviously after the RF power amplifier the second harmonic is going to be significantly larger and we are going to need an power amplifier output low pass filter - see power amplifier steps.
Step 14: APC220 Serial Radio Interface Module
These little radio serial interface modules are fantastic. I love all things radio so to have the ability to control my projects via a radio link and get high speed telemetry information is just amazing. The attached image shows the pair of modules. One of the modules connects directly to the PIC18K25K22 microprocessor while the second module connects to the PC via a USB to COM port adaptor.
The modules are configured to run at a data rate of 56K baud and operate asynchronously.
The modules present themselves as a simple three wire serial interface (Tx, Rx and Ground). From the point of view of the microprocessor and the PC they simply look like any other serial interface, as if you had a bit of wire connecting the PC and WSPR beacon board.
Connection wise you simply wire Tx of the APC220 to Rx of the PIC serial interface and Tx of the PIC to Rx of the APC220. Then open up the serial port of the PIC and allocated COM port of the PC and just send receive data - it is that straight forward.
Step 15: 35dB RF Radio Power Amplifier Module
This is a brilliant little module - it is just perfect for the job of WSPR transmitter. I picked mine up from eBay and I think it was about £12 delivered including the heatsink. Just no way I could build it for that price. It operates from 12-15V and has around 35dB of gain for a 0dBm input.
I have found with direct input from the AD9850 DDS module this RF power amplifier is producing around 33dBm of output with a supply of around 14V.
Power to the RF power amplifier is controlled from the PIC microprocessor which switches on the supply one second before the WSPR modulation starts. The power is switched using a IRF9530 P-channel Mosfet device being driven by an opto-isolator. The P-channel Mosfet switches the 12V high side. When the gate is driven low by the opto-isolator power to the RF amplifier is switched on. When the opto-isolator is off the Mosfet gate is pulled to 12V switch the device off. The opto-isolator LED is driven directly from the PIC via a 470ohm current limiting resistor.
Step 16: Output From the RF Power Amplifier Module
This step show the output of the RF power amplifier using a spectrum analyser. I could have used a professional spectrum analyser loaned from work but have chosen to use my home brew analyser.
The spectrum analyser used comprises of a Rigol DS1054Z sampling digital oscilloscope in combination with a Python based piece of PC software called PyDSA. The PyDSA software uses the oscilloscope as a 1GSa/s input sampler and subsequently uses a windowed FFT to produce the frequency spectrum. The original PyDSA script I discovered on the internet but have made many enhancements to the original script including accurate calibration, peak detection, delta marker, tracking generator support with AGC and multi-trace storage. The resultant spectrum analyser has some limitations but for HF work up to 500MHz is an extremely useful tool.
The attached plot from the analyser shows three saved traces.
- The orange trace shows uses the tracking generator support I developed to show the frequency response of the QRP labs 20m low pass filter.
- The yellow trace shows the output of the RF power amplifier with no output low pass filter. We can clearly see the very prominent and unacceptable second harmonic at around -12dBc
- The red trace shows the output of the RF power amplifier with the QRP labs 20m low pass filter in place. We can see the fundamental has remained unaffected but the second harmonic has been suppressed to around -50dBc.
Step 17: Output From the RF Power Amplifier (no Filtering) Reference Level Set
The attached image show the 20m output from the RF power amplifier with no low pass filtering. A 30dB attenuator was used before the scope. To compensate for this loss the spectrum analyser has had 30dB of calibration added in. Therefore, the peak and delta markers display the true power amplifier output.
We can see the fundamental is at a level of about 32.5dBm and the second harmonic has a level of -11.9dBc which is totally unacceptable and we very much need the low pass filter in place - see next step !
Step 18: Output From the Filtered RF Power Amplifier Reference Level Set
The attached image show the 20m output from the RF power amplifier with the QRP labs 20m filter in place. A 30dB attenuator was used before the scope. To compensate for this loss the spectrum analyser has had 30dB of calibration added in. Therefore, the peak and delta markers display the true power amplifier output.
We can see the fundamental is at a level of about 32.6dBm and the second harmonic has a filter suppressed level of -48.8dBc - an excellent result.
Step 19: Firmware Design
By far the lions share of the work for this project has been software and firmware. The firmware is the code that executes on the PIC18F25K22 microcontroller. The software application executes on the PC. The bootloader is also a small firmware application also running on the microprocessor.
The PIC18F25K22 microcontroller is configured to use its internal 64MHz clock; this is the fastest clock rate possible for this device. Each instruction cycle takes four clock cycles and so the device executes code at 16MIPS.(Million Instructions Per Second). All the firmware for the main application and the bootloader is written in C and is compiled under the MPLAB IDE using the MicroChip C18 compiler with optimisation enabled.
I have attached a block diagram for this step showing a top level view of the microprocessor firmware design.
Looking at the design from a high level, the code is split into well defined sections as follows:
- Message decoder state machine - this code has two primary functions. The state machine parses and processes uplink messages sent over the serial radio link by the PC GUI application. Once messages are successfully decoded, downlink messages are sent back to the PC GUI in order to acknowledge the uplink; debug messages are also sent and displayed on the PC console window. When uplink configuration is decoded it is formatted and saved in non volatile EEPROM. When the WSPR beacon is powered up, the microprocessor checks for valid stored configuration and if found, restores the data. Therefore, once configured, the beacon can operate stand alone without the need for a PC connection.
- Transmit state machine - this code executes under the control of the above message decoder. Once everything is configured and the user has instructed the beacon to transmit via the PC GUI, the message decoder will invoke the transmit state machine; alternatively, the user can manually press the Tx enable button on the beacon itself. The transmit state machine performs a wide variety of functions including actually encoding the WSPR message from the user supplied data. It also decides on and calculates the transmit frequencies and bands, implementing single band operation or frequency hopping. The progress of the transmit state machine is a function of both the GPS time/tick and also the 0.683 second symbol period tick (see next step).
- Serial port 0 and ISR - this serial port is connected to the APC220 radio module. The serial port is configured to operate at 56K baud. All of the uplink and downlink traffic is passed via this port. The port is also used by the bootloader to communicate with the dedicated PC bootloader application and ultimately receive a new firmware application image. The bootloader operates by polling the serial port for data but the main application firmware operates using a high priority ISR (Interrupt Service Routine) to receive data. The serial port receive input buffer is only two bytes long so the ISR parses the incoming data and assembles the raw messages before passing them onto the message decoder state machine for processing.
- Serial port 1 and ISR - this second serial port is connected to the NEO-7M GPS receiver module. The module is configured at run-time rather than relying on the battery back-up which, as mentioned before, was dead(ish) on arrival. The GPS module defaults to 9600 baud and so the serial port is initially opened at this rate. The new configuration information is written to the GPS module concluding with commands to change the serial port rate to 56K baud. The serial port is then closed and re-opened at the new faster rate. Received data from this serial port is handled by a high priority ISR.
- Hardware timer and ISR - in order to achieve accurate symbol timing of 0.683 seconds per WSPR symbol an on microprocessor hardware timer is used. The timer is 16 bit wide and creates an interrupt every 0.03415 seconds. The ISR post scales this hardware tick to generate a very accurate symbol period tick which in turn is used by the transmit state machine to sequence through the 162 WSPR symbols.
- AD9850 module driver - this code bit bashes the interface to the AD9850 DDS module. The DDS module takes a 40 bit data word in order to set frequency and phase. The is a synchronous SPI interface with clock, data and load strobe.
- LCD 20x4 driver - the LCD display interface is IIC. The firmware uses the Microchip IIC library to provide the basic functions. The LCD driver is subsequently built up from these basic operations allowing the display to be configured and cleared; the cursor can be positioned and character sequences displayed.
- Bootloader - the bootloader is a dedicated piece of firmware located into the first 0x1000 bytes of program memory. It is the bootloader that executes on power up or reset. If the user has the bootloader button pressed at reset, the bootloader executes and attempts to communicate with the dedicated PC application via the serial radio link. Once communications are established, the bootloader accepts commands from the PC application and also returns data regarding the number of memory blocks, sizes and addressing. Once instructed, the bootloader erases all on-chip unprotected memory and flashes the new image transferred over the serial link. Once flashed, the bootloader reads and transmits all the data back to the PC application for verification. If on reset the user had not pressed the bootloader button, control is automatically passed to the WSPR firmware application.
Step 20: Measured WSPR Symbol Period of 0.683s
As was mentioned in the previous step the WSPR symbol period is 0.683s. A microprocessor hardware timer is used to generate 0.683 / 20 ticks per second. The interrupts are post scaled in the ISR to generate the 0.683s symbol tick required.
The attached oscilloscope screen shot shows the symbol period. Annoyingly the marker only moves in steps of two and so the Cursor B delta is displayed as 682ms but I assure you that the period is 683ms.
Step 21: The Bootloader
Although not not related in any way to WSPR the bootloader is an essential part of the project.
To reiterate - what is a bootloader ?
The purpose of a bootloader is to allow the user to reprogram or reflash the main application code (in this case the WSPR application) without the need for a dedicated specialized PIC programmer. If I were to distribute pre-programmed PIC microprocessors and needed to issue a firmware update the bootloader allows the user to reflash the new firmware without either having to buy a PIC programmer or return the PIC to me for a reflash.
A bootloader is simply a piece of software running on a computer. In this case the bootloader is running on the PIC microcontroller and I refer to this as firmware. The bootloader could be located anywhere in program memory but I find in more convenient to locate it right at the start of program memory within the first 0x1000 byte page.
When a microprocessor is powered up or reset it will start program execution from a reset vector. For the PIC microprocessor the reset vector is located at 0x0 and normally (without a bootloader) this would either be the start of the application code or a jump to the start depending on how the code is located by the compiler.
With a bootloader present following power up or reset it is the bootloader code that is executed and the actual application is located higher up in memory (termed relocated) from 0x1000 and above. The first thing the bootloader does is check the status of the bootloader hardware button. If this button is not pressed the bootloader automatically transfers program control to the main code in this case the WSPR application. From the users point of view this is seamless and the application code just appears to execute as expected.
However, if the bootloader hardware button is pressed during power up or reset the bootloader will attempt to establish communication with the host PC in our case via the radio serial interface. The PC bootloader application will detect and communicate with the PIC firmware and we are now ready to start a reflash procedure.
The procedure is straightforward and is conducted as follows:
- Bootloader hardware button and held while hardware is powered up or reset.
- PC application detects PIC bootloader and green status bar displays 100% plus PIC detected message is displayed.
- User selects 'Open Hex File' and using the file chooser navigates to the new firmware HEX file.
- User now selects 'Program/Verify' and the flashing process starts. First the new firmware is flashed by the PIC bootloader and then read back and verified. Progress is reported by the green progress bar at all stages.
- Once program and verify is complete the user presses the 'Reset Device' button (bootloader button not pressed) and the new firmware begins execution.
Step 22: Conclusion and Future Development
If anyone has read this far I very much hope you have enjoyed this instructable ?
From my point of view this has been a really enjoyable and fun project. It incorporates everything I really enjoy working on, microprocessor control, sensors, telemetry, PC GUI development and obviously radio. It has taken quite a bit of time and effort to get everything working correctly and polished especially on the software front but it was definitely worth all the work.
In addition to the beacon itself I have now got a very useful HF spectrum analyser which can be used to develop future projects with an RF component. Also the serial bootloader is sure to be used again in the future.
Like all good projects this one has expanded my knowledge and added things to the mental toolbox that will be useful in the future for other projects. Some might say "what is the point" in spending all the time developing something for no real gain. The point is there is always gain on working on new and interesting projects, you learn new things and it keeps the grey matter lubricated - but above all it is just fun and satisfying.
Another up side which is difficult to quantify comes from sharing the knowledge gained with others. So if anyone has questions or comments I am more than happy to at least try and help.
I am more than happy to share the software privately with anyone interested or if someone just wants to build the beacon. If anyone wants a programmed tested PIC microprocessor, please let me know. I may take the project further, possibly as a future product, so at present would rather not share all the software publically. Please private message me if you are interested in the software or any other aspect of the project and I will be more than happy to help.
Until the next mad project have fun !