Time setting for Raspberry Pi on a Boat

If you have a raspberry pi, or other small computer, on your boat you may have found that it can’t tell the time. It does not have a real time clock and backup battery, so will forget the time when switched off. If it is connected to the internet, it would normally set the clock when it starts up using NTP - the network time protocol - by asking various servers on the internet for the time. On a boat without an internet connection you need another time source.

Some possible solutions are:

  1. Add a real time clock to the pi. These are available in the form of a small module with a coin cell battery. Once the time is set it will then remember it. These cost about $2 for aliexpress.

  2. Use a GPS. GPS receivers know the time very accurately. The pi can extract the time from NMEA messages if it is connected to some GPS receiver on the boat. Alternatively, you can add a GPS module to the pi itself. These are surprisingly cheap, and on a GRP boat you probably don’t need an external antenna. If you can afford to splash out about $5, many of these also come with a real time clock and backup battery, so even without GPS signal they do the same job as an RTC module.

  3. Set the clock from another computer, like your laptop. You can configure NTP on the pi so that instead of asking servers on the internet what time it is, it can ask your laptop, which probably knows the time well enough from when it was last on the internet. Obviously this only works if your laptop is on and connected to the pi on your boat’s network.

Using an RTC module

I won’t describe how to do this here. I’ve not tried it, and there are already tutorials on the web which explain it well.

The only advantage I think there is to this solution, compared to a GPS module, is that it will use less power. It’s probably also easier if you don’t like configuring linux systems.

Using GPS

To set the time from an NMEA stream you can use ntpd (whether or not you also want to use it to set time from the internet). The NMEA data can come from the boat’s network or a locally connected GPS. ntpd knows how to read the time from gpsd, which reads data from a locally connected gps. I use kplex, which can read NMEA from the network or locally, and can be configured to look like gpsd so ntpd can also read the time from it.

gpsd

gpsd is simpler but more limited than kplex. It will only look for a locally connected gps device. I won’t describe the setup here because I don’t use it. If you want to receive NMEA data from a network over tcp for example, or from USB or serial GPS devices, kplex is very good.

kplex

If you are using kplex, you can add the following to your /etc/kplex.conf to provide something that ntpd will recognise:

# Output time for ntpd
[pty]
mode=master
direction=out
filename=/dev/gps0
baud=4800

# Output filter on this interface - only output the needed message with time
# in it. I am using GPGLL but you should use GPRMC or GPZDA to get the date
# too if your GPS outputs that.

ofilter=+GPGLL:-all

You must also have setup kplex to receive NMEA data from somewhere.

ntpd configuration

If you pi is running another variant of NTP software such as chrony or systemd-timesyncd you should disable those to avoid fights. Here is my ntpd config file:

restrict 127.0.0.1
driftfile  /var/lib/ntp/ntp.drift

# If you have lines like this in the default config for your operating system
# it is polite to use the servers provided. (i.e. not debian if you are using
# something else.)

server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst

# Change <laptop> to the hostname or IP of another computer on your boat
# network that knows the time.
server <laptop> iburst

# NMEA GPS Input
# The IP address 127.127.20.0 is just a kludge ntpd uses to mean local gpsd /
# read time from NMEA stream. It's not actually something on the network.
# My NMEA data comes from kplex, pretending to be gpsd.
server 127.127.20.0 minpoll 4
# fudge 127.127.20.0 flag3 1 flag2 0 # This config is for PPS, which I don't have.

# Set stratum very low so it won't be used unless nothing else available. I do
# this because without PPS, the delays and imprecision in the serial NMEA
# stream probably make it worse than network time.

fudge 127.127.20.0 stratum 14

Problems with NMEA GPS

Time sent over NMEA messages will not be exact because NMEA is slow and there is a delay in the message getting from the GPS to your computer. For exact time, GPS receivers may have a Pulse per Second (PPS) output, when switches on the second each second. If precision within a second is good enough you don’t need to worry about this. A marine GPS receiver will probably not have this anyway. If you need it, you can buy a GPS module with PPS to connect directly to the pi. You almost certainly don’t need it.

An actual problem might be lack of date. The GPRMC and GPZDA NMEA messages (can) contain the GPS date and time. On my boat, I only get the time but not date from my receiver.

A GPZDA message that contains only the time (19h 46m 44s). The date would be between some of those commas.

$GPZDA,194644,,,,00,*42

I could set the date manually, but I actually use NTP.

Using NTP (with or without a GPS receiver)

On the pi, you can use the same ntpd configuration file as the above used for GPS, but comment out the GPS server line. You can also use any other ntp software and add your laptop or other local machine that knows the time as an ntp server.

Then you need to configure the laptop as an ntp server so it will respond to time requests from the pi. I won’t go into the details of that because it depends on what software you are using on that machine. You may need to configure it to allow requests, possibly only from the local network, and also allow connections in on your machine’s firewall.