MSF clocks and timekeeping...

One of the most interesting timekeeping projects with the Arduino has got to be the decoding and display of the time based on the MSF radio signals. MSF is just one of a number of time signals transmitted by radio by various countries around the world but, as I live in the United Kingdom, it is the one I am interested in. MSF doesn't really mean anything in itself as it is simply a station identifier for the transmitter that sends the signal. The signal itself is very simple and consists of a single carrier wave at 60KHz that is interrupted (switched off) to indicate the start of a Second. Other information is also provided by this simple system which, once decoded, can be used to synchronise devices such as an Arduino clock. If you want to find out about other time standards, Google is your friend.

The MSF radio signal is currently transmitted from Anthorn in Cumbria but, from 1950 up to April 2007, it was transmitted from Rugby in Warwickshire To new Anthorn transmitter has the call-sign GBZ but the old MSF name is retained. Time information is provided by the National Physical Laboratory. The signal itself is a straight carrier wave with no modulation so, if you have a receiver which can pick it up, all you will hear is a carrier signal interrupted every second by a carrier off period. In traditional Morse code transmissions the opposite normally occurs as the carrier wave signal is only transmitted when the operator presses their Morse key down.

I first started playing with the MSF signal in 1984 when I bought my first BBC micro computer. I had also just purchased a Radio Shack shortwave receiver which could receive the Rugby MSF signal very clearly on 60KHz. I was fascinated by how this simple on-off signal could be used to provide time information so I researched all the information available at my local library (no Internet in those days!) and listened carefully to the MSF signal to try and understand it.

A small modification to my shortwave receiver produced a very clean digital output of the MSF signal which I was then able to feed into my BBC micro. Lots of coding later I was able to decode the basic time information provided by the MSF signal and display the time, date etc. on my monitor screen. Believe me, in those days, this was like winning the lottery!

Please be aware that the MSF signal is NOT 24/7/365 but, scheduled outages are announced at:

http://www.npl.co.uk/science-technology/time-frequency/products-and-services/time/msf-outages

With modern Real Time Clock devices it is possible to make a very precise clock with no outside synchronisation required but, this is where the terms "accurate" and "precision" need some explanation. An accurate clock displays the time based on a reference (in the case of MSF it's UTC) whereas a precision clock displays time in a precise manner but isn't necessarily  "accurate". For example, I may make a very precise RTC clock which maintains its time to with a few milli Seconds a day but, what time did it start out at? How do I set the time on the RTC device in the first place? If I set the time at UTC + 1 Second, it will remain precise to that time but it is always out by 1 Second and is therefore NOT accurate.

How we measure the time and set our clocks is a minefield. There's an old saying that a "stopped" clock is the most accurate because it is always exactly right twice a day! If I want an "accurate" clock, I need to set it to a time reference such as UTC or UT1 and maintain the clock at the same time as the reference.

UT1 or Universal Time is the time determined by methods such as observation of the sun and even quasars. It is universally known as Solar Time. Greenwich Mean Time (GMT) is UT1.

UTC or Universal Time Coordinated is derived from atomic clocks and is within 1 Second of UT1.

DUT1 is the difference between UT1 and UTC in ms.

MSF time is derived from UTC and is within 1mS of UTC.

I have read a lot of articles on the MSF time signal and how to decode it and I have to say that there are quite a few people out there who don't understand the system so, I will try and explain how it works. (I could also be one of those that doesn't understand it either and if I don't, please tell me).

The MSF time signal is a carrier wave transmission at a frequency of 60KHz (60,000 Hz) which is switched off or "keyed" for short intervals to represent data. At the start of every second the carrier is turned off for a minimum of 100milliSeconds (abbreviated to mS). The length of this pulse is either 100mS, 200mS or 300mS except on the first second of the minute where the off pulse is 500mS so, each second there is at least 700mS of carrier before the next interruption on normal seconds and 500mS of carrier on the first second of the minute. It is the off pulse length that carries the data. Just to complicate things a little, some seconds can have 2 x 100mS pulses.

The data present in the signal is binary and can be thought of as 2 channels of data, the "A" channel and the "B" channel. The "A" channel carries the actual time data and can be read on its own for basic time decoding. The "B" channel carries additional information such as the difference between the MSF signal which is UTC (Universal Time Co-ordinated) and Universal Time also known as DUT1. This difference can be ignored for all normal applications. The "B" channel also carries Parity bit data for use in checking that the time data on channel "A" is correct and if you need it, the difference between UTC and Universal Time (known as DUT1).

The binary data sent is as follows:

"B" Channel bit

"A" Channel bit

Carrier off pulses per Second

0

0

100mS off

0

1

200mS off

1

0

100mS off + 100mS on + 100mS off

1

1

300mS off

0

0

500mS off (Start of Minute)

Looks fairly simple doesn't it? well, there are a few additional matters to consider. For instance, there are not always 60 seconds to a minute in MSF land. At certain times during the year, "leap" seconds are either added to or subtracted from the MSF data stream meaning that there can be 59, 60 or even 61 seconds. Luckily, this doesn't happen very often and a lot of software ignores the leap seconds which is fine for most normal applications. Why are there leap seconds? as already discussed, MSF (UTC) time differs from Universal Time and the rate of change is not constant so, when the difference between UTC and UT becomes large enough, a second is added or removed to correct the error.

Small differences between UTC and UT are sent in the MSF time signal so that equipment that requires absolute accuracy can be adjusted "on the fly".

British Summer Time or BST indication is also included in the signal.

How the MSF time data is transmitted:

Data

START

DUT1 Positive Offset

DUT1 Negative Offset

Second/bit

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

"A" data

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0*

"B" data

0

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x*

Second "0" is the first second of the minute and is indicated by a 500ms pulse. The next 16 seconds/bits carry the difference between UTC and DUT1 in steps of 100ms. Only the "B" bits carries the data, the "A" bits are always zero. Bit 16 is special as Leap Seconds are either added or subtracted here. When added, an extra bit 16 is transmitted, when subtracted, bit 16 is not transmitted at all.

Data

Year (00-99)

Month (01-12)

Date (01-31)

Day (0-6)

Second/bit

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

"A" data

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

"B" data

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

The next block of seconds/bits (17A - 38A) carries the Year, Month, Date and Day of the Week data. Only the "A" bits carry the data in BCD (Binary Coded Decimal) format. The "B" bits are always zero.

Data

Hour (00-23

Minute (00-59)

Marker/Parity/BST

Second/bit

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

"A" data

x

x

x

x

x

x

x

x

x

x

x

x

x

0

1

1

1

1

1

1

0

"B" data

0

0

0

0

0

0

0

0

0

0

0

0

0

0

*

P

P

P

P

**

0

Seconds/bits 39A - 51A carry the Hour and Minute data. Only the "A" bits carry the data in BCD format. The "B" bits are always zero. Seconds/bits 52 - 59 are special and carry the most vital data (apart from the time and date of course). "A" seconds/bits 52A - 59A always (until further notice) carry the binary sequence "01111110" which, as it can only occur after reception of second/bit 59, indicates that the next second will be the Start of the next minute. This is very useful as its presence tells us when we can use the received data.

"B" second/bit *53B is used to indicate that BST (British Summer Time) is going to start and is set to "1" for 61 minutes prior to the start of BST. Second/bit *58B is the actual BST bit and changes when BST begins. Seconds/bits "B" 54B - 57B are parity bits and are used to check that the time and date data has been received correctly.

Receiving the MSF signal:

We need a radio receiver that is tuned to 60KHz and that is able to provide an output suitable for the Arduino to read. Luckily, there are ready made receivers available and they don't cost a fortune. The one I use came from PV Electronics and cost about 10 UK Pounds with shipping. Another source of MSF receivers is so-called "Radio Controlled" clocks such as those sold by Lidl as they (at the time of writing) contain a separate receiver module that can be used with the Arduino (shown below).

These receivers are simply a small aerial made form a Ferrite rod with a lot of turns of wire around it. This aerial is connected to a digital circuit which has a crystal for the relevant frequency (these modules can be used for other systems such as DCF77 by simply changing the aerial and crystal). The digital circuit removes the 60KHz carrier signal and outputs a simple on/off signal representing the carrier state. The output of these receivers is often inverted so that the output goes "high" or "logic 1" when the carrier is off. Some go "low" or "logic 0" when the carrier is off. It doesn't matter as we can alter our software as required. Some receivers have an LED which flashes when the carrier is off and this can be very useful although, the sketches I present later all flash the LED on Pin 13 of the Arduino anyway.

All sounds very simple doesn't it? well, it isn't. Trying to receive signals at 60KHz is a nightmare as, at this frequency and with a small Ferrite aerial, you are also going to be receiving every pop, bang, Sun spot, faulty car ignition, refrigerator compressor etc., etc., etc.  and these will all affect and degrade the MSF signal by producing erroneous pulses which will have to be filtered by our software. Another complication is that we need to receive a whole Minute's worth of data, without error, before we can decode the time correctly so, one false pulse and we have to start over.

My trusty Casio Wave Ceptor MSF watch failed recently with loss of MSF signal. I found that I could manually reset it to pick up the signal and it would last all day but, overnight, it would lose the MSF signal again. The watch was 5 years old so I changed the battery but, still no difference so I decided to play detective. I always leave my watch on a small table overnight, next to our DAB Clock Radio and there had never been a problem before but, I had recently placed a DECT telephone on the table as well and it was this device that was affecting my watch. I moved the phone and all was well again.

To make the most of the MSF signal, place the receiver away from all possible sources of interference including but not restricted to, computers, cell phones, radios, televisions etc. You will soon know if you have interference by the way the LED flashes on your receiver. It should be possible to make sense of the pulses with a little practise but if all you see are random rapid flashes, give up and move your receiver.

The aerial must also be horizontal and at right angles to the transmitter. If you live due South of Anthorn, Cumbria, your aerial should be aligned East - West or as near to that as possible.

And finally, although most MSF receivers will work between 2.5V and 5.5V use the 3.3V supply from your Arduino as this voltage does really work best. Also consider mounting your receiver and aerial on a panel of some sort and use a long(ish) cable to bring its output to your Arduino until everything is working. This allows you to find the best signal position but keep your arduino where you want it. Have a look at Peter Balcombe's MSF - RTC project for some idea of how to make use of an MSF receiver module.

Decoding the MSF signal:

If you haven't been frightened off by now, let's look at how to decode the MSF signal. Firstly, it is pointless to try and use the MSF time data on its own as even one lost minute will ruin your clock. The way to use MSF data is as a means of correcting or synchronising a clock that is already present. You can use a DS1307 RTC module and/or the excellent Arduino Time library as your clock. This is how commercial "Radio Controlled" clocks work. For instance, my Casio "Wave Ceptor" wristwatch synchronizes 8 times a day with the MSF signal. More information on RTC modules can be found here.

There is a MSF Decoder library available for the Arduino but, it has problems and I always try to write my own solutions so, you have a choice but, I will only talk about my sketches and solutions here. The "Proof of Concept" sketch, presented later, displays the time within 10ms of MSF time.

Here's how we wire up our MSF receiver to our Arduino Uno using the PV Electronics module:

With the MSF receiver wired up and power applied, the LED on the receiver (if fitted) should flash in response to the pulses in the MSF signal. If it doesn't go back and double check your wiring!

The normal inputs/outputs on these MSF receivers are:

Vdd = 3.3V input

GND = 0V

TCON = Digital output of Carrier signal

PON (if provided) = Power ON

The PON input is usually grounded to 0V to enable the receiver. If it is left unconnected the receiver enters a very low power state. This is useful for battery powered clocks.

I have written two sketches available in the downloads section to demonstrate what can be done with the MSF data as follows:

1: Basic sketch which displays the MSF data in its raw form via the Serial port

2: An actual clock which outputs to the Serial port

The "Proof of Concept" sketch indicates the signal pulses on the LED on Arduino pin 13. The sketch is designed to work with the Arduino IDE Serial Monitor but, it works better with a VT100 Terminal Emulator.

The baud rate is 9600 but you can increase this if you like.

The sketch uses the Arduino interrupt on pin 3 (it can be reconfigured for pin 2 if required) and calculates the pulses lengths, checks the parity of the data, decodes the time and date data every minute and prints it out to the Serial Monitor every minute. It also shows the data bits as they are received as either 0,1,2 or 3 characters. The number of seconds received is also shown along with the DUT1 data.

It is a "thrown together" sketch with lots of notes but it does work. Please feel free to modify it as you feel fit as long as you respect my copyright notice.

There is a constant called "CARRIER_OFF" near the start of the sketch which is set to "HIGH" for receivers that invert the signal e.g. give a high pulse when the carrier goes off. If your receiver gives a low pulse when the carrier is off, change "CARRIER_OFF" to "LOW".

The serial output of the sketch is shown here using HyperTerminal but any other VT100 terminal emulator will work. As can be seen, all the basic information is printed including the DUT1 data.

If you use the Arduino IDE Serial Monitor you will see an extra "0" before each "2" because the Arduino monitor won't process backspace characters. On a standard terminal you will see a "0" written then quickly overwritten by a "2". This only occurs when "B" bits on their own are received. The actual data stored within the program is correct.

In the data stream "0" = 0, "1" = "A" bit only, "2" = "B" bit only, "3" = "A" & "B" bits.