In this project, a Raspberry Pi 4B is connected to a Neo7 GPS receiver via a USB cable to obtain GPS data, particularly the time information. The Raspberry Pi will then be configured as an NTP server for other IP-based devices.
Real Application
In a secure CCTV system, all components, including cameras, network switches, and NVR recorders, must be isolated to prevent the theft of video footage. Accurate timestamps on the video footage are essential for investigations in the event of accidents or robberies. However, isolated CCTV systems cannot access standard time servers via the internet to obtain real-time information. Therefore, a standalone NTP server is required within this isolated network.
What You’ll Need
- Raspberry Pi 4B with Raspberry Pi OS installed in a 32G SD card
- Neo7 GPS receiver , with GPS antenna
- USB cable (USB A to Micro USB)
- Internet connection for setting up the Raspberry Pi (can be disconnected after installation is complete)
Let’s start
Connect the Neo7 GPS receiver to the Raspberry Pi 4B using the USB cable (USB A to Micro USB) . Attach a GPS antenna to SMA jack of Neo7 GPS receiver. Power on Pi 4B. Try to add heatsink to the GPS receiver as some chips on it is very hot.
Make sure the GPS antenna are placed in an area with clear view of the sky. GPS signals can be obstructed by buildings, trees, or indoor environments.
I assume everyone knows how to install Raspberry Pi OS, add/edit users and change the IP address. These procedures will not be discussed here. Connect to the Pi 4B using WinSCP (in case you are using Window PC) and Putty SSH using your PC.
Install Required Software
(1) Update the System
sudo apt update
sudo apt upgrade
(2) Install NTP and GPS Daemon:
sudo apt install ntp gpsd gpsd-clients
(3) Configure GPSD
After connecting the GPS receiver, check the kernel messages to see if the device is detected. Type the following command and look for messages indicating a new device, like /dev/ttyACM0.
dmesg | grep tty
Returned messages:
[0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_hdmi=0 smsc95xx.macaddr=DC:A6:32:49:5F:7A vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 console=tty1 root=PARTUUID=aacf6751-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cfg80211.ieee80211_regdom=HK
[0.000325] printk: console [tty1] enabled
[2.097007] fe201000.serial: ttyAMA1 at MMIO 0xfe201000 (irq = 36, base_baud = 0) is a PL011 rev2
[2.097244] serial serial0: tty port ttyAMA1 registered
[2.100835] fe215040.serial: ttyS0 at MMIO 0xfe215040 (irq = 37, base_baud = 62500000) is a 16550
[5.256713] systemd[1]: Created slice system-getty.slice - Slice /system/getty.ls
[24.596427] cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
Open the GPSD configuration file:
sudo nano /etc/default/gpsd
Change the configuration to:
START_DAEMON="true"
GPSD_OPTIONS="-n"
DEVICES="/dev/ttyACM0"
USBAUTO="true"
Restart GPSD:
sudo systemctl restart gpsd
Make sure GPS device is successfully detected as /dev/ttyACM0, using the following command:
ls /dev/tty*
Returned messages:
/dev/tty /dev/tty14 /dev/tty20 /dev/tty27 /dev/tty33 /dev/tty4 /dev/tty46 /dev/tty52 /dev/tty59 /dev/tty8
/dev/tty0 /dev/tty15 /dev/tty21 /dev/tty28 /dev/tty34 /dev/tty40 /dev/tty47 /dev/tty53 /dev/tty6 /dev/tty9
/dev/tty1 /dev/tty16 /dev/tty22 /dev/tty29 /dev/tty35 /dev/tty41 /dev/tty48 /dev/tty54 /dev/tty60 /dev/ttyACM0
/dev/tty10 /dev/tty17 /dev/tty23 /dev/tty3 /dev/tty36 /dev/tty42 /dev/tty49 /dev/tty55 /dev/tty61 /dev/ttyprintk
/dev/tty11 /dev/tty18 /dev/tty24 /dev/tty30 /dev/tty37 /dev/tty43 /dev/tty5 /dev/tty56 /dev/tty62 /dev/ttyS0
/dev/tty12 /dev/tty19 /dev/tty25 /dev/tty31 /dev/tty38 /dev/tty44 /dev/tty50 /dev/tty57 /dev/tty63
/dev/tty13 /dev/tty2 /dev/tty26 /dev/tty32 /dev/tty39 /dev/tty45 /dev/tty51 /dev/tty58 /dev/tty7
/dev/ttyACM0 is found !
Verify GPS Functionality
cgps -s
Key Observations
The SNR values are all 0.0, indicating that the GPS is not receiving signals from satellites.
Status: NO FIX:
The line Status: NO FIX (6 secs) indicates that the GPS is unable to determine its position. This is a critical issue, as a valid time fix is necessary for NTP synchronization.
Latitude and Longitude:
Both Latitude and Longitude are shown as n/a, further confirming that the GPS has not acquired a position.
SNR (Signal-to-Noise Ratio):
The SNR values are all 0.0, indicating that the GPS is not receiving signals from satellites.
Obviously, the GPS receiver cannot receive any signals from satellites. So I place the GPS antenna directly outside the window. Sometimes, it may take several minutes for the GPS to acquire a fix, especially if it has just been powered on or moved to a new location. I use the “cgps -s” command again after few minutes and the result is positive. I got a 3D FIX !!! The LED on the GPS receiver will blink every second when it successfully receives information from the satellites.
(4) Configure NTP
Open the NTP configuration file:
sudo nano /etc/ntpsec/ntp.conf
Remark some items and add new items. Final items without remark are shown below.
#Drift and Leap Files for accurate timekeeping
driftfile /var/lib/ntpsec/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list
tos maxclock 11
#specify GPS as the only time server
server 127.127.28.0 minpoll 4 maxpoll 4
fudge 127.127.28.0 stratum 1
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1
Explanation of GPS time server configuration lines:
server 127.127.28.0 minpoll 4 maxpoll 4 prefer
:server 127.127.28.0
: This specifies the local GPS as the NTP server using the shared memory interface.minpoll 4
: This sets the minimum polling interval for the NTP server to 16 seconds (2^4 seconds).maxpoll 4
: This sets the maximum polling interval to also 16 seconds.prefer
: This indicates that this server should be preferred over others if there are multiple servers configured. It tells NTP to use this server as the primary source of time.
fudge 127.127.28.0 stratum 1
:fudge 127.127.28.0
: This command allows you to modify the behavior of the specified server.stratum 1
: This sets the stratum level of the GPS time source to 1. In NTP, stratum levels indicate the distance from the reference clock (with 1 being the highest quality). Since GPS is considered a very accurate source, it is often set to stratum 1.
In summary, this configuration line tells your NTP server to use the GPS (via 127.127.28.0
) as a preferred time source with a polling interval of 16 seconds, and it designates the GPS as a high-quality time source by assigning it a stratum level of 1. This setup is commonly used for accurate timekeeping in systems that rely on GPS.
Restart NTP Service
sudo systemctl restart ntp
Verify GPS and NTP Functionality
- Check GPS Status:
Run the following command to check if the GPS is receiving signals:
gpsmon
- Check NTP Status:
Verify that the NTP server is synchronized with the GPS:
ntpq -p
Return message:
remote refid st t when poll reach delay offset jitter
=======================================================================================================
*SHM(0) .SHM. 1 l 3 16 377 0.0000 0.8508 2.6636
Breakdown of the Output
remote
:*SHM(0)
: The asterisk (*
) indicates that this is the currently selected time source for synchronization.SHM(0)
refers to the shared memory interface being used to get time data from the GPS.
refid
:.SHM.
: This shows that the reference ID is from the shared memory. It confirms that the GPS is providing the time.
st
(Stratum):1
: This indicates that the GPS is a stratum 1 source, meaning it is directly connected to a reference clock (the GPS).
t
(Type):l
: The letterl
indicates that the source is local (a local clock), which in this case is the GPS.
when
:3
: This indicates that the last time the NTP daemon received a valid time update from the GPS was 3 seconds ago.
poll
:16
: This shows the polling interval (in seconds) for the NTP server to query the GPS for updated time. A value of16
corresponds to a polling interval of 2^4 seconds (16 seconds).
reach
:377
: This is an octal representation of the reachability status of the NTP server. A value of377
(which is111111111
in binary) indicates that the server has successfully responded to all recent queries.
delay
:0.0000
: This represents the round-trip delay to the time source in milliseconds. A value of0.0000
indicates that the GPS is responding immediately, which is typical for local sources.
offset
:0.8508
: This is the offset in milliseconds between the local clock and the GPS time source. An offset of0.8508
means the local clock is about 0.85 milliseconds ahead of the GPS time.
jitter
:2.6636
: This represents the variability in the time measurements, indicating the stability of the time source. A jitter of2.6636
milliseconds suggests some fluctuation in the time readings, but it’s within an acceptable range for GPS.
In summary, the NTP server is successfully synchronized with the GPS. It is using the GPS as a local time source, polling it every 16 seconds. The reachability is perfect, and the offset indicates that your local clock is very close to the GPS time. The jitter value suggests that while there is some variability, it is not significant enough to impact synchronization. Everything appears to be functioning correctly!
In case of failure, you can look at the NTP logs to identify any issues
sudo journalctl -u ntpsec
Or make sure the gpsd
service is started and configured correctly. Check its status:
sudo systemctl status gpsd
(5) Set Up Clients
- Other devices on your local network can now point to the Raspberry Pi’s IP address as their NTP server.
Next jobs:
Create web interface for user to change username/password and show the GPS status. Several LEDs will be added to indicate if GPS receiver receives satellite signal and the quantity of satellites it can detected. As hardware of Pi is touched, Python language will be used. Node JS and Ajax will be used for web interface development.