MSF Clock Difficulties

oracacle

Senior Member
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.

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
attached is a screen grab of the output.
 

Attachments

Jeremy Harris

Senior Member
I've built an MSF clock, and recently tried to build another one, as the master clock for the house data logger. Whereas the one I built several years ago works at our old house, it refuses to lock to MSF at the new house. I tried all sorts of things to get the clock to sync to MSF, but the best I can get is the "waiting" message (I'm using much the same code as you, I think).

What I have found is that if you wait until after midnight, reception tends to improve and the unit locks up to the MSF signal fairly easily. It was as frustrating as hell trying to test it, though, as the slightest bit of interference would stop it locking on to the signal. I even went so far as to make a very long cable, so that I could get the receiver well away from the PC. That improves things, but not enough to get a solid lock during the day.

My solution in the end was to buy a cheap GPS module, and use that, with a bit of code in the Picaxe to predict the change to BST and adjust the hour. My master clock now has two RTCs, one running on GMT, the other on BST. Both are synchronised to GPS time at 01:03 GMT every night. I use the GMT date and time data to control the house data logger and the GMT/BST date and time data just for a display in the hall for now. The intention is to replace several time switches in the house with dumb receivers, that are turned on or off by a master timer that's synchronised to the master GMT/BST clock.
 

oracacle

Senior Member
I have started trying to write my own code from scratch - there is some progress

Code:
main:
	'do while pinb.0 = 1 
	'loop
	pulsin b.0, 1, w4
	if w4 > 40000 and w4 <60000 then
		sertxd ("Minute Marker",44,#w4,13,10)
	'else if w4 = 0 then
		'sertxd("Normal Second",13,10)
	'else
		'sertxd (#w4,13,10)
	end if
	goto main
this shows minute marker on the 0 second every time according to time.is the pulse length varies a little between about ~48000 to ~54000, this I assume is due to when the picaxe arrives to start timing the pulse length.
 

hippy

Technical Support
Staff member
attached is a screen grab of the output.
Seems it is not even getting consistent data for the year after the initial synchronisation pulse.

Best approach would be to develop the code from the ground-up, just read the bits and print those out, check they are as expected and consistent, to start with. If not, try to figure out why not; that could well be inverted signal polarity, bad program timing, or a not very good or reliable signal from the MSF receiver.

There seems to be simpler starting code which just beeps every minute (post #24) and dumps the bit data out (Post #36) in the thread linked to.
 

hippy

Technical Support
Staff member
I have started trying to write my own code from scratch - there is some progress.
As you can tell there was a delay between writing my earlier post and hitting send :)

PULSIN gets a bit complicated and signal polarity can play a big part.

The synch pulse is 500ms off, 500ms on.

The seconds ticks are 100ms off, 100ms A-bit on/off, 100ms B-bit on/off, 700ms on. The on/off periods therefore vary depending on which bits are set.

www.npl.co.uk/upload/pdf/MSF_Time_Date_Code.pdf
 

hippy

Technical Support
Staff member
I'd start with this ...

Code:
Symbol RX_PIN   = pinB.0

Symbol POLARITY = 1

Symbol aBit     = bit0
Symbol bBit     = bit1
Symbol sBit     = bit2

Main:
  Do
    Gosub ReadBit
    If sBit = 1 Then
      SerTxd( CR, LF, "-" )
    Else
      SerTxd( #aBit )
    End If  
  Loop

ReadBit:
  Do : Loop Until RX_PIN = POLARITY
  Do : Loop While RX_PIN = POLARITY
  Pause 150 : aBit = RX_PIN ^ POLARITY
  Pause 100 : bBit = RX_PIN ^ POLARITY
  Pause 100 : sBit = RX_PIN ^ POLARITY
  Return
Untested. If, after a couple of minutes, you don't see "-" and 59 digits, try changing POLARITY to 0.
 

nick12ab

Senior Member
The low frequency MSF signal can suffer badly from interference. Attach an LED to the digital output - this will make it much easier to position the aerial as you can see how clean the pulses are. Rapid flickering of the LED indicates a bad signal.

You may find getting a reliable signal difficult. It is better to simulate the signal when developing the code, then change over to the real receiver once everything appears to work.

Here is some simulator code I made a long time ago. The duration of each bit is accurate; the interval of each byte is not, however, but this doesn't matter if you're using start bit detection for each byte (second of data) rather than timing it all from the minute mark.

Code:
#picaxe 28x2
#no_data
#no_end
#terminal off

table 0,(%00001111,%10,%10,%10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,%01,0,0,%01,0,%01,0,0,%01,0,0,0,0,%01,0,0,0,%01,0,0,0,%01,%0,0,0,%01,0,%01,0,%01,0,%01,0,%01,%11,%01,%01,%01,%01,0)

setfreq m2
hsersetup 51923,%00111
pause 500
do
	for b0 = 0 to 59
		readtable b0,b1
		b1 = not b1
		hserout 0,(b1)
	next
loop
 

oracacle

Senior Member
nick12ab, thanks, even when I get mostly one off signal (the unit has an LED of its own) which does flicker. sometimes its fine, other time it flickers.
Its going to spend its entire life in a Dartmoor valley in a house made mostly of granite walls about 1.5-2 foot thick. This I think is the death knell in this idea - I was a bit dubious about it in first place

I will give hippy's code ago and see what happens though.
 

oracacle

Senior Member
Hippy your code needed to polarity set to 0 before I got anything more than unending "-" and the odd 1. But even then the results were inconsistent. Think its a by product of location - something I had feared at the start of the project.

just have to admit defeat every once in a while. GPS is a bit on the steep side for the project so I will just rely of a good old RTC.

Thanks for the help though, its much appreciated.
 

JimPerry

Senior Member
in a house made mostly of granite walls about 1.5-2 foot thick. This I think is the death knell in this idea - I was a bit dubious about it in first place

I will give hippy's code ago and see what happens though.
Can you drill a small hole for a cable and mount the receiver in a waterproof box on the outside of the house? :confused:
 

hippy

Technical Support
Staff member
Getting good and reliable reception can be tricky. When getting my setup to work on my desk I found that if I leaned back it worked and stopped if I leant forward, was affected by what my computer was doing, was okay when showing the Windows desktop, stopped when full-screen MS-DOS prompt.

Best bet might be to build something battery powered on bread-board, take it outside, take it on your travels, to see if it is location which is the problem. An LCD and some sort of code which could indicate how many good and bad pulses and packets there were might help with that.
 

oracacle

Senior Member
As it happens hippy, my project room contains three computers (one for writing and testing code, a small server and my main rig which is a bit of a beast).
The project needs to be complete fairly soon for various reasons and out side the house isn't really an option as it wold have to go through the roof.

In the future and battery operated setup with an OLED be used for a walk about device to see if I can get something, but that unfortunately is someway down the line.
 

hippy

Technical Support
Staff member
The project needs to be complete fairly soon for various reasons and out side the house isn't really an option as it wold have to go through the roof.
I was really suggesting temporarily take something 'thrown together' outside to see if that works better, to help identify whether there is a problem because of where you are located or a problem with the environment you are trying to make it work within.

But, if it's not looking hopeful, and there is not time to investigate further, then it is fair enough to abandon one idea and go some other way with a project.
 

Jeremy Harris

Senior Member
FWIW, I've found that the relatively cheap Ublox GPS modules work very reliably indoors, even right next to the PC on my bench. You can programme them easily with the free Ublox utility and so get rid of all the extraneous data. Mine is set to only output the GPZDA sentence, which is just the date and time. It will squirt this out even if the reception from the SVs isn't good enough to get a navigation lock. The only snag is that it's UTC, but it's very easy to write a short bit of Picaxe code to change it to BST/GMT, as the BST change dates are fixed and follow an easy to decode pattern.
 

PhilHornby

Senior Member
Another alternative...

Rather than using MSF or GPS, you could instead use an ESP8266 (assuming a mains-powered, indoor project). Ideally, make use of NTP - which involves writing some custom code - or less elegantly, but using the stock firmware - you could parse the "Date:" header from a web-site with a trustworthy time-stamp (perhaps BBC.CO.UK, rather than PICAXEFORUM.CO.UK ;-)

Code:
Date: Wed, 19 Apr 2017 23:48:52 GMT
Even the bottom of the range ESP8266-01 should be able to manage this task.

(I tangled with MSF receivers in a commercial situation about 15 years ago - there were a dozen or more of them, geographically dispersed around the UK. None of them worked properly - not helped by the fact that they were in fact, actually receiving the time signal from somewhere in Germany :eek:)
 

hippy

Technical Support
Staff member
If one has a means to access the Local Area Network many PC operating systems have a ability to run a Daytime or NTP server and it is possible to create or download and app which does that. It is also possible to write a server which can deliver date and time information to a PICAXE over a serial port.

A physical RTC is probably the best solution because it can keep fairly accurate time during power cuts and powered off period. It is not a good idea to rely only on an remote service for time keeping as that service may not always be available when the PICAXE needs it.
 

PhilHornby

Senior Member
If one has a means to access the Local Area Network many PC operating systems have a ability to run a Daytime or NTP server and it is possible to create or download and app which does that.
It could even be an itty-bitty Raspberry Pi...though I was actually suggesting using your ISP's NTP server.

It is also possible to write a server which can deliver date and time information to a PICAXE over a serial port.
Or to combine some previously floated ideas - a 'server' could broadcast the time periodically using a USB-HC12 module, to be received by multiple HC-12 equipped clients:-

[highlight](Simple Windows script to output time once per second, over 433MHz FSK link)[/highlight]
Code:
:loop
echo Time is:%time%>com6:   ;adjust com6: as required
choice /t 1 /d y /n         ;delay one second
goto loop
A physical RTC is probably the best solution because it can keep fairly accurate time during power cuts and powered off period. It is not a good idea to rely only on an remote service for time keeping as that service may not always be available when the PICAXE needs it.
It would depend on the application. Perhaps a hybrid solution, would be to periodically synch the M2 TIME variable, (or an equivalent DIY solution for the X2). (This being the method adopted by Windows NT and all its descendants - where the OS counts 'ticks', but is periodically resynced to the RTC)

Of course, if you go for a standalone RTC, with associated backup battery, you really need to implement a mechanism to check the state of that battery - and perform some sort of remedial action if required.

(As an aside, I once saw a Vax Cluster brought to its knees by a flat backup battery. On boot, one machine prompted the Operator to enter the Date and time manually. He got the month and day back to front and the VMS scheduler then ran every scheduled job simultaneously (since they'd clearly missed their time slots). The resulting mayhem took an awful lot of 'repair work'!).
 

Jeremy Harris

Senior Member
A physical RTC is probably the best solution because it can keep fairly accurate time during power cuts and powered off period. It is not a good idea to rely only on an remote service for time keeping as that service may not always be available when the PICAXE needs it.
Interestingly, the cheap Ublox GPS modules include a battery backed RTC, so if they lose reception they carry on squirting out the time until they re-acquire a signal and correct it to UTC. The GPZDA sentence doesn't stop when the signal is lost, it just switches to the internal RTC. This means there's no need to add a RTC to the Picaxe, although I did, as I didn't realise the GPS module already had one..................
 

Jeremy Harris

Senior Member
@ Jeremy

Which Ublox GPS module do you like using with a PICAXE and/or which one do you recommend..??
I used one of the older Ublox Neo-6 modules, like this: http://www.ebay.co.uk/itm/Ublox-NEO-6M-GPS-Module-Aircraft-Flight-Controller-For-Arduino-MWC-IMU-APM2-New-/281957215228?hash=item41a5f5abfc:g:5tkAAOSwYlJW3VYf
There are newer versions around, but the one thing you have to watch is that some come without the tiny lithium RTC back up battery, some do. It's not problem to just solder on the tiny battery if you get one that doesnt have it fitted, as the pads are there. I believe it's something to do with air shipping that means they leave the battery off.
 

oracacle

Senior Member
Martin, I have been using time.is

The item was intended to use a DS3231 and have the radio clock to keep the thing in check. But if I am completely honest the Charlieplex clock is still absolutely bang on using the DS3231.
the project now has a full complement of hardware and just awaiting for a full write of the software now.
Does anyone know if there are example on the forum for changing the time when DST come around. The last sunday in march goes forward and last sunday in october clocks go back. I was thinking if month = 3 and date > 22 and its sunday change the time @ 2am same for the other end of the year.

something like:
Code:
[color=Blue]if [/color][color=Purple]month [/color][color=DarkCyan]= [/color][color=Navy]3 [/color][color=DarkCyan]and [/color][color=Purple]date [/color][color=DarkCyan]> [/color][color=Navy]24 [/color][color=DarkCyan]and [/color][color=Purple]day [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=DarkCyan]and [/color][color=Purple]hour [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then
            [/color][color=Purple]hour [/color][color=DarkCyan]= [/color][color=Purple]hour [/color][color=DarkCyan]+ [/color][color=Navy]1
      [/color][color=Blue]end if 

      if [/color][color=Purple]month [/color][color=DarkCyan]= [/color][color=Navy]10 [/color][color=DarkCyan]and [/color][color=Purple]date [/color][color=DarkCyan]> [/color][color=Navy]24 [/color][color=DarkCyan]and [/color][color=Purple]day [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=DarkCyan]and [/color][color=Purple]hour [/color][color=DarkCyan]= [/color][color=Navy]2 [/color][color=Blue]then
            [/color][color=Purple]hour [/color][color=DarkCyan]= [/color][color=Purple]hour [/color][color=DarkCyan]- [/color][color=Navy]1
      [/color][color=Blue]end if [/color]
also completely forgot the DS3231 compensates for leap years.
 
Last edited:

hippy

Technical Support
Staff member
Does anyone know if there are example on the forum for changing the time when DST come around.
My feeling is that it is best to always keep the clock running on non-DST time, then add an extra hour to the data read when that is during the DST period.

It make setting the time a little more complicated but it removes all possibility of anything going wrong when entering and leaving DST.
 

Jeremy Harris

Senior Member
Here in the UK, there is a set schedule for switching to DST (BST here), so it's easy to just detect the change point from the date and time data and apply the correction. In my case I reset a separate RTC to BST once a day, at 01:03 UTC. The reason for the odd time is that here the BST switchover happens at 01:00 UTC on either the last Sunday morning in March, or the last Sunday morning in October. I allow 3 mins before changing the clock because I have a data logger that samples every six minutes, starting on the hour. Changing the time at 01:03 UTC means that I get a sample at 01:00 UTC OK. In fact this is a bit redundant now, as I decided to keep the data logger sampling on UTC, ignoring BST, but I haven't bothered to change the time synchronisation code for the RTC that runs the wall display.
 

AllyCat

Senior Member
Hi,

if ..... hour = 2 then
hour = hour - 1
And what happens one hour (and two hours) later?

As hippy says: "My feeling is that it is best to always keep the clock running on non-DST time.... it removes all possibility of anything going wrong when entering and leaving DST."

Cheers, Alan.
 

oracacle

Senior Member
its a loose bit of code, no where near complete, a very similar piece of code could be used to set a flag for BST and the flag check each time the RTC is checked. But the issue is that, that flag would clear in the event of a restart. writing it to the PICAXE EEPROM would solve that though.
 

marks

Senior Member
Hi oracacle ,
I only read the last bit of this thread
I have done some code before as you've described and also using the Julian date (so I could determine the day SUN and adjust for dst) for gps.
this time I used the RTC to save the day lol.
as others have described the best approach to always have the RTC programmed with the standard time and correct the hours ,date and month during the daylight savings period.
I haven't thoroughly tested but seems ok on paper I've added to code snippets in case it needs fixing later lol #17
http://www.picaxeforum.co.uk/showthread.php?18694-DS3231-Code-examples/page2
 

oracacle

Senior Member
hey marks, I actually wrote the BST code on the 25th, final code structure was completely different but works really quite nicely.
It sets the a flag which is checked on each loop of the main programme, if it BST, add 1 and check for overflow, if not carry on. Change is checked 1am every morning, when a change occurs, another flag set so that the check is ignored until 5am to stop multiple changes being made

Code:
      [color=Blue]hi2Cin [/color][color=Navy]$0  [/color][color=Black], [/color][color=Blue]([/color][color=Purple]secs[/color][color=Black],[/color][color=Purple]mins[/color][color=Black],[/color][color=Purple]hour[/color][color=Black],[/color][color=Purple]day[/color][color=Black],[/color][color=Purple]date[/color][color=Black],[/color][color=Purple]month[/color][color=Black],[/color][color=Purple]year[/color][color=Blue])     [/color][color=Green]'Read from DS3231
      [/color][color=Blue]let [/color][color=Purple]tempbyte0 [/color][color=DarkCyan]= [/color][color=Purple]month [/color][color=DarkCyan]/ [/color][color=Navy]16 [/color][color=DarkCyan]* [/color][color=Navy]$FA [/color][color=DarkCyan]+ [/color][color=Purple]month
      [/color][color=Blue]let [/color][color=Purple]tempbyte1 [/color][color=DarkCyan]= [/color][color=Purple]date [/color][color=DarkCyan]/ [/color][color=Navy]16 [/color][color=DarkCyan]* [/color][color=Navy]$FA [/color][color=DarkCyan]+ [/color][color=Purple]date
      [/color][color=Blue]let [/color][color=Purple]tempbyte2 [/color][color=DarkCyan]= [/color][color=Purple]day [/color][color=DarkCyan]* [/color][color=Navy]16 [/color][color=DarkCyan]/ [/color][color=Navy]$FA [/color][color=DarkCyan]+ [/color][color=Purple]day
      [/color][color=Blue]if [/color][color=Purple]tempbyte2 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then                                       [/color][color=Green]'check for sunday
            [/color][color=Blue]if [/color][color=Purple]tempbyte1 [/color][color=DarkCyan]>= [/color][color=Navy]25 [/color][color=Blue]then                               [/color][color=Green]'check for last sunday
                  [/color][color=Blue]if [/color][color=Purple]tempbyte0 [/color][color=DarkCyan]= [/color][color=Navy]3 [/color][color=Blue]then                           [/color][color=Green]'if its march, adnvace time
                        [/color][color=Purple]bst [/color][color=DarkCyan]= [/color][color=Navy]1
                  [/color][color=Blue]else if [/color][color=Purple]tempbyte0 [/color][color=DarkCyan]= [/color][color=Navy]10 [/color][color=Blue]then
                        [/color][color=Purple]bst [/color][color=DarkCyan]= [/color][color=Navy]0                             [/color][color=Green]'if its octobre, regress time
                  [/color][color=Blue]end if
            [/color][color=Purple]ignore [/color][color=DarkCyan]= [/color][color=Navy]1                                      [/color][color=Green]'set ignore flag
            [/color][color=Blue]end if
      end if[/color]
I did actually snag your code for -40 to +85 temp readings, made some changes due to the way thing are displayed. The one thing that I was a little puzzled by was the **25600, my assumption was correction for the 2s complement format that the DS3231 gives it temperature at.
I have done very little with 2s complement, its on the list to learn but life keep getting in the way.
 

pxgator

Senior Member
Here is one way to understand two's compliment numbers.

Code:
[color=Navy]#picaxe [/color][color=Black]08m2[/color]
[color=Navy]#Terminal 4800
#no_data[/color]



[color=Black]eight:[/color]
[color=Blue]for [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]6[/color]
[color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=DarkCyan]- [/color][color=Purple]b1[/color]
[color=Blue]if [/color][color=Purple]b0 [/color][color=DarkCyan]>= [/color][color=Navy]128 [/color][color=Blue]then                         [/color][color=Green];test if bit 7 is set[/color]
[color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Purple]b0 [/color][color=DarkCyan]- [/color][color=Navy]1 [/color][color=DarkCyan]^ [/color][color=Navy]%11111111                   [/color][color=Green];if it is then subtract 1[/color]
[color=Blue]sertxd ([/color][color=Red]"1 - "[/color][color=Black],#[/color][color=Purple]b1[/color][color=Black],[/color][color=Red]" = "[/color][color=Black],[/color][color=Red]"-"[/color][color=Black],#[/color][color=Purple]b0[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)   [/color][color=Green];EXCLUSIVE OR  then show[/color]
[color=Blue]else[/color][color=Black]:[/color][color=Blue]sertxd ([/color][color=Red]"1 - "[/color][color=Black],#[/color][color=Purple]b1[/color][color=Black],[/color][color=Red]" = "[/color][color=Black],#[/color][color=Purple]b0[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)  [/color][color=Green];negative num[/color]
[color=Blue]end if
pause [/color][color=Navy]1000[/color]
[color=Blue]next

sertxd (cr[/color][color=Black],[/color][color=Blue]lf)[/color]

[color=Black]sixteen:[/color]
[color=Blue]for [/color][color=Purple]w2 [/color][color=DarkCyan]= [/color][color=Navy]1000 [/color][color=Blue]to [/color][color=Navy]1005[/color]
[color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Navy]1000 [/color][color=DarkCyan]- [/color][color=Purple]w2[/color]
[color=Blue]if [/color][color=Purple]w1 [/color][color=DarkCyan]>= [/color][color=Navy]32768 [/color][color=Blue]then                       [/color][color=Green];same here but test bit 15              [/color]
[color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Purple]w1 [/color][color=DarkCyan]- [/color][color=Navy]1 [/color][color=DarkCyan]^ [/color][color=Navy]%1111111111111111[/color]
[color=Blue]sertxd ([/color][color=Red]"1000 - "[/color][color=Black],#[/color][color=Purple]w2[/color][color=Black],[/color][color=Red]" = "[/color][color=Black],[/color][color=Red]"-"[/color][color=Black],#[/color][color=Purple]w1[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
else[/color][color=Black]:[/color][color=Blue]sertxd ([/color][color=Red]"1000 - "[/color][color=Black],#[/color][color=Purple]w2[/color][color=Black],[/color][color=Red]" = "[/color][color=Black],#[/color][color=Purple]w1[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
end if
pause [/color][color=Navy]1000[/color]
[color=Blue]next
end[/color]
Cheers to All
 
Last edited:
Top