|flabbergast e557366978 Make sure python knows about utf-8.||4 years ago|
|bin||4 years ago|
|cgi-bin||4 years ago|
|configs||4 years ago|
|time-from-gps||4 years ago|
|watcher-daemon||4 years ago|
|README.md||4 years ago|
|auth||4 years ago|
These are instructions on how to make a Raspberry Pi into a time server, with the help of a GPS addon board.
The result should be that the Pi will continuously get current time from the GPS unit, which will be then served outside via a NTP daemon. The NTP deamon will not run if the GPS unit does not have a signal (so as not to announce wrong time). A simple web interface is provided, to monitor the status of the GPS, NTP daemon, and some other server status data.
Note that this setup is not secure, so don’t let the net see your Pi! (I.e. use it behind a firewall or something.)
SSH daemon should be running by default. The first run should be either with a keyboard and a monitor, or plugged into a router (so that we can ssh into it, a DHCP client is waiting on the ethernet port).
We want a gps daemon, some clients, and some misc utils that I can’t do without.
sudo apt-get install git htop gpsd gpsd-clients supervisor lighttpd
/etc/network/interfaces. I wanted two static configs on the ethernet port, so changed
iface eth0 inet dhcp to
auto eth0 iface eth0 inet static address 192.168.3.14 netmask 255.255.255.0 gateway 192.168.3.1 auto eth0:0 iface eth0:0 inet static address 192.168.0.1 netmask 255.255.255.0
We need to change the default configuration (getty on the serial port), so that linux doesn’t try to communicate/access the serial port, which now has a GPS unit attached to. So:
/etc/inittab(probably last line)
Make it does not start on boot (will be managed by
sudo dpkg-reconfigure gpsd
Also make sure it doesn’t start automatically. Also will be managed by
sudo update-rc.d ntp disable
sudo update-rc.d lighttpd disable
Get the files and put them into
/opt/gps-timekeep (this path is hardcoded into things -- I’m lazy).
sudo mkdir /opt/gps-timekeep sudo chown pi:pi /opt/gps-timekeep cd /opt git clone https://github.com/flabbergast/gps-timekeep.git
Alternatively, download a zip by clicking on “Download ZIP” in the right column, unpack it, and copy the contents of
This will get you configurations files for the daemons (will be used by supervisor),
time-from-gps python scripts and a python cgi script which displays system info and lets you edit some config files. What remains to be done is:
sudo cp /opt/gps-timekeep/configs/daemons.conf /etc/supervisor/conf.d
supervisord, and restart it
sudo /etc/init.d/supervisor stop sudo /etc/init.d/supervisor start
Now you should have access to a basic info web page (on port
80) and to
supervisord web interface (on port
The “Further info and configuration” webpage, as well as access to
supervisord, is password protected (don’t feel protected by this, it’s not really secure). The name:pass is
admin:muflon. There is a web form to change this, but making it work is another privilege escalation (see also “Optional extras” below), so requires making two files writable by the
lighttpd process. So:
sudo chgrp www-data /etc/supervisor/conf.d/daemons.conf sudo chown g+w /etc/supervisor/conf.d/daemons.conf
The other file,
/opt/gps-timekeep/auth should be set up OK already, but just in case it isn’t:
chmod 0666 /opt/gps-timekeep/auth
If you want to remove the password protection:
/etc/supervisor/conf.d/daemons.confand remove the two lines (
/opt/gps-timekeep/configs/lighttpd.confand comment out the
Some actions from the web interface require privilege escalation (I couldn’t convince
lighttpd to run as root), so:
If you want to be able to edit the system configuration from the web interface, you’ll need to change the permissions of the corresponding files so that they are writable by the user/group as which the
lighttpd web server runs. For instance:
sudo chgrp www-data /etc/network/interfaces sudo chown g+w /etc/network/interfaces
This changes the group of
www-data and makes it group-writable.
Similarly, if you want to be able to reboot from the web interface, you need to make it possible for the
www-data user to execute
/sbin/reboot. The easiest (and most unsafe) way is to make
/sbin/halt (to which
/sbin/reboot is a symbolic link) setuid root:
sudo chmod +s /sbin/halt
(Archlinux users need to edit
configs/lighttpd.conf and change the user and group to
/dev/ttyAMA0, and produces PPS pulse on GPIO pin 18 (every second).
gpspython module, the debian package is
/opt/gps-timekeep! Also some assumptions that a debian-based system is used are in place (e.g.
/sbin/reboot -> /sbin/halt,
lighttpdruns to provide a “web interface”. Its main function is to provide info about the status of things.
gpsddaemon. This one is supposed to be running all the time, and all the other programs get GPS info through it. Among other things, it writes the current time received from GPS (“coarse time”) to a “shared memory” segment, where it can be read by
ntpddaemon. It reads the shared memory segment to get GPS time. However, there are a couple of quirks/issues:
ntpdcan’t use the PPS signal from the GPS unit directly. So a workaround daemon,
rpi_gpio_ntp, needs to be running to receive the PPS pulses and write the precise time to the shared memory segment to be read by
ntpd. The thing is that
rpi_gpio_ntpneeds to start only after GPS has a fix and the system time is approximately correct (I’m not sure how it works and why, this observation comes from my experience).
ntpdrefuses to read time from the shared memory segment for some reason, and restarting things doesn’t help me. A “fix”, which seems to work for me is to set the system time to an approximately correct time before starting any daemons.
time-from-gps.py: this is a “startup” script. It waits until GPS reports a fix and a time, and subsequently sets the system time (to an approximately correct one) and starts the other daemon:
gps-watcher.py: monitors the GPS for signal. If there’s no signal, it stopd
rpi_gpio_ntp. If there is signal, it starts them up. Also, it regenerates the basic static html page (every 2-3 seconds).
supervisordruns its own web interface on port 9001.
serverconfig.py), which gives more system info, and lets you edit
/etc/network/interfacesand reboot the Pi (see “Optional Extras” for what’s needed to make this work).
gpsdparameters should contain
-n. This is so that gpsd starts listening to the GPS device even before a client (like cgps or such) asks for it. we need this so that the timekeeping starts right away on boot.
To test if
rpi_gpio_ntp receives the pulses, run (the
18 is the GPIO pin on which the PPS pulse is sent):
sudo rpi_gpio_ntp -g 18 -d
It should print one line every second (when the pulse comes).
SHMsource is an observed value to make the offset of this source smallish (<5ms). It’s more-less the time which is takes the GPS unit to transmit info over serial and then gpsd to process and enter into the shared memory. It’s likely to be larger (cca 0.350) for GPS units attached over USB.
Current status of the NTP daemon can be observed by running
ntpq -p or
ntpq -pn (
-n for not reverse resolving IP addresses). Most important things about the output:
*means currently used/selected,
xmeans not used
reachcolumn should have
UPPSsource (means ntpd “sees” the source). It changes for a while after ntpd restart, then it should stabilize on
offsetis in milliseconds. Shouldn’t be too big; less than 1 for the
UPPSsource, or at least single digits.
lighttpd is set up to use
/run/www as the main document root, since the status page is updated every 2-3 seconds and so we want to use a
tmpfs filesystem. In other words, stuff from there lives only in the memory and disappears on every reboot!