What is a time server? A time server gets its time from a reference time source. That source can be a another time server, a local time source such as a rubidium or cesium atomic clock. In this post I make an USB GPS receiver for a Linux time server using cheap available components. After assembling the GPS module I give instructions on how to configure the Linux NTP daemon to use this module. The GPS receiver gets its time signal from the GPS satellite network. Its longtime time drift is about 0 seconds. This is possible because the GPS time signals are constantly adjusted to keep very accurate time needed for navigation.
This is not a project for a beginner. I will generally describe what you need and assume you have a usable set electronics skill. Now let get all the important stuff you need:
A GPS receiver with an one pulse per second output. I used a Fastrax UP501 that is available on eBay (http://stores.ebay.com/reyax). The UP501 GPS module has a MediaTek MT3329 chipset which for the purpose of a time server comes with a +-50 nanosecond precision 1PPS output. Mine is a UP501B subtype. It has a backup battery connector for time keeping while no power is available.
Get a FT232RL USB to Serial Module, you need this to convert the TTL serial signal from the GPS module to feed it in your time server. Choose a module which breaks out the DCD input and the 3.3V output. The DCD pin on the FT232RL will be fed the 1PPS signal. Most cheap modules only breakout the TXD and RXD signals. Mine is a breakout board made by HEX. (search eBay on: “FT232RL USB to Serial Module USB to TTL”)
You also need a prototype pcb to mount all the parts. I used one which measures about 5x7cm. Get yourself a nice project box to put the pcb in. I used a grey project box with dimension 120x100x45mm.
Besides these components you will also need some tools like a soldering iron, screwdriver and drills. But I guess you already have them.
In this rough schematic you can see the FT232RL module on the left, the GPS connector and the support circuitry.
When soldering all components on the pcb, you should connect all common signals together. For example, the 3.3V output of the FT232RL module should be connected to the 3.3V connection of the GPS, the VCC connection of the decoupling capacitor (C1) and the VCC connection for the LED. Same with all the GND connections.
Capacitor C2 will be charged when power is applied and will provide the GPS module with some power to keep track of time when the USB connection is temporary disconnected. If you quickly reconnect USB then you will notice that the GPS module instantly locks onto the GPS time siganl.
The LED flashes with every 1 pulse per second. I used a blue LED. The LED also is handy for indication that a GPS signal is present when giving the GPS receiver a permanent place next to your time server. The UP501 gps module is very sensitive and worked about 2 meters away from a door which has no direct line of sight to the sky.
Note that the antenna of the GPS module is the ceramic part and not the metal shielding. Keep in mind the orientation in such a way that the antenna can be pointed to the sky.
After soldering you will magically have a working GPS receiver:
I use a windows workstation to test the GPS module. After connecting USB the RXD led of the FT232RL module should start flashing. After a while the blue 1PPS led will also start flashing indicating a GPS lock. Start your favorite serial terminal (I used Putty) and configure it for 9600 8N1. You should see something like this:
These are NMEA sentences and are outputted once per second. This module outputs the GPGGA, GPGSA, GPGSV and GPRMC sentences.
You now can use the module in your time server, but you can also reconfigure the defaults to output more GPS sentences and use a faster baudrate.
Search the net for “MiniGPS_1.4.exe”. This program can change the default settings of your gps module. Start the program and connect to your GPS on the correct serial port with the baudrate 9600:
Go to the setup tab and press the “Query” button just below “MCHN”. That will get the GPS sentences that will be outputted. Mine came with GSA, RMC, GSV and GGA set:
Now you can reconfigure the default baudrate and other settings. I chose only to reconfigure the baudrate. Select 115200 and press “set”. Now go to the “Test” tab and press the “Set” button in the “Write settings into flash” groupbox. You can change the default only 8 times. After that you cannot change the defaults with Mini GPS. I believe you can do a global erase and reprogram the firmware, but I never found out how. Just keep in mind, change only once and you have 7 tries left:
Your GPS receiver is now configured to be used in a time server. Mount the PCB in the project box. I used hot glue. Scratch the surface where the hot glue will be used for a better adhesion. You will need to drill a big enough hole for the USB connector and a small hole for the LED. I chose to mount the LED on the side of the project box. The project box will be put on its side so the GPS receiver antenna is somewhat at an angle. At the same time, the LED will now be on top:
Give the GPS module a permanent location and connect is to one of the USB ports of your Linux server. If your backup capacitor (C2) was large enough and the GPS receiver has a good enough view of the sky it will instantly lock onto the GPS signal and start flashing the blue 1PPS led.
I use Linux Centos 6 x64. If you use another Linux distribution the commands will be somewhat different.
After you plugged in the receiver you should see this in `dmesg`:
usb 3-1: new full-speed USB device number 25 using xhci_hcd ftdi_sio 3-1:1.0: FTDI USB Serial Device converter detected usb 3-1: Detected FT232RL usb 3-1: Number of endpoints 2 usb 3-1: Endpoint 1 MaxPacketSize 64 usb 3-1: Endpoint 2 MaxPacketSize 64 usb 3-1: Setting MaxPacketSize 64 usb 3-1: FTDI USB Serial Device converter now attached to ttyUSB2
The FT232 chip is attached to ttyUSB2. I have multiple USB serial devices and chose to let udev setup symlinks for me. Udev symlinks the GPS receiver to /dev/ttyUSB.gps
To do the same for your receiver make a new file /etc/udev/rules.d/99-usb-serial.rules and put this in it:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A9VXFO2K", SYMLINK+="ttyUSB.gps"
Obviously you should change the idVendor, idProducti and servial values. Use “lsusb -v” for that. Install “yum -y install usbutils” if you do not have lsusb.
Run it, `lsusb -v` and search for “FTDI” in the output, you can now find the serial number of your USB serial converter:
Bus 003 Device 025: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0403 Future Technology Devices International, Ltd idProduct 0x6001 FT232 USB-Serial (UART) IC bcdDevice 6.00 iManufacturer 1 FTDI iProduct 2 GPS iSerial 3 A9VXFO2K
Udev should automatically pick up the new configuration. Unplug and replug your USB gps receiver and it should have created a symlink for you:
ls -al /dev/ttyUSB.gps lrwxrwxrwx 1 root root 7 Apr 28 19:09 /dev/ttyUSB.gps -> ttyUSB2
Install all needed software: `yum install ntp gpsd`. You may find that gpsd is missing. I compiled it myself into a RPM you can download (and install):
gpsd-3.4-1.el6.x86_64.rpm
gpsd-clients-3.4-1.el6.x86_64.rpm
gpsd-libs-3.4-1.el6.x86_64.rpm
gpsd-devel-3.4-1.el6.x86_64.rpm
gpsd-3.4-1.el6.src.rpm
You can skip the devel and src.rpm. You need them only when developing packages for gpsd. Or when you have x32 Centos you can use the src.rpm to compile gpsd.
Edit /etc/sysconfig/gpsd, change contents to:
DAEMON_OPTS="-n -G" DEVICE="/dev/ttyUSB.gps" BAUDRATE="115200" USBAUTO="false"
Start gpsd: `service gpsd start`
Run dmesg and you should see this:
pps pps0: new PPS source usbserial2 pps pps0: source "/dev/ttyUSB2" added
Edit /etc/ntp.conf and add:
# Read the rough GPS time from device 127.127.28.0 # Read the accurate PPS time from device 127.127.28.1 server 127.127.28.0 minpoll 6 maxpoll 6 fudge 127.127.28.0 time1 0.286 refid GPS server 127.127.28.1 minpoll 4 maxpoll 4 prefer fudge 127.127.28.1 refid PPS
Restart ntpd. The ip addresses are not real. It only instructs ntpd to read PPS and GPS data from the GPS daemon. You do not have to configure anything else in ntp but the “time1” parameter. Here it is 0.286. That is an offset from which the GPS date is received and what is claimed to be the time in the GPS data. It can be determined with `ntpq -p` after running your new time server for a while.
Run `ntpq -p`:
remote refid st t when poll reach delay offset jitter ============================================================================== +SHM(0) .GPS. 0 l 15 64 377 0.000 1.290 28.903 *SHM(1) .PPS. 0 l 13 16 377 0.000 0.050 0.036 2001:980:1401:: .INIT. 16 u - 1024 0 0.000 0.000 0.000 -IPv6.remco.org 255.254.181.36 2 u 9 64 377 26.342 1.640 0.442 +ntp1.nl.uu.net .PPS. 1 u 5 64 377 12.925 5.137 1.123
The first to servers are your GPS date and the GPS 1PPS signals. The “reach” column indicates that it works. Also, the “+” and “*” are a good sign. “*” is assigned to the master time provider. Servers with “+” are good backup servers. Servers with “-” not so good. Sometimes the GPS data is worthless and a “X” will appear. That server is excluded from the equation to calculate the current time.
Congratulation! You now have a working stratum 1 time server.
Now what to do next? You can build a somewhat over the top wall clock as I did. Or you can graph the performance of your time server: