NTP-Server with Raspberry Pi and Sure Electronics GPS Eval board: Unterschied zwischen den Versionen
Dl8rds (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „== Scope == It was already a few years ago when I bought a Sure Electronics GPS timing receiver. Though, there was never enough time to complete and deploy it…“) |
Dl8rds (Diskussion | Beiträge) (→Implementation) |
||
(34 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
== Scope == | == Scope == | ||
− | It was already a few years ago when I bought a Sure Electronics GPS timing receiver. Though, there was never enough time to complete and deploy it. I | + | It was already a few years ago when I bought a Sure Electronics GPS timing receiver. Though, there was never enough time to complete and deploy it. I have done it now. |
+ | |||
+ | The Sure receiver is nice because it has 3,3V IO pins, and this matches perfectly with a Raspberry Pi. So it's a good point using it. | ||
+ | |||
+ | Obviously many people have problems with the NTPD that comes with the recent raspian distributions: ntp 4.2.6p5. It does not support PPS... | ||
+ | |||
+ | It is rather easy to make the kernel PPS aware, but ntp still is not capable of using it. I needed to recompile the ntp package so that I was able to use it. The symptom therefore is: | ||
+ | |||
+ | * The tool '''ppstest''' does report the reception of a pulse, but even if you configure NTP correctly, it won't give you an output with PPS using the command '''ntpq -p'''. | ||
+ | |||
+ | * Please note that I am reading the PPS through GPIO Pin 18 and the regular NMEA sentence comes via the serial port. I am not using the onboard UART, but I rather connect the /dev/ttyUSB0. | ||
+ | |||
+ | Note that there is a successor project which is closely related: [[NTP-Server with Raspberry Pi and Trimble Resolution SMT]] | ||
== References == | == References == | ||
+ | * http://www.satsignal.eu/ntp/Sure-GPS.htm Here the board is described very well | ||
* http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html | * http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html | ||
* https://store.uputronics.com/index.php?route=product/product&path=60_64&product_id=81 | * https://store.uputronics.com/index.php?route=product/product&path=60_64&product_id=81 | ||
* http://rdlazaro.info/compu-Raspberry_Pi-RPi-stratum0.html | * http://rdlazaro.info/compu-Raspberry_Pi-RPi-stratum0.html | ||
* http://mythopoeic.org/pi-ntp/ | * http://mythopoeic.org/pi-ntp/ | ||
+ | * https://raspberry.tips/raspberrypi-tutorials/raspberry-pi-uhrzeit-ueber-gps-beziehen-zeitserver/ | ||
+ | |||
+ | == Implementation == | ||
+ | |||
+ | === OS Installation and Preparation === | ||
+ | |||
+ | First of all I decided to use a minibian image: | ||
+ | |||
+ | https://sourceforge.net/projects/minibian/files/2016-03-12-jessie-minibian.tar.gz | ||
+ | |||
+ | because I don't want to create a really big thing. I just want to have an NTP server. | ||
+ | |||
+ | * Unpack, write it to the SD card, as described so often everywhere on almost every RPI page. | ||
+ | * Use '''gparted''' to resize the root partition to the rest of your SD card. We should not waste space. | ||
+ | * Log in using uid root pwd raspberry (default). Note that opposed to Raspian, there is no user "pi". | ||
+ | * '''apt-get update; apt-get upgrade''' and update the minibian image. | ||
+ | * Give it a nice hostname, editing the file '''/etc/hostname''' and reboot. | ||
+ | * Edit '''/boot/config.txt''' - Add '''dtoverlay=pps-gpio,gpiopin=18''' on a new line. - Connect the PPS signal of the Sure board to this pin. Don't get the pin wrong :-) | ||
+ | |||
+ | [[Image:Raspi1BPlusHeaders.jpg]] | ||
+ | |||
+ | * I also added another line to the '''boot'config.txt''' file: '''dtparam=i2c_arm=on''' because I have included an I2C sensor that gives me some more values. | ||
+ | Here is why: http://stackoverflow.com/questions/32021924/raspberry-pi-2-cannot-enable-dev-i2c-0 | ||
+ | * Save the file... | ||
+ | * Edit the file '''/etc/modules''' to contain the following lines. Just paste them below what is there already: | ||
+ | i2c-bcm2708 | ||
+ | i2c_dev | ||
+ | pps-gpio | ||
+ | : so to ensure that these modules will be loaded. | ||
+ | * Install the pps-tools: | ||
+ | apt-get install pps-tools | ||
+ | |||
+ | If you are using a BMP085 or a BMP180 sensor to grab some data as I do, then do this: | ||
+ | |||
+ | * Install the according i2c devices: | ||
+ | apt-get update | ||
+ | apt-get install i2c-tools # I2C-Toolkit for commandline | ||
+ | apt-get install python-smbus # Python library for I2C | ||
+ | apt-get install libi2c-dev # library for C | ||
+ | apt-get install git # need this later... | ||
+ | : Note here (German): http://www.netzmafia.de/skripten/hardware/RasPi/RasPi_I2C.html | ||
+ | |||
+ | * Note that the I2C devices will not becreated just like that, but that you need to create them manually: | ||
+ | |||
+ | mknod /dev/i2c-0 c 89 0 | ||
+ | mknod /dev/i2c-1 c 89 1 | ||
+ | |||
+ | * Configure the timezone using the command '''dpkg-reconfigure tzdata''' | ||
+ | * Create a symlink from '''/dev/ttyUSB0''' to '''/dev/gps0''' because the latter is the device the NTP driver will be looking for: | ||
+ | lrwxrwxrwx 1 root root 7 Apr 10 23:47 /dev/gps0 -> ttyUSB0 | ||
+ | |||
+ | Alternatively it makes sense to create a udev rule file: | ||
+ | vi /etc/udev/rules.d/09.pps.rules | ||
+ | and add: | ||
+ | KERNEL=="ttyACM0", SYMLINK+="gps0" | ||
+ | KERNEL=="pps0", OWNER="root", GROUP="tty", MODE="0660", SYMLINK+="gpspps0" | ||
+ | which will create the devices | ||
+ | /dev/ttygps0 | ||
+ | /dev/gpspps0 | ||
+ | |||
+ | Now reboot. A device will be created during system startup: '''/dev/pps0''' Check for it to be created. Another device will be created for the I2C stuff, see below. | ||
+ | |||
+ | If you connected the PPS, the following command will produce results like here: | ||
+ | root@ntp1:/etc# ppstest /dev/pps0 | ||
+ | trying PPS source "/dev/pps0" | ||
+ | found PPS source "/dev/pps0" | ||
+ | ok, found 1 source(s), now start fetching data... | ||
+ | source 0 - assert 1460368282.999995290, sequence: 43451 - clear 0.000000000, sequence: 0 | ||
+ | source 0 - assert 1460368284.000007548, sequence: 43452 - clear 0.000000000, sequence: 0 | ||
+ | source 0 - assert 1460368284.999994807, sequence: 43453 - clear 0.000000000, sequence: 0 | ||
+ | source 0 - assert 1460368285.999995063, sequence: 43454 - clear 0.000000000, sequence: 0 | ||
+ | If you get one of these lines every second, this means that your kernel is now disciplined by a PPS. It reacts to the pulse coming in, it recognizes the pulse properly. Congratulations! | ||
+ | |||
+ | Now let's check for the I2C stuff: The device '''/dev/i2c-1''' should have been created. If you also use the BMP sensor, you should find it as '77'. Once you got the sensor connected as described in the manuals, detect it: | ||
+ | |||
+ | i2cdetect -y 1 | ||
+ | |||
+ | and it should show up as "77": | ||
+ | |||
+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f | ||
+ | 00: -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- | ||
+ | 70: -- -- -- -- -- -- -- 77 | ||
+ | |||
+ | Great! | ||
+ | |||
+ | Then you can proceed to download Lady Ada's code examples: | ||
+ | |||
+ | git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git | ||
+ | |||
+ | and then try it out: | ||
+ | |||
+ | cd Adafruit-Raspberry-Pi-Python-Code/Adafruit_BMP085 | ||
+ | ./Adafruit_BMP085_example.py | ||
+ | |||
+ | Temperature: 25.29 C | ||
+ | Pressure: 974.22 hPa | ||
+ | Altitude: 530 | ||
+ | |||
+ | Now let's go back for the NTP application. | ||
+ | |||
+ | Note: The structure of the Adafruit repositories has changed recently. Now you can clone exclusively the BMP libraries with this command: | ||
+ | |||
+ | git clone https://github.com/adafruit/Adafruit_Python_BMP | ||
+ | |||
+ | But let me remark that I am having problems with this recent development. Well, it's probably not so complicated but I have not hafd the time to find out how it works. | ||
+ | |||
+ | === NTP configuration === | ||
+ | |||
+ | The default NTP package is not sufficient, as I wrote above. It does not support reading the PPS from the kernel. It is quite disappointing if you did everything right and you're still not successful. | ||
+ | |||
+ | Though I recommend installing it first because we can prepare it nevertheless, using the command '''apt-get install ntp''' | ||
+ | |||
+ | Then edit the config file '''/etc/ntp.conf''' and make it look like this. Maybe it's agood idea to copy it to another filename and to have a reference: '''cp /etc/ntp.conf /etc/ntp.conf_orig'''. Now edit the '''/etc/ntp.conf''': | ||
+ | |||
+ | <pre> | ||
+ | # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help | ||
+ | |||
+ | driftfile /var/lib/ntp/ntp.drift | ||
+ | |||
+ | # Enable this if you want statistics to be logged. | ||
+ | statsdir /var/log/ntpstats/ | ||
+ | |||
+ | statistics loopstats peerstats clockstats | ||
+ | filegen loopstats file loopstats type day enable | ||
+ | filegen peerstats file peerstats type day enable | ||
+ | filegen clockstats file clockstats type day enable | ||
+ | filegen sysstats file sysstats type day link enable | ||
+ | |||
+ | tos minsane 3 | ||
+ | tos orphan 10 | ||
+ | tos mindist 0.4 | ||
+ | |||
+ | server 127.127.22.0 minpoll 4 prefer | ||
+ | fudge 127.127.22.0 refid PPS flag2 0 flag3 1 | ||
+ | |||
+ | server 127.127.20.0 minpoll 4 mode 18 prefer # NMEA serial port, 16 = 9600 baud, 2 = $GPGGA | ||
+ | fudge 127.127.20.0 time2 0.439 flag1 0 refid GPS stratum 1 flag3 1 | ||
+ | |||
+ | #server 127.127.1.0 | ||
+ | #fudge 127.127.1.0 stratum 10 | ||
+ | |||
+ | #server 127.127.28.0 minpoll 4 maxpoll 4 | ||
+ | #fudge 127.127.28.0 time1 0.000 refid SHM stratum 1 | ||
+ | |||
+ | pool de.pool.ntp.org minpoll 10 iburst | ||
+ | server db0fhn.ampr.org minpoll 4 iburst | ||
+ | server ntp1.ptb.de minpoll 4 iburst | ||
+ | |||
+ | |||
+ | # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for | ||
+ | # details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions> | ||
+ | # might also be helpful. | ||
+ | # | ||
+ | # Note that "restrict" applies to both servers and clients, so a configuration | ||
+ | # that might be intended to block requests from certain clients could also end | ||
+ | # up blocking replies from your own upstream servers. | ||
− | + | # By default, exchange time with everybody, but don't allow configuration. | |
+ | restrict -4 default kod notrap nomodify nopeer noquery | ||
+ | restrict -6 default kod notrap nomodify nopeer noquery | ||
− | + | restrict 172.16.0.0 mask 255.240.0.0 | |
+ | restrict 192.168.0.0 mask 255.255.0.0 | ||
− | + | # Local users may interrogate the ntp server more closely. | |
− | + | restrict 127.0.0.1 | |
− | + | restrict ::1 | |
− | |||
− | === Images | + | broadcast 192.168.1.255 |
+ | </pre> | ||
+ | |||
+ | Since NTP is frequently writing to the SD card, I did a trick. The creation of the mount point '''/var/log/ntpstats''' will be done during package installation. | ||
+ | * Stop the daemon with '''service ntp stop''' | ||
+ | * Now delete the contents of this directory: '''rm /var/log/ntpstats/*''' | ||
+ | * Now add the following line to the file '''/etc/fstab''' and create a RAM disk | ||
+ | tmpfs /var/log/ntpstats tmpfs nodev,nosuid,size=10M 0 0 | ||
+ | : It will cost 10 of your 512 MB RAM, but you didn't plan a high performance compute cluster anyway :-) If you want, you can easily add more. Occasional reboots will keep it empty anyway. | ||
+ | : Note that the process ntpd just consumes about 5 MBytes... So 512 is almost a waste of RAM. :-) | ||
+ | * Reboot. | ||
+ | |||
+ | Now let's check a couple of things: | ||
+ | * '''mount''' will show something like this: | ||
+ | tmpfs on /var/log/ntpstats type tmpfs (rw,nosuid,nodev,relatime,size=10240k) | ||
+ | * '''ntpq -p''' will show something like this: | ||
+ | root@ntp1:/etc# ntpq -p | ||
+ | remote refid st t when poll reach delay offset jitter | ||
+ | ============================================================================== | ||
+ | *GPS_NMEA(0) .GPS. 1 l 7 16 377 0.000 1.300 11.017 | ||
+ | -test.danzuck.ch 162.23.41.56 2 u 712 1024 377 20.054 -0.302 1.833 | ||
+ | +stratum2-3.NTP. 129.70.130.70 2 u 288 1024 377 31.598 2.897 0.542 | ||
+ | +static.5-9-80-1 213.239.239.165 3 u 448 1024 377 21.270 1.829 0.854 | ||
+ | -ns2.bvc-cloud.d 109.75.188.245 3 u 212 1024 377 23.095 0.746 0.502 | ||
+ | : Note that there is probably no line containing anything about PPS. | ||
+ | : Though this output already tells us that our NTP server is keeping a more or less precise time. Good enough for your alarm clock in the morning for sure :-) | ||
+ | |||
+ | * Now let's add PPS support. Here is a good reference page: https://raspberry.tips/raspberrypi-tutorials/raspberry-pi-uhrzeit-ueber-gps-beziehen-zeitserver/ | ||
+ | |||
+ | * Since the recent minibian is based on jessie rather than on wheezy: | ||
+ | |||
+ | sh -c 'echo "deb-src http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi" >> /etc/apt/sources.list' | ||
+ | apt-get update | ||
+ | * Get the build dependencies and the source code of the package: | ||
+ | cd ~ | ||
+ | apt-get -y build-dep ntp | ||
+ | apt-get -y source ntp | ||
+ | * The source code was stored in my home directory. In the moment and for me it is the version '''ntp-4.2.6.p5+dfsg'''. Note that it could be different for you. | ||
+ | cd ntp-4.2.6.p5+dfsg/debian/ | ||
+ | * Edit the '''rules''' file and add the missing support for PPS/ATOM. Search for '''configure''' and append a line at the end of the statement. Don't forget the '''\''' at the end of the previous line. | ||
+ | ./configure CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' \ | ||
+ | --prefix=/usr \ | ||
+ | --enable-all-clocks --enable-parse-clocks --enable-SHM \ | ||
+ | --disable-debugging --sysconfdir=/var/lib/ntp \ | ||
+ | --with-sntp=no \ | ||
+ | --with-lineeditlibs=edit \ | ||
+ | --without-ntpsnmpd \ | ||
+ | --disable-local-libopts \ | ||
+ | --enable-ntp-signd \ | ||
+ | --disable-dependency-tracking \ | ||
+ | --with-openssl-libdir=/usr/lib/$(DEB_HOST_MULTIARCH) \ | ||
+ | --enable-ATOM | ||
+ | * Now add the '''changelog''' file so that it reflects the change: | ||
+ | ntp (1:4.2.6.p5+dfsg-7+deb8u1) jessie-security; urgency=medium | ||
+ | : into: | ||
+ | ntp (1:4.2.6.p5+dfsg-8+deb8u1) jessie-security; urgency=medium | ||
+ | * Now 'cd' into the package directory and build the package. | ||
+ | cd .. | ||
+ | sudo dpkg-buildpackage -b | ||
+ | : It will take a while now. In my case three deb files were created: | ||
+ | 344 -rw-r--r-- 1 root root 350362 Apr 11 02:11 ntp_4.2.6.p5+dfsg-8+deb8u1_armhf.deb | ||
+ | 68 -rw-r--r-- 1 root root 68882 Apr 11 02:11 ntpdate_4.2.6.p5+dfsg-8+deb8u1_armhf.deb | ||
+ | 1008 -rw-r--r-- 1 root root 1030588 Apr 11 02:09 ntp-doc_4.2.6.p5+dfsg-8+deb8u1_all.deb | ||
+ | * Now install them: | ||
+ | cd .. | ||
+ | dpkg -i ntp_4.2.6.p5+dfsg-8+deb8u1_armhf.deb | ||
+ | dpkg -i ntpdate_4.2.6.p5+dfsg-8+deb8u1_armhf.deb | ||
+ | dpkg -i ntp-doc_4.2.6.p5+dfsg-8+deb8u1_all.deb | ||
+ | * Now restart the ntp server with the command '''service ntp restart''' and after ~ 1 minute it should give you this output using '''ntpq -p''': | ||
+ | root@ntp1:~# ntpq -p | ||
+ | remote refid st t when poll reach delay offset jitter | ||
+ | ============================================================================== | ||
+ | oPPS(0) .PPS. 0 l 16 16 377 0.000 -0.090 0.007 | ||
+ | *GPS_NMEA(0) .GPS. 1 l 15 16 377 0.000 -4.357 5.950 | ||
+ | -static.249.171. 194.225.150.25 3 u 163 1024 3 20.506 -1.796 1.607 | ||
+ | +tschil.ethgen.c 131.188.3.222 2 u 175 1024 3 20.443 -0.381 0.988 | ||
+ | +malbolge.de 131.188.3.221 2 u 169 1024 3 20.930 -0.417 0.933 | ||
+ | -ghost-networks. 130.149.17.8 2 u 204 1024 3 22.189 0.102 0.769 | ||
+ | * The 'o' at the beginning of the line says that PPS is being used. | ||
+ | * Please also check the output of '''ntptime''': | ||
+ | root@ntp1:~# ntptime | ||
+ | ntp_gettime() returns code 0 (OK) | ||
+ | time dab60019.f0feffcc Mon, Apr 11 2016 12:51:05.941, (.941391075), | ||
+ | maximum error 4827 us, estimated error 0 us, TAI offset 0 | ||
+ | ntp_adjtime() returns code 0 (OK) | ||
+ | modes 0x0 (), | ||
+ | offset -76.297 us, frequency -37.570 ppm, interval 1 s, | ||
+ | maximum error 4827 us, estimated error 0 us, | ||
+ | status 0x2007 (PLL,PPSFREQ,PPSTIME,NANO), | ||
+ | time constant 4, precision 0.001 us, tolerance 500 ppm, | ||
+ | : If you want to know how to interpret it, consider this (rather old) posting: https://groups.google.com/forum/#!topic/comp.protocols.time.ntp/FDAIxL3V-k4 | ||
+ | |||
+ | Congratulations! | ||
+ | |||
+ | === System considerations concerning DHCP === | ||
+ | |||
+ | In case you retrieve your IP configuration via DHCP, there is a default statement to also retrieve the according NTP server config: You will want to exclude that! | ||
+ | |||
+ | Edit the file '''/etc/dhcp/dhclient.conf''' and remove the string '''ntp-servers''' from the line behind the ''request'' keyword. | ||
+ | |||
+ | Then remove the file '''/var/lib/ntp/ntp.conf.dhcp'''. | ||
+ | |||
+ | == Results == | ||
+ | |||
+ | === Processing Automation === | ||
+ | |||
+ | Here are the contents for the /etc/crontab file: | ||
+ | |||
+ | */10 * * * * root /var/www/bin/createstats.sh 2>&1 > /dev/null | ||
+ | */10 * * * * root /usr/local/bin/prep_charts.gpl 2>&1 > /dev/null | ||
+ | */10 * * * * root /usr/local/bin/prep_env.gpl 2>&1 > /dev/null | ||
+ | * * * * * root cat /var/www/html/ntpq_c_rl_notes > /var/www/html/graphs/ntpq-c_rl.txt; ntpq -c rl >> /var/www/html/graphs/ntpq-c_rl.txt | ||
+ | * * * * * root ntptime -N > /var/www/html/graphs/ntptime.txt | ||
+ | * * * * * root ntpq -p > /var/www/html/graphs/ntpq-p.txt; cat /var/www/html/ntpq-p-notes.txt >> /var/www/html/graphs/ntpq-p.txt | ||
+ | * * * * * root /usr/local/bin/env_data.sh 2>&1 > /dev/null | ||
+ | |||
+ | Note that I am adding some legend to the ntpq -p output: /var/www/html/graphs/ntpq-p.txt | ||
+ | |||
+ | -------------------------------------------------------------------------------------------------------------- | ||
+ | * the source you are synchronized to (syspeer) | ||
+ | # source selected, distance exceeds maximum value | ||
+ | o the PPS(Pulse Per Second) source if your ntpd (ppspeer, only if you have a PPS capable system and refclock) | ||
+ | + candidate, i.e. it is considered a good source | ||
+ | - outlyer, i.e. quality is not good enough | ||
+ | x falseticker, i.e. this one is considered to distribute bad time | ||
+ | blank: source discarded, failed sanity | ||
+ | |||
+ | I am also adding some notes to the 'ntpq -c rl' output: /var/www/html/ntpq-p-notes.txt | ||
+ | |||
+ | Notes: 'ntpq -c rl' output parameters: | ||
+ | |||
+ | precision - is rounded to give the next larger integer power of two. The achieved resolution is thus 2precision (seconds) | ||
+ | rootdelay - total roundtrip delay to the primary reference source at the root of the synchronization subnet. Note that this variable can take on both positive and negative values, depending on clock precision and skew (seconds) | ||
+ | rootdisp - maximum error relative to the primary reference source at the root of the synchronization subnet (seconds) | ||
+ | tc - NTP algorithm PLL (phase locked loop) or FLL (frequency locked loop) time constant (log2) | ||
+ | mintc - NTP algorithm PLL/FLL minimum time constant or 'fastest response' (log2) | ||
+ | offset - best and final offset determined by the combine algorithm used to discipline the system clock (ms) | ||
+ | frequency - system clock period (log2 seconds) | ||
+ | sys_jitter - best and final jitter determined by the combine algorithm used to discipline the system clock (ms) | ||
+ | clk_jitter - host hardware(?) system clock jitter (ms) | ||
+ | clk_wander - host hardware(?) system clock wander (PPM - parts per million) | ||
+ | |||
+ | === Data Processing === | ||
+ | |||
+ | Here is how we collect environmental data. Please note that the stats of the NTP daemon are produced anyway. | ||
+ | |||
+ | <pre> | ||
+ | root@ntp1:/usr/local/bin# cat /usr/local/bin/env_data.sh | ||
+ | #!/bin/bash | ||
+ | |||
+ | DATAFILE="/var/log/envdata/envdata.log" | ||
+ | YESTERDAY="/var/log/envdata/yesterdaydata.log" | ||
+ | TODAY="/var/log/envdata/todaydata.log" | ||
+ | |||
+ | tail -3000 $DATAFILE \ | ||
+ | | grep $(date -d yesterday +"%Y-%m-%d") \ | ||
+ | > $YESTERDAY | ||
+ | |||
+ | tail -30000 $DATAFILE \ | ||
+ | | grep $(date +%F) \ | ||
+ | > $TODAY | ||
+ | |||
+ | # Ueberlauf verhindern | ||
+ | cat $YESTERDAY > $DATAFILE | ||
+ | cat $TODAY >> $DATAFILE | ||
+ | |||
+ | COMMAND=/usr/local/bin/get_env_data.py | ||
+ | |||
+ | MESSZEITPUNKT=$(date '+%F %T') | ||
+ | MESSUNG=$($COMMAND) | ||
+ | |||
+ | OUTLINE="$MESSZEITPUNKT $MESSUNG" | ||
+ | |||
+ | echo $OUTLINE >> $DATAFILE | ||
+ | </pre> | ||
+ | |||
+ | === GNUPlot === | ||
+ | |||
+ | This is the script which evaluates round trip times and offset for the general voerview: | ||
+ | |||
+ | <pre> | ||
+ | #! /usr/bin/gnuplot | ||
+ | # Remember to check you have these lines in /etc/ntp.conf and that ntpd is actually running: | ||
+ | # statsdir /var/log/ntpstats/ | ||
+ | # statistics loopstats peerstats clockstats | ||
+ | # filegen loopstats file loopstats type day enable | ||
+ | # filegen peerstats file peerstats type day enable | ||
+ | # filegen clockstats file clockstats type day enable | ||
+ | |||
+ | # Resolution: fullscreen | ||
+ | #set term x11 size `xrandr | awk '/\*/{sub(/x/,",");print $1; exit}'` | ||
+ | |||
+ | set term png size '1024,768' | ||
+ | set grid | ||
+ | set bars 0.4 | ||
+ | set y2tics | ||
+ | set y2range [0:] | ||
+ | set ytics nomirror | ||
+ | set xdata time | ||
+ | set timefmt "%s" | ||
+ | set format x "%H:%M" | ||
+ | set title "NTP statistics" | ||
+ | set ylabel "Clock offset / Roundtrip delay (ms)" | ||
+ | set y2label "Frequency offset (seconds per day)" | ||
+ | set xlabel "Time of day" | ||
+ | local_time = `date +%s --utc -d "12:00:00 $(date +%z)"` | ||
+ | utc_time = `date +%s --utc -d "12:00:00"` | ||
+ | localdifferencefromUTC = utc_time - local_time | ||
+ | timeoffsettoday = `date +%s --utc -d "today 0:00"` + localdifferencefromUTC | ||
+ | set output "/var/www/html/graphs/ntp.png" | ||
+ | plot \ | ||
+ | "/var/log/ntpstats/loopstats" u ($2+timeoffsettoday):($3*1000):($5*1000/2) t "Clock offset" w errorlines lt 1 lw 2 pt 187, \ | ||
+ | "/var/log/ntpstats/peerstats" u ($2+timeoffsettoday):($6*1000):($8*1000/2) t "Roundtrip delay" w errorbars lt 26 pt 26,\ | ||
+ | # "/var/log/ntpstats/loopstats" u ($2+timeoffsettoday):($4*0.0864):($6*0.0864/2) axes x1y2 t "Frequency offset" w errorline lt 7 pt 65,\ | ||
+ | 0 w l lt -1 | ||
+ | #pause mouse close | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | And this is the GNUPlot script that generates the details: | ||
+ | |||
+ | <pre> | ||
+ | #!/usr/bin/gnuplot | ||
+ | |||
+ | set output '/var/www/html/graphs/loopstats.png' # Save the plot to a *.png file | ||
+ | set term png font arial 8 size 900, 600 # Set size of image: width, height | ||
+ | |||
+ | set zero 1e-08 | ||
+ | set lmargin -1 | ||
+ | set bmargin -1 | ||
+ | set rmargin -1 | ||
+ | set tmargin -1 | ||
+ | set locale "C" | ||
+ | set noclip points | ||
+ | set clip one | ||
+ | set noclip two | ||
+ | set bar 1.0 | ||
+ | set border 31 lt -1 lw 1.0 | ||
+ | set xdata | ||
+ | set ydata | ||
+ | set boxwidth | ||
+ | set dummy x,y | ||
+ | set format x "%g" | ||
+ | set format y "%g" | ||
+ | |||
+ | set key title "" | ||
+ | set key right top Right noreverse box linetype -2 linewidth 1.000 samplen 4 spacing 1 width 0 | ||
+ | set pointsize 1 | ||
+ | set encoding default | ||
+ | set origin 0,0 | ||
+ | set style data points | ||
+ | set xzeroaxis lt -2 lw 1.0 | ||
+ | set yzeroaxis lt -2 lw 1.0 | ||
+ | set tics in | ||
+ | set ticslevel 0.5 | ||
+ | set tics scale 1,0.5 | ||
+ | set mxtics default | ||
+ | set xtics border mirror norotate autofreq | ||
+ | set ytics border mirror norotate autofreq | ||
+ | set mxtics | ||
+ | set xlabel "UTC Time Seconds" | ||
+ | set xrange [0:86400] | ||
+ | set yrange [ * : * ] noreverse nowriteback # (currently [-10.0:10.0] ) | ||
+ | set time | ||
+ | set multiplot layout 2,1 title "NTP Estimated Offset and Jitter -- Most Recent 24 Hours" # 2 rows, 1 column of plots | ||
+ | |||
+ | set title "Time Offset" | ||
+ | set ylabel "Offset (seconds)" | ||
+ | plot "/var/log/ntpstats/loopstats" using 2:3 with linespoints, "/var/log/ntpstats/loopstats" using 2:3:5 with yerrorbars | ||
+ | |||
+ | set title "Frequency Offset" | ||
+ | set ylabel "Offset (ppm)" | ||
+ | plot "/var/log/ntpstats/loopstats" using 2:4 with linespoints, "/var/log/ntpstats/loopstats" using 2:4:6 with yerrorbars | ||
+ | </pre> | ||
+ | |||
+ | === Charts === | ||
+ | |||
+ | [[image:2016-05-31-overview_ntp1.png|800px]] | ||
+ | |||
+ | [[image:2016-05-31-details_ntp1.png|800px]] | ||
+ | |||
+ | [[image:2016-05-31-environmental_ntp1.png|800px]] | ||
+ | |||
+ | === Textual Output === | ||
+ | |||
+ | This is the ntpq -p output: | ||
+ | |||
+ | remote refid st t when poll reach delay offset jitter | ||
+ | ============================================================================== | ||
+ | oPPS(0) .PPS. 0 l 12 16 377 0.000 0.001 0.001 | ||
+ | *GPS_NMEA(0) .GPS. 1 l 11 16 377 0.000 8.351 2.548 | ||
+ | -s1.vlns.de 103.84.99.179 3 u 555 1024 377 31.992 0.934 0.348 | ||
+ | -xen1.hochstaett 130.149.17.8 2 u 418 1024 377 34.547 -3.785 2.045 | ||
+ | -hotel.zq1.de 161.62.157.173 3 u 939 1024 377 31.870 0.132 0.390 | ||
+ | +stratum2-3.ntp. 129.70.130.71 2 u 678 1024 377 40.134 2.543 0.215 | ||
+ | -db0fhn.as64626. 77.37.6.59 3 u 14 16 377 46.805 3.642 10.021 | ||
+ | +ptbtime1.ptb.de .PTB. 1 u 2 16 377 34.777 1.070 0.173 | ||
+ | 192.168.1.255 .BCST. 16 u - 64 0 0.000 0.000 0.001 | ||
+ | |||
+ | This is the ntptime output: | ||
+ | |||
+ | ntp_gettime() returns code 0 (OK) | ||
+ | time daf968e2.82eab768 Wed, Jun 1 2016 16:00:02.511, (.511394656), | ||
+ | maximum error 4234 us, estimated error 0 us, TAI offset 0 | ||
+ | ntp_adjtime() returns code 0 (OK) | ||
+ | modes 0x2000 (NANO), | ||
+ | offset 0.566 us, frequency -38.558 ppm, interval 1 s, | ||
+ | maximum error 4234 us, estimated error 0 us, | ||
+ | status 0x2007 (PLL,PPSFREQ,PPSTIME,NANO), | ||
+ | time constant 4, precision 0.001 us, tolerance 500 ppm, | ||
+ | |||
+ | This is the ntpq -c rl outout: | ||
+ | |||
+ | associd=0 status=011d leap_none, sync_pps, 1 event, kern, | ||
+ | version="ntpd 4.2.6p5@1.2349-o Mon Apr 11 00:03:43 UTC 2016 (1)", | ||
+ | processor="armv6l", system="Linux/4.1.19+", leap=00, stratum=1, | ||
+ | precision=-20, rootdelay=0.000, rootdisp=0.234, refid=PPS, | ||
+ | reftime=daf9698a.7e2ec618 Wed, Jun 1 2016 16:02:50.492, | ||
+ | clock=daf9698b.5f8ff368 Wed, Jun 1 2016 16:02:51.373, peer=36029, tc=4, | ||
+ | mintc=3, offset=0.000, frequency=-38.558, sys_jitter=0.001, | ||
+ | clk_jitter=0.000, clk_wander=0.000 | ||
+ | |||
+ | Notes: “ntpq -c rl” output parameters: | ||
+ | |||
+ | precision is rounded to give the next larger integer power of two. The achieved resolution is thus 2precision (seconds) | ||
+ | rootdelay – total roundtrip delay to the primary reference source at the root of the synchronization subnet. Note that this variable can take on both positive and negative values, depending on clock precision and skew (seconds) | ||
+ | rootdisp – maximum error relative to the primary reference source at the root of the synchronization subnet (seconds) | ||
+ | tc – NTP algorithm PLL (phase locked loop) or FLL (frequency locked loop) time constant (log2) | ||
+ | mintc – NTP algorithm PLL/FLL minimum time constant or ‘fastest response’ (log2) | ||
+ | offset – best and final offset determined by the combine algorithm used to discipline the system clock (ms) | ||
+ | frequency – system clock period (log2 seconds) | ||
+ | sys_jitter – best and final jitter determined by the combine algorithm used to discipline the system clock (ms) | ||
+ | clk_jitter – host hardware(?) system clock jitter (ms) | ||
+ | clk_wander – host hardware(?) system clock wander (PPM – parts per million) | ||
+ | |||
+ | == Images == | ||
[[Image:2016-04-05-SureGPS-1.jpg|400px]] [[Image:2016-04-05-SureGPS-2.jpg|400px]] | [[Image:2016-04-05-SureGPS-1.jpg|400px]] [[Image:2016-04-05-SureGPS-2.jpg|400px]] | ||
+ | |||
[[Image:2016-04-05-SureGPS-3.jpg|400px]] [[Image:2016-04-05-SureGPS-4.jpg|400px]] | [[Image:2016-04-05-SureGPS-3.jpg|400px]] [[Image:2016-04-05-SureGPS-4.jpg|400px]] | ||
+ | |||
[[Image:2016-04-05-SureGPS-5.jpg|400px]] [[Image:2016-04-05-SureGPS-6.jpg|400px]] | [[Image:2016-04-05-SureGPS-5.jpg|400px]] [[Image:2016-04-05-SureGPS-6.jpg|400px]] | ||
− | [[Image:2016-04-05-SureGPS-7 | + | |
+ | [[Image:2016-04-05-SureGPS-7.jpg|400px]] |
Aktuelle Version vom 15. Januar 2020, 19:46 Uhr
Inhaltsverzeichnis
1 Scope
It was already a few years ago when I bought a Sure Electronics GPS timing receiver. Though, there was never enough time to complete and deploy it. I have done it now.
The Sure receiver is nice because it has 3,3V IO pins, and this matches perfectly with a Raspberry Pi. So it's a good point using it.
Obviously many people have problems with the NTPD that comes with the recent raspian distributions: ntp 4.2.6p5. It does not support PPS...
It is rather easy to make the kernel PPS aware, but ntp still is not capable of using it. I needed to recompile the ntp package so that I was able to use it. The symptom therefore is:
- The tool ppstest does report the reception of a pulse, but even if you configure NTP correctly, it won't give you an output with PPS using the command ntpq -p.
- Please note that I am reading the PPS through GPIO Pin 18 and the regular NMEA sentence comes via the serial port. I am not using the onboard UART, but I rather connect the /dev/ttyUSB0.
Note that there is a successor project which is closely related: NTP-Server with Raspberry Pi and Trimble Resolution SMT
2 References
- http://www.satsignal.eu/ntp/Sure-GPS.htm Here the board is described very well
- http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
- https://store.uputronics.com/index.php?route=product/product&path=60_64&product_id=81
- http://rdlazaro.info/compu-Raspberry_Pi-RPi-stratum0.html
- http://mythopoeic.org/pi-ntp/
- https://raspberry.tips/raspberrypi-tutorials/raspberry-pi-uhrzeit-ueber-gps-beziehen-zeitserver/
3 Implementation
3.1 OS Installation and Preparation
First of all I decided to use a minibian image:
https://sourceforge.net/projects/minibian/files/2016-03-12-jessie-minibian.tar.gz
because I don't want to create a really big thing. I just want to have an NTP server.
- Unpack, write it to the SD card, as described so often everywhere on almost every RPI page.
- Use gparted to resize the root partition to the rest of your SD card. We should not waste space.
- Log in using uid root pwd raspberry (default). Note that opposed to Raspian, there is no user "pi".
- apt-get update; apt-get upgrade and update the minibian image.
- Give it a nice hostname, editing the file /etc/hostname and reboot.
- Edit /boot/config.txt - Add dtoverlay=pps-gpio,gpiopin=18 on a new line. - Connect the PPS signal of the Sure board to this pin. Don't get the pin wrong :-)
- I also added another line to the boot'config.txt file: dtparam=i2c_arm=on because I have included an I2C sensor that gives me some more values.
Here is why: http://stackoverflow.com/questions/32021924/raspberry-pi-2-cannot-enable-dev-i2c-0
- Save the file...
- Edit the file /etc/modules to contain the following lines. Just paste them below what is there already:
i2c-bcm2708 i2c_dev pps-gpio
- so to ensure that these modules will be loaded.
- Install the pps-tools:
apt-get install pps-tools
If you are using a BMP085 or a BMP180 sensor to grab some data as I do, then do this:
- Install the according i2c devices:
apt-get update apt-get install i2c-tools # I2C-Toolkit for commandline apt-get install python-smbus # Python library for I2C apt-get install libi2c-dev # library for C apt-get install git # need this later...
- Note here (German): http://www.netzmafia.de/skripten/hardware/RasPi/RasPi_I2C.html
- Note that the I2C devices will not becreated just like that, but that you need to create them manually:
mknod /dev/i2c-0 c 89 0 mknod /dev/i2c-1 c 89 1
- Configure the timezone using the command dpkg-reconfigure tzdata
- Create a symlink from /dev/ttyUSB0 to /dev/gps0 because the latter is the device the NTP driver will be looking for:
lrwxrwxrwx 1 root root 7 Apr 10 23:47 /dev/gps0 -> ttyUSB0
Alternatively it makes sense to create a udev rule file:
vi /etc/udev/rules.d/09.pps.rules
and add:
KERNEL=="ttyACM0", SYMLINK+="gps0" KERNEL=="pps0", OWNER="root", GROUP="tty", MODE="0660", SYMLINK+="gpspps0"
which will create the devices
/dev/ttygps0 /dev/gpspps0
Now reboot. A device will be created during system startup: /dev/pps0 Check for it to be created. Another device will be created for the I2C stuff, see below.
If you connected the PPS, the following command will produce results like here:
root@ntp1:/etc# ppstest /dev/pps0 trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1460368282.999995290, sequence: 43451 - clear 0.000000000, sequence: 0 source 0 - assert 1460368284.000007548, sequence: 43452 - clear 0.000000000, sequence: 0 source 0 - assert 1460368284.999994807, sequence: 43453 - clear 0.000000000, sequence: 0 source 0 - assert 1460368285.999995063, sequence: 43454 - clear 0.000000000, sequence: 0
If you get one of these lines every second, this means that your kernel is now disciplined by a PPS. It reacts to the pulse coming in, it recognizes the pulse properly. Congratulations!
Now let's check for the I2C stuff: The device /dev/i2c-1 should have been created. If you also use the BMP sensor, you should find it as '77'. Once you got the sensor connected as described in the manuals, detect it:
i2cdetect -y 1
and it should show up as "77":
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- 77
Great!
Then you can proceed to download Lady Ada's code examples:
git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
and then try it out:
cd Adafruit-Raspberry-Pi-Python-Code/Adafruit_BMP085 ./Adafruit_BMP085_example.py
Temperature: 25.29 C Pressure: 974.22 hPa Altitude: 530
Now let's go back for the NTP application.
Note: The structure of the Adafruit repositories has changed recently. Now you can clone exclusively the BMP libraries with this command:
git clone https://github.com/adafruit/Adafruit_Python_BMP
But let me remark that I am having problems with this recent development. Well, it's probably not so complicated but I have not hafd the time to find out how it works.
3.2 NTP configuration
The default NTP package is not sufficient, as I wrote above. It does not support reading the PPS from the kernel. It is quite disappointing if you did everything right and you're still not successful.
Though I recommend installing it first because we can prepare it nevertheless, using the command apt-get install ntp
Then edit the config file /etc/ntp.conf and make it look like this. Maybe it's agood idea to copy it to another filename and to have a reference: cp /etc/ntp.conf /etc/ntp.conf_orig. Now edit the /etc/ntp.conf:
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help driftfile /var/lib/ntp/ntp.drift # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable filegen sysstats file sysstats type day link enable tos minsane 3 tos orphan 10 tos mindist 0.4 server 127.127.22.0 minpoll 4 prefer fudge 127.127.22.0 refid PPS flag2 0 flag3 1 server 127.127.20.0 minpoll 4 mode 18 prefer # NMEA serial port, 16 = 9600 baud, 2 = $GPGGA fudge 127.127.20.0 time2 0.439 flag1 0 refid GPS stratum 1 flag3 1 #server 127.127.1.0 #fudge 127.127.1.0 stratum 10 #server 127.127.28.0 minpoll 4 maxpoll 4 #fudge 127.127.28.0 time1 0.000 refid SHM stratum 1 pool de.pool.ntp.org minpoll 10 iburst server db0fhn.ampr.org minpoll 4 iburst server ntp1.ptb.de minpoll 4 iburst # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for # details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions> # might also be helpful. # # Note that "restrict" applies to both servers and clients, so a configuration # that might be intended to block requests from certain clients could also end # up blocking replies from your own upstream servers. # By default, exchange time with everybody, but don't allow configuration. restrict -4 default kod notrap nomodify nopeer noquery restrict -6 default kod notrap nomodify nopeer noquery restrict 172.16.0.0 mask 255.240.0.0 restrict 192.168.0.0 mask 255.255.0.0 # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 restrict ::1 broadcast 192.168.1.255
Since NTP is frequently writing to the SD card, I did a trick. The creation of the mount point /var/log/ntpstats will be done during package installation.
- Stop the daemon with service ntp stop
- Now delete the contents of this directory: rm /var/log/ntpstats/*
- Now add the following line to the file /etc/fstab and create a RAM disk
tmpfs /var/log/ntpstats tmpfs nodev,nosuid,size=10M 0 0
- It will cost 10 of your 512 MB RAM, but you didn't plan a high performance compute cluster anyway :-) If you want, you can easily add more. Occasional reboots will keep it empty anyway.
- Note that the process ntpd just consumes about 5 MBytes... So 512 is almost a waste of RAM. :-)
- Reboot.
Now let's check a couple of things:
- mount will show something like this:
tmpfs on /var/log/ntpstats type tmpfs (rw,nosuid,nodev,relatime,size=10240k)
- ntpq -p will show something like this:
root@ntp1:/etc# ntpq -p remote refid st t when poll reach delay offset jitter ============================================================================== *GPS_NMEA(0) .GPS. 1 l 7 16 377 0.000 1.300 11.017 -test.danzuck.ch 162.23.41.56 2 u 712 1024 377 20.054 -0.302 1.833 +stratum2-3.NTP. 129.70.130.70 2 u 288 1024 377 31.598 2.897 0.542 +static.5-9-80-1 213.239.239.165 3 u 448 1024 377 21.270 1.829 0.854 -ns2.bvc-cloud.d 109.75.188.245 3 u 212 1024 377 23.095 0.746 0.502
- Note that there is probably no line containing anything about PPS.
- Though this output already tells us that our NTP server is keeping a more or less precise time. Good enough for your alarm clock in the morning for sure :-)
- Now let's add PPS support. Here is a good reference page: https://raspberry.tips/raspberrypi-tutorials/raspberry-pi-uhrzeit-ueber-gps-beziehen-zeitserver/
- Since the recent minibian is based on jessie rather than on wheezy:
sh -c 'echo "deb-src http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi" >> /etc/apt/sources.list' apt-get update
- Get the build dependencies and the source code of the package:
cd ~ apt-get -y build-dep ntp apt-get -y source ntp
- The source code was stored in my home directory. In the moment and for me it is the version ntp-4.2.6.p5+dfsg. Note that it could be different for you.
cd ntp-4.2.6.p5+dfsg/debian/
- Edit the rules file and add the missing support for PPS/ATOM. Search for configure and append a line at the end of the statement. Don't forget the \ at the end of the previous line.
./configure CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' \ --prefix=/usr \ --enable-all-clocks --enable-parse-clocks --enable-SHM \ --disable-debugging --sysconfdir=/var/lib/ntp \ --with-sntp=no \ --with-lineeditlibs=edit \ --without-ntpsnmpd \ --disable-local-libopts \ --enable-ntp-signd \ --disable-dependency-tracking \ --with-openssl-libdir=/usr/lib/$(DEB_HOST_MULTIARCH) \ --enable-ATOM
- Now add the changelog file so that it reflects the change:
ntp (1:4.2.6.p5+dfsg-7+deb8u1) jessie-security; urgency=medium
- into:
ntp (1:4.2.6.p5+dfsg-8+deb8u1) jessie-security; urgency=medium
- Now 'cd' into the package directory and build the package.
cd .. sudo dpkg-buildpackage -b
- It will take a while now. In my case three deb files were created:
344 -rw-r--r-- 1 root root 350362 Apr 11 02:11 ntp_4.2.6.p5+dfsg-8+deb8u1_armhf.deb 68 -rw-r--r-- 1 root root 68882 Apr 11 02:11 ntpdate_4.2.6.p5+dfsg-8+deb8u1_armhf.deb 1008 -rw-r--r-- 1 root root 1030588 Apr 11 02:09 ntp-doc_4.2.6.p5+dfsg-8+deb8u1_all.deb
- Now install them:
cd .. dpkg -i ntp_4.2.6.p5+dfsg-8+deb8u1_armhf.deb dpkg -i ntpdate_4.2.6.p5+dfsg-8+deb8u1_armhf.deb dpkg -i ntp-doc_4.2.6.p5+dfsg-8+deb8u1_all.deb
- Now restart the ntp server with the command service ntp restart and after ~ 1 minute it should give you this output using ntpq -p:
root@ntp1:~# ntpq -p
remote refid st t when poll reach delay offset jitter ============================================================================== oPPS(0) .PPS. 0 l 16 16 377 0.000 -0.090 0.007 *GPS_NMEA(0) .GPS. 1 l 15 16 377 0.000 -4.357 5.950 -static.249.171. 194.225.150.25 3 u 163 1024 3 20.506 -1.796 1.607 +tschil.ethgen.c 131.188.3.222 2 u 175 1024 3 20.443 -0.381 0.988 +malbolge.de 131.188.3.221 2 u 169 1024 3 20.930 -0.417 0.933 -ghost-networks. 130.149.17.8 2 u 204 1024 3 22.189 0.102 0.769
- The 'o' at the beginning of the line says that PPS is being used.
- Please also check the output of ntptime:
root@ntp1:~# ntptime ntp_gettime() returns code 0 (OK) time dab60019.f0feffcc Mon, Apr 11 2016 12:51:05.941, (.941391075), maximum error 4827 us, estimated error 0 us, TAI offset 0 ntp_adjtime() returns code 0 (OK) modes 0x0 (), offset -76.297 us, frequency -37.570 ppm, interval 1 s, maximum error 4827 us, estimated error 0 us, status 0x2007 (PLL,PPSFREQ,PPSTIME,NANO), time constant 4, precision 0.001 us, tolerance 500 ppm,
- If you want to know how to interpret it, consider this (rather old) posting: https://groups.google.com/forum/#!topic/comp.protocols.time.ntp/FDAIxL3V-k4
Congratulations!
3.3 System considerations concerning DHCP
In case you retrieve your IP configuration via DHCP, there is a default statement to also retrieve the according NTP server config: You will want to exclude that!
Edit the file /etc/dhcp/dhclient.conf and remove the string ntp-servers from the line behind the request keyword.
Then remove the file /var/lib/ntp/ntp.conf.dhcp.
4 Results
4.1 Processing Automation
Here are the contents for the /etc/crontab file:
*/10 * * * * root /var/www/bin/createstats.sh 2>&1 > /dev/null */10 * * * * root /usr/local/bin/prep_charts.gpl 2>&1 > /dev/null */10 * * * * root /usr/local/bin/prep_env.gpl 2>&1 > /dev/null * * * * * root cat /var/www/html/ntpq_c_rl_notes > /var/www/html/graphs/ntpq-c_rl.txt; ntpq -c rl >> /var/www/html/graphs/ntpq-c_rl.txt * * * * * root ntptime -N > /var/www/html/graphs/ntptime.txt * * * * * root ntpq -p > /var/www/html/graphs/ntpq-p.txt; cat /var/www/html/ntpq-p-notes.txt >> /var/www/html/graphs/ntpq-p.txt * * * * * root /usr/local/bin/env_data.sh 2>&1 > /dev/null
Note that I am adding some legend to the ntpq -p output: /var/www/html/graphs/ntpq-p.txt
-------------------------------------------------------------------------------------------------------------- * the source you are synchronized to (syspeer) # source selected, distance exceeds maximum value o the PPS(Pulse Per Second) source if your ntpd (ppspeer, only if you have a PPS capable system and refclock) + candidate, i.e. it is considered a good source - outlyer, i.e. quality is not good enough x falseticker, i.e. this one is considered to distribute bad time blank: source discarded, failed sanity
I am also adding some notes to the 'ntpq -c rl' output: /var/www/html/ntpq-p-notes.txt
Notes: 'ntpq -c rl' output parameters: precision - is rounded to give the next larger integer power of two. The achieved resolution is thus 2precision (seconds) rootdelay - total roundtrip delay to the primary reference source at the root of the synchronization subnet. Note that this variable can take on both positive and negative values, depending on clock precision and skew (seconds) rootdisp - maximum error relative to the primary reference source at the root of the synchronization subnet (seconds) tc - NTP algorithm PLL (phase locked loop) or FLL (frequency locked loop) time constant (log2) mintc - NTP algorithm PLL/FLL minimum time constant or 'fastest response' (log2) offset - best and final offset determined by the combine algorithm used to discipline the system clock (ms) frequency - system clock period (log2 seconds) sys_jitter - best and final jitter determined by the combine algorithm used to discipline the system clock (ms) clk_jitter - host hardware(?) system clock jitter (ms) clk_wander - host hardware(?) system clock wander (PPM - parts per million)
4.2 Data Processing
Here is how we collect environmental data. Please note that the stats of the NTP daemon are produced anyway.
root@ntp1:/usr/local/bin# cat /usr/local/bin/env_data.sh #!/bin/bash DATAFILE="/var/log/envdata/envdata.log" YESTERDAY="/var/log/envdata/yesterdaydata.log" TODAY="/var/log/envdata/todaydata.log" tail -3000 $DATAFILE \ | grep $(date -d yesterday +"%Y-%m-%d") \ > $YESTERDAY tail -30000 $DATAFILE \ | grep $(date +%F) \ > $TODAY # Ueberlauf verhindern cat $YESTERDAY > $DATAFILE cat $TODAY >> $DATAFILE COMMAND=/usr/local/bin/get_env_data.py MESSZEITPUNKT=$(date '+%F %T') MESSUNG=$($COMMAND) OUTLINE="$MESSZEITPUNKT $MESSUNG" echo $OUTLINE >> $DATAFILE
4.3 GNUPlot
This is the script which evaluates round trip times and offset for the general voerview:
#! /usr/bin/gnuplot # Remember to check you have these lines in /etc/ntp.conf and that ntpd is actually running: # statsdir /var/log/ntpstats/ # statistics loopstats peerstats clockstats # filegen loopstats file loopstats type day enable # filegen peerstats file peerstats type day enable # filegen clockstats file clockstats type day enable # Resolution: fullscreen #set term x11 size `xrandr | awk '/\*/{sub(/x/,",");print $1; exit}'` set term png size '1024,768' set grid set bars 0.4 set y2tics set y2range [0:] set ytics nomirror set xdata time set timefmt "%s" set format x "%H:%M" set title "NTP statistics" set ylabel "Clock offset / Roundtrip delay (ms)" set y2label "Frequency offset (seconds per day)" set xlabel "Time of day" local_time = `date +%s --utc -d "12:00:00 $(date +%z)"` utc_time = `date +%s --utc -d "12:00:00"` localdifferencefromUTC = utc_time - local_time timeoffsettoday = `date +%s --utc -d "today 0:00"` + localdifferencefromUTC set output "/var/www/html/graphs/ntp.png" plot \ "/var/log/ntpstats/loopstats" u ($2+timeoffsettoday):($3*1000):($5*1000/2) t "Clock offset" w errorlines lt 1 lw 2 pt 187, \ "/var/log/ntpstats/peerstats" u ($2+timeoffsettoday):($6*1000):($8*1000/2) t "Roundtrip delay" w errorbars lt 26 pt 26,\ # "/var/log/ntpstats/loopstats" u ($2+timeoffsettoday):($4*0.0864):($6*0.0864/2) axes x1y2 t "Frequency offset" w errorline lt 7 pt 65,\ 0 w l lt -1 #pause mouse close
And this is the GNUPlot script that generates the details:
#!/usr/bin/gnuplot set output '/var/www/html/graphs/loopstats.png' # Save the plot to a *.png file set term png font arial 8 size 900, 600 # Set size of image: width, height set zero 1e-08 set lmargin -1 set bmargin -1 set rmargin -1 set tmargin -1 set locale "C" set noclip points set clip one set noclip two set bar 1.0 set border 31 lt -1 lw 1.0 set xdata set ydata set boxwidth set dummy x,y set format x "%g" set format y "%g" set key title "" set key right top Right noreverse box linetype -2 linewidth 1.000 samplen 4 spacing 1 width 0 set pointsize 1 set encoding default set origin 0,0 set style data points set xzeroaxis lt -2 lw 1.0 set yzeroaxis lt -2 lw 1.0 set tics in set ticslevel 0.5 set tics scale 1,0.5 set mxtics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set mxtics set xlabel "UTC Time Seconds" set xrange [0:86400] set yrange [ * : * ] noreverse nowriteback # (currently [-10.0:10.0] ) set time set multiplot layout 2,1 title "NTP Estimated Offset and Jitter -- Most Recent 24 Hours" # 2 rows, 1 column of plots set title "Time Offset" set ylabel "Offset (seconds)" plot "/var/log/ntpstats/loopstats" using 2:3 with linespoints, "/var/log/ntpstats/loopstats" using 2:3:5 with yerrorbars set title "Frequency Offset" set ylabel "Offset (ppm)" plot "/var/log/ntpstats/loopstats" using 2:4 with linespoints, "/var/log/ntpstats/loopstats" using 2:4:6 with yerrorbars
4.4 Charts
4.5 Textual Output
This is the ntpq -p output:
remote refid st t when poll reach delay offset jitter ============================================================================== oPPS(0) .PPS. 0 l 12 16 377 0.000 0.001 0.001 *GPS_NMEA(0) .GPS. 1 l 11 16 377 0.000 8.351 2.548 -s1.vlns.de 103.84.99.179 3 u 555 1024 377 31.992 0.934 0.348 -xen1.hochstaett 130.149.17.8 2 u 418 1024 377 34.547 -3.785 2.045 -hotel.zq1.de 161.62.157.173 3 u 939 1024 377 31.870 0.132 0.390 +stratum2-3.ntp. 129.70.130.71 2 u 678 1024 377 40.134 2.543 0.215 -db0fhn.as64626. 77.37.6.59 3 u 14 16 377 46.805 3.642 10.021 +ptbtime1.ptb.de .PTB. 1 u 2 16 377 34.777 1.070 0.173 192.168.1.255 .BCST. 16 u - 64 0 0.000 0.000 0.001
This is the ntptime output:
ntp_gettime() returns code 0 (OK) time daf968e2.82eab768 Wed, Jun 1 2016 16:00:02.511, (.511394656), maximum error 4234 us, estimated error 0 us, TAI offset 0 ntp_adjtime() returns code 0 (OK) modes 0x2000 (NANO), offset 0.566 us, frequency -38.558 ppm, interval 1 s, maximum error 4234 us, estimated error 0 us, status 0x2007 (PLL,PPSFREQ,PPSTIME,NANO), time constant 4, precision 0.001 us, tolerance 500 ppm,
This is the ntpq -c rl outout:
associd=0 status=011d leap_none, sync_pps, 1 event, kern, version="ntpd 4.2.6p5@1.2349-o Mon Apr 11 00:03:43 UTC 2016 (1)", processor="armv6l", system="Linux/4.1.19+", leap=00, stratum=1, precision=-20, rootdelay=0.000, rootdisp=0.234, refid=PPS, reftime=daf9698a.7e2ec618 Wed, Jun 1 2016 16:02:50.492, clock=daf9698b.5f8ff368 Wed, Jun 1 2016 16:02:51.373, peer=36029, tc=4, mintc=3, offset=0.000, frequency=-38.558, sys_jitter=0.001, clk_jitter=0.000, clk_wander=0.000
Notes: “ntpq -c rl” output parameters:
precision is rounded to give the next larger integer power of two. The achieved resolution is thus 2precision (seconds) rootdelay – total roundtrip delay to the primary reference source at the root of the synchronization subnet. Note that this variable can take on both positive and negative values, depending on clock precision and skew (seconds) rootdisp – maximum error relative to the primary reference source at the root of the synchronization subnet (seconds) tc – NTP algorithm PLL (phase locked loop) or FLL (frequency locked loop) time constant (log2) mintc – NTP algorithm PLL/FLL minimum time constant or ‘fastest response’ (log2) offset – best and final offset determined by the combine algorithm used to discipline the system clock (ms) frequency – system clock period (log2 seconds) sys_jitter – best and final jitter determined by the combine algorithm used to discipline the system clock (ms) clk_jitter – host hardware(?) system clock jitter (ms) clk_wander – host hardware(?) system clock wander (PPM – parts per million)