WSPR is Hopping
November 25, 2010 5 Comments
I managed to get WSPR to frequency hop!
It took me a while to understand the structure of the program, which is written in Fortran, Python, and a bit of C. All the signal processing is done in Fortran, and so is the scheduling of the transmit/receive cycles. The GUI, including the manual frequency changes, is in Python. The C code implements some external interfaces, to the audio subsystem, to start threads, and so on.
The changes I made to the Fortran code were minimal. I added two global variables that are accessible from both Fortran and Python. One is a binary flag that is used to tell the Python code when frequency hopping is allowed. It is set by the Fortran code when it finishes transmitting of receiving. It is cleared by the Fortran when it starts transmitting or receiving, and it is also cleared by the Python immediately after hopping, to avoid double hop. The other variable is set and cleared by the Python, and it tells the Fortran whether automatic hopping is active or not. This variable is used by the Fortran code when a new transmit/receive cycle begins, at the beginning of an even whole minute. If the variable is set, the Fortran code choses between receiving and transmitting completely randomly, with probabilities that reflect the user’s requested transmit fraction. If the variable is not set, the decision rule is the one that was in use before hopping (it’s a bit more complicated, to disallow consecutive transmit cycles in most cases).
I made two changes to the Python code. One is a new set up panel for frequency hopping. You can see it in the screen shot above. It has a check box for every band and a slider to set the transmit fraction. In the screen shot, I hop on three bands but transmit on none of them. If one of the check boxes is checked, we are in hopping mode (this affects T/R scheduling, as I explained above). The second change was to inspect periodically the variable that tells us whether it is a good time to hop. If so, we clear, search a band to hop to, and hop. This is basically it.
Joe Taylor, WSPR’s author, added me to the list of developers, which allowed me to upload the new code to the subversion repository. Joe tested it and it seems to work for him too. Hopefully this feature will get released soon. Currently, the hopping feature will show up in the menu only if the user adds a file called hopping.txt to the WSPR’s program directory. Without the file, the program won’t hop and its behavior is essentially unchanged. This should allow people to test it without everybody suffering from bugs if there are any
Martin Ehrenfried pointed out on the WSPR forum that when switching bands, it is worth transmitting a bit, even for a short while, to allow automatic antenna tuners to tune to the new frequency. In fact, this is one of the features of the existing T/R scheduling in WSPR: it transmit in the second cycle after startup, to allow you to tune (I didn’t figure this by myself; Joe explained this to me). The current idea is to add an option to transmit for a few seconds in the period between the end reception or transmission in one cycle and the beginning of the next, if we hopped. Each transmission or reception is 110 seconds long, so we have 10 seconds available until the next cycle begins. I have not started working on this yet, but I plan to. But Joe already added a feature to invoke a user script of program after hopping, which he uses to switch antennas.
Here is the log of my first hopping operation; it shows spots on 7, 10, and 14MHz.
| Timestamp | Call | MHz | SNR | Drift | Grid | Pwr | Reporter | RGrid | km | az |
|---|---|---|---|---|---|---|---|---|---|---|
| 2010-11-23 06:26 | OK1ITK | 7.040077 | -21 | 0 | JN79is | 5 | 4X6IZ | KM72jc | 2573 | 132 |
| 2010-11-23 06:24 | DK8FT | 7.040027 | -21 | -1 | JN58pe | 5 | 4X6IZ | KM72jc | 2661 | 124 |
| 2010-11-23 06:22 | IZ3ATV | 7.040140 | -27 | 0 | JN55vk | 5 | 4X6IZ | KM72jc | 2470 | 119 |
| 2010-11-23 06:22 | DF6MK | 7.040009 | -16 | 0 | JN68ik | 5 | 4X6IZ | KM72jc | 2591 | 126 |
| 2010-11-23 06:22 | EA1URO | 7.040092 | -13 | 0 | IN62bh | 5 | 4X6IZ | KM72jc | 3901 | 93 |
| 2010-11-23 06:20 | G6HUI | 14.097090 | -26 | 1 | IO81wl | 5 | 4X6IZ | KM72jc | 3682 | 111 |
| 2010-11-23 06:20 | DL2RMC | 14.097042 | -21 | 1 | JN68ig | 5 | 4X6IZ | KM72jc | 2580 | 126 |
| 2010-11-23 06:18 | PA2PF | 10.140189 | -28 | 0 | JO22jq | 5 | 4X6IZ | KM72jc | 3319 | 122 |
| 2010-11-23 06:14 | IQ4AX | 10.140202 | -24 | 0 | JN54ks | 1 | 4X6IZ | KM72jc | 2499 | 116 |
| 2010-11-23 06:14 | ES1HJ | 10.140141 | -18 | -1 | KO29hj | 5 | 4X6IZ | KM72jc | 3127 | 162 |
| 2010-11-23 06:10 | F6BIA | 10.140231 | -27 | -1 | JN18dq | 2 | 4X6IZ | KM72jc | 3274 | 112 |
| 2010-11-23 06:00 | KC1PO | 7.040148 | -26 | 0 | FN42ih | 5 | 4X6IZ | KM72jc | 8827 | 56 |
| 2010-11-23 06:00 | K4MOG | 7.040098 | -14 | 0 | EM73qw | 5 | 4X6IZ | KM72jc | 10316 | 48 |
| 2010-11-23 05:58 | F6BIA | 10.140231 | -25 | 0 | JN18dq | 2 | 4X6IZ | KM72jc | 3274 | 112 |
| 2010-11-23 05:56 | LA3RK | 7.040120 | -26 | 0 | JO59hw | 5 | 4X6IZ | KM72jc | 3569 | 139 |
| 2010-11-23 05:56 | LY2BOS | 7.040039 | -13 | 0 | KO24or | 1 | 4X6IZ | KM72jc | 2627 | 159 |
| 2010-11-23 05:56 | IZ3ATV | 7.040139 | -25 | 1 | JN55vk | 5 | 4X6IZ | KM72jc | 2470 | 119 |
| 2010-11-23 05:56 | G7BZD | 7.040095 | -24 | 0 | IO90fq | 5 | 4X6IZ | KM72jc | 3612 | 111 |






