I have been trying to work with a PV electronics MSF radio clock unit. I found this 4 year old thread on using MSF, and even some code for the PV electronics unit, http://www.picaxeforum.co.uk/showthread.php?11334-Decoding-UK-s-NPL-MSF-Time-Signal/page3&highlight=msf*
I am using a 20m2+ with the clock attached to pinb.0. I have made a few changes to the code as I am currently not using an LCD or DS1307. Just trying to wrap my head around things for a minute, original code in post #93, un-needed bit have been commented out for the most part with very few actual changes made.
the aerial is horizontal. if it placed vertically the system fail to get to the "waiting" section. As far as I can tell its failing parity tests as well.
attached is a screen grab of the output.
I am using a 20m2+ with the clock attached to pinb.0. I have made a few changes to the code as I am currently not using an LCD or DS1307. Just trying to wrap my head around things for a minute, original code in post #93, un-needed bit have been commented out for the most part with very few actual changes made.
the aerial is horizontal. if it placed vertically the system fail to get to the "waiting" section. As far as I can tell its failing parity tests as well.
Code:
' ********************
' ***** Symbols *****
' ********************
symbol LCD = 6
symbol BAUD = N2400
symbol Line1 = 128
symbol Line2 = 192
symbol Line3 = 148
symbol Line4 = 212
symbol carrier_on = 1 ' input pin state for carrier on
symbol carrier_off = 0 ' ditto off
symbol bit_time = w0 '(b0 b1)
symbol address = w0
symbol parity_test = w0
symbol temp_word = w1 '(b2 b3)
symbol ADVal = w0
symbol year = b4
symbol month = b5
symbol day = b6
symbol dofw = b7
symbol hours = b8
symbol mins = b9
symbol secs = b10
symbol bitA = b11
symbol bitB = b12
symbol i = b13
symbol tempL = b14
symbol nbits = b14
symbol tempH = b15
symbol rt_sec = b16
symbol rt_mins = b17
symbol rt_hours = b18
symbol rt_day = b19
symbol rt_date = b20
symbol rt_month = b21
symbol rt_year = b22
symbol parity = b23
symbol rx_parity = b24
symbol parity_result = b10
symbol parity_flag = b25
symbol press_adjust = 180
symbol samples = 10
#no_data
' ***************************
' ***** Initialisation *****
' ***************************
init:
#terminal 9600
dirsB = %00000000 'setup Port-BG as outputs
Pause 500
'SerOut LCD, BAUD,(254,1,254,14) 'Clear LCD
Pause 50 'Wait for screen to clear
'high 5 'write protect eeprom
' *********************************
' *** Main loop - Display data ****
' *********************************
main:
gosub initialise ' all relevant variables
wait_for_start:
do
gosub receive_sec0
loop while bit_time <= 42
' Found SEC-00, denoted by start bit ~ 500mS
gosub wait_for_data
gosub read_year
gosub read_month
gosub read_day
gosub read_dofw
gosub read_hour
gosub read_mins
' gosub display_pressure
' gosub display_humidity
goto wait_for_start
wait_for_data: ' Now skip 16-bits to get to bit-17 the start of the data for YEAR
sertxd ("waiting",13,10)
for i = 0 to 15
gosub receive_sec
next i
return
read_year:
year = 0
for i = 1 to 8
year = year * 2
gosub receive_sec
year = year + bitA AND $3F
next i
BCDTOASCII year,tempH, tempL
'serout LCD,BAUD,(254,201,"-20",tempH, tempL)
sertxd ("-20",tempH, tempL,13,10)
return
read_month:
month = 0
for i = 1 to 5
month = month * 2
gosub receive_sec
month = month + bitA AND $1F
next i
BCDTOASCII month,tempH, tempL
'serout LCD,BAUD,(254,198,"-",tempH, tempL)
sertxd ("-",tempH, tempL,13,10)
return
read_day:
day = 0
for i = 1 to 6
day = day * 2
gosub receive_sec
day = day + bitA AND $3F
next i
BCDTOASCII day,tempH, tempL
'serout LCD,BAUD,(254,196,tempH, tempL)
sertxd(tempH, tempL,13,10)
return
read_dofw:
dofw = 0
for i = 1 to 3
dofw = dofw * 2
gosub receive_sec
dofw = dofw + bitA AND $07
next i
'serout LCD,BAUD,(254,192)
#rem
if dofw = $00 then serout LCD,BAUD,("Sun") endif
if dofw = $01 then serout LCD,BAUD,("Mon") endif
if dofw = $02 then serout LCD,BAUD,("Tue") endif
if dofw = $03 then serout LCD,BAUD,("Wed") endif
if dofw = $04 then serout LCD,BAUD,("Thu") endif
if dofw = $05 then serout LCD,BAUD,("Fri") endif
if dofw = $06 then serout LCD,BAUD,("Sat") endif
serout LCD,BAUD,(254,128)
#endrem
if dofw = $00 then sertxd("Sun") endif
if dofw = $01 then sertxd("Mon") endif
if dofw = $02 then sertxd("Tue") endif
if dofw = $03 then sertxd("Wed") endif
if dofw = $04 then sertxd("Thu") endif
if dofw = $05 then sertxd("Fri") endif
if dofw = $06 then sertxd("Sat") endif
sertxd (13,10)
return
read_hour:
hours = 0
for i = 1 to 6
hours = hours * 2
gosub receive_sec
hours = hours + bitA
next i
BCDTOASCII hours,tempH, tempL
sertxd(tempH, tempL,":")
return
read_mins:
mins = 0
for i = 1 to 7
mins = mins * 2
gosub receive_sec
mins = mins + bitA
next i
BCDTOASCII mins,tempH, tempL
sertxd(tempH, tempL,13,10)
'return
parity = 0
' Now receive bits 52(1), 53(2), 54(3), 55(4), 56(5), 57(6), 58(7) and 59(8)
gosub receive_sec 'Skip BIT-52B
gosub receive_sec 'Skip BIT-53B
gosub receive_sec 'Get BIT-54B
parity = parity OR bitB
parity = parity * 2 ' shift parity bit in to parity word
gosub receive_sec 'Get BIT-55B
parity = parity OR bitB
parity = parity * 2' shift parity bit in to parity word
gosub receive_sec 'Get BIT-56B
parity = parity OR bitB
parity = parity * 2' shift parity bit in to parity word
gosub receive_sec 'Get BIT-57B
parity = parity OR bitB ' no shift neded for LSB bit in to parity word
'serout LCD,BAUD,("PB=",#parity)
' Parity variable now has the 4 parity bits in the lower nibble.
gosub receive_sec 'Get BIT-58B
gosub receive_sec 'Get BIT-59B
'#rem
'gosub read_RTC
if hours <= $23 AND mins <= $59 AND parity_flag <> "*" then
rx_parity = parity / 8 AND $01
parity_test = year
gosub test_parity
if parity_result = 1 then 'result is ODD
rx_parity = parity / 4 AND $01 ' Move the year parity bit down
parity_test = month * 256 + day
gosub test_parity
if parity_result = 1 then 'result is ODD
rx_parity = parity / 2 AND $01
parity_test = dofw
gosub test_parity
if parity_result = 1 then
rx_parity = parity AND $01
parity_test = hours * 256 + mins
gosub test_parity
if parity_result = 1 then
if hours = rt_hours AND mins = rt_mins then
' gosub write_RTC
rx_parity = "*" ' Indicates all tests passed, RTC was updated
parity_flag = "*" ' Indicate on display that time was received correctly
endif
else
rx_parity = "i" ' Indicates all test passed but not yet on a 30-min boundary e.g. 00, 30 etc
endif
endif
endif
endif
endif
sertxd (parity_flag,13,10)
if rx_parity <> "*" AND rx_parity <> "i" then
rx_parity = "!"
endif
rx_parity = mins // 05 'Only allow time to be updated if on a 5-min boundary
if rx_parity = 0 then
parity_flag = "!"
endif
'BCDTOASCII hours,tempH,tempL
'serout LCD,BAUD,(254,128,tempH,tempL,":")
'BCDTOASCII mins, tempH,tempL
'serout LCD,BAUD,(tempH,tempL,"Hr")
'gosub display_RTC
return
#rem
display_RTC:
gosub read_RTC
BCDTOASCII rt_hours, tempH, tempL
serout LCD,BAUD,(254,140,tempH, tempL,":")
BCDTOASCII rt_mins, tempH, tempL
serout LCD,BAUD,(tempH, tempL,"Hr",parity_flag,254,128)
return
#endrem
test_parity:
nbits = 0
for i = 1 to 16
parity_result = parity_test AND %00000001
if parity_result = 1 then
nbits = nbits + 1
endif
parity_test = parity_test / 2
next i
parity_result = nbits + rx_parity AND $01
return
receive_sec0:
bitA = 0
bitB = 0
if pinb.0 = carrier_off then goto receive_sec0
bit_time = 0
do
pause 8 ' Ideally 10 but 8 takes account instruction delays, determined by a test of this section.
bit_time = bit_time + 1
loop while pinb.0 = carrier_on
'gosub Flash_LED
return
receive_sec:
if pinb.0 = carrier_off then goto receive_sec
Pause 160
bitA = pinb.0 & $01
Pause 100
bitB = pinb.0 & $01
'gosub Flash_LED
'gosub display_RTC
Pause 275
return
initialise:
year = 0
month = 0
day = 0
dofw = 0
hours = 0
mins = 0
parity_flag = "!"
'SerOut LCD,BAUD,(254,1)
Pause 400
sertxd ("Started", 13,10)
return
'
' END initialise
#rem
Flash_LED:
High 3
Pause 40
Low 3
Return
write_RTC:
' Time has to be sent in BCD format to the clock
i2cslave %11010000, i2cslow, i2cbyte
'Format is 'secs,mins,hours,day, date,month,year, control - control byte is $10
rt_sec = 0
writei2c 0, (00,mins,hours,rt_day,rt_date,rt_month,rt_year,$10)
return
read_RTC:
' Format is secs,mins,hours,day,date,month,year
i2cslave %11010000, i2cslow, i2cbyte
readi2c 0, (rt_sec,rt_mins,rt_hours) ',rt_day,rt_date,rt_month,rt_year)
return
#endrem
' END OF PROGRAMME
Attachments
-
50.6 KB Views: 24