Today I have been working on getting my Propeller WSPR beacon to obey WSPR's timing rules. I have implemented the notion of TX Percent. As mentioned in previous posts, I define TX Percent in this way as there is no clear definition in Joe Taylor's documentation on WSPR.
CON
TXPercent = 0.20 ' Transmit 20% of the time
VAR
LONG SecondCnt, Stack[16], Sync
PUB Init
Sync := ROUND(1.0 / TXPercent * 2.0) ' Calculate when next xmit occurs in minutes
Sync += (Sync // 2) ' Always send on a 2 minute boundary
Sync *= 60 ' Minutes
SecondCnt := 0 ' Reset the second counter to zero
cognew(Clock, @Stack) ' Start the clock COG
PUB Clock ' Runs In its own COG
repeat
delay(1000) ' Update second counter every 1000 ms
SecondCnt++ ' Should be good for 2^32 seconds or about 136 years
Ok, so TX percent of 20% means you will transmit every 10 minutes. If you want to change how often you transmit, change the value of TXPercent. I modified the code to not send when TXPercent is zero as this is listen only mode.
PUB sendCode(stringptr)
if TXPercent > 0
repeat strsize(stringptr)
sendSymbol(byte[stringptr++])
The Clock procedure runs on its own COG and just keeps track of seconds. The presumption is that you flip on the Propeller board at precisely the start of an even minute.
Lastly, I modified the main routine to wait for the next transmit window.
PUB doInitialize
repeat
' Send symbol set for KO7M CN87 7
sendCode(string("<paste in your WSPR encoded message here>"))
noTone
repeat while SecondCnt // Sync
delay(100)
I have the updated code running now on 10.140.200 every 10 minutes at about 7 dBm (5 mW). Look for me in the spot database. I am seeing about -3 drift typically when running on a 10 minute cycle. I will have to experiment with better temperature control of the board to see if I can eliminate that.
For those interested, here is the entire beacon Spin code. I have removed my WSPR coded message. Please see my previous post on how to create that for your call sign, grid square and power level in dBm.
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
WMin = 381 'WAITCNT-expression-overhead Minimum
RFPin = 27
Frequency = 10_140_200
ErrorOffset = -431
symbolLength = 683 ' 8192 / 12000 * 1000 = milliseconds
TXPercent = 0.20 ' Transmit 20% of the time or about every 10 minutes
OBJ
Freq : "Synth"
VAR
LONG SecondCnt, Stack[16]
LONG Sync
PUB Main
doInitialize
repeat
' Send symbol set for KO7M CN87 7
sendCode(string("<paste your own WSPR coded message here>"))
noTone
repeat while SecondCnt // Sync
delay(100)
PUB doInitialize
Sync := ROUND(1.0 / TXPercent * 2.0) ' Calculate when next transmission occurs in minutes
Sync += (Sync // 2) ' Make sure we always send on a 2 minute boundary
Sync *= 60 ' Convert minutes to seconds
SecondCnt := 0 ' Reset the second counter to zero
cognew(Clock, @Stack) ' Start the clock COG
PUB sendCode(stringptr)
if TXPercent > 0 ' TXPercent of zero indicates we are not transmitting
repeat strsize(stringptr)
sendSymbol(byte[stringptr++])
PUB sendSymbol(char)
case char
"0":
sendTone(-3)
delay(symbolLength)
"1":
sendTone(-1)
delay(symbolLength)
"2":
sendTone(1)
delay(symbolLength)
"3":
sendTone(3)
delay(SymbolLength)
PUB sendTone(tone)
Freq.Synth("A",RFPin, Frequency + tone + ErrorOffset)
PUB noTone
Freq.Synth("A",RFPin, 0)
PUB delay(Duration)
waitcnt(((clkfreq / 1_000 * Duration - 3932) #> WMin) + cnt)
PUB Clock ' Runs In its own COG
repeat
delay(1000) ' Update second counter every 1000 ms
SecondCnt++ ' Should be good for 2^32 seconds or about 136 years
No comments:
Post a Comment