ntpi:使用 Raspberry Pi 和GPS模块的精准时间
原文链接:
https://www.talkunafraid.co.uk/2012/12/the-ntpi-accurate-time-with-a-raspberry-pi-and-venus638flpx/
我一直喜欢修改时间源和同步。通常,这与一些合理的事情有关,比如网络时间协议,以及为广播网络设计和维护时间分配系统。最近虽然我一直在玩“实时”来源-全球定位系统和MSF广播。这是一个关于如何设置一个Raspberry Pi的快速教程,它只需消耗几瓦的功率就可以成为一个经济的时间服务器,与Venus 638FLPx GPS接收器(可从Sparkfun的一个合适的转接板上获得)进行对话在这里).
值得注意的是,所讨论的GPS芯片并不是真正理想的定时应用。有更好的板来达到这个目的。但最重要的是,由于大多数这些东西都是非常标准的,所以几乎所有这些指南仍然有效。Venus确实制造了一个IC,638LPx-T,这是这个芯片的一个变体,设计用于计时,精度为正负30 us,但我在一个breakout 板上找不到,我有一个来自UAS平台的FLPx板备用。
GPS时间源/服务器的基本要求是:
- 以串行方式输出NMEA字符串并具有1PPS输出的GPS模块。
- 带有GPIO引脚的计算机,用于1PPS和串行连接,运行Linux。
- GPS天线安装在一个可以看到一大片天空并反馈给模块的地方。
Venus板上的引脚有串行RX/TX,+3.3V,GND和PPS。对于我的时间服务器,我使用的是Raspberry Pi–要使用的GPIO是头上的23号插脚,RX连接到TX,TX连接到RX,而且3V3的报头电源非常适合为模块供电。我用了一个Adafruit Pi Cobbler 来做这个,但是以后会用一个Ciseco Slice of Pi board来做一些更坚固的东西。无论如何,鼓捣起来很简单。
棘手的一点来自软件。让我们来谈谈GPS时间来源是如何工作的。
GPS卫星依靠高度精确的定时,并将UTC时间信息作为信号的一部分进行广播。时间戳的区别在于,很大程度上,是什么让你的接收者知道你在哪里。但是,如果你知道你在哪里,你可以使用这些时间戳来找到一个非常精确的时间定位。
GPS上的NMEA字符串描述了各种各样的事情。它们看起来有点像:
pi@ntpi ~ $ cat /dev/gps0
$GPGGA,201705.000,5644.4848,N,00142.3529,W,1,10,0.9,64.4,M,49.0,M,,0000*75
$GPGLL,5644.4848,N,00142.3529,W,201705.000,A,A*43
$GPGSA,A,3,07,26,08,19,15,05,09,21,18,24,,,1.5,0.9,1.2*3B
$GPZDA,201705.000,29,12,2012,00,00*5E
它们有点晦涩,但它们有时间编码在里面,比如解决方案中使用了多少卫星,速度/航向等等。例如,第一个块,$GPGGA是每个字符串的前导码,最后三个字符用于表示该类型的字符串,例如GGA。
遗憾的是,这不能给我们一个非常准确的参考。让我们看看PPS是什么样子,对于初学者来说,使用示波器:
我们可以很清楚地看到这些都是很小的,5毫秒的高电平脉冲,一秒钟一次。真棒!那么这些NMEA字符串通过串行发送如何?
我们可以看到,在这个轨迹的上半部分,一个完整的NMEA传输发生在PPS脉冲之后(1.18ms),但是NMEA帧传输是很大的!并且如果我们跟着它,我们也会看到它(的开始时刻)在左右晃动。
这是PPS脉冲相对于NMEA传输的放大视图(脉冲后1.6毫秒,这次-变化很大)。这是用GPS在“发送NMEA与PPS同步”模式下拍摄的!
PPS 和 ntpd
因此,如果我们想让我们的设备准确,我们需要使用PPS。但如果我们只使用PPS,我们就不知道了哪一个我们马上就到了!所以我们必须两者兼用。幸运的是,ntpd会帮我们处理的。
2015年4月更新:你现在可以跳过内核了!
**但是…**您需要启用设备树并将dtoverlay=pps-gpio,gpiopin=23添加到config.txt 。现在,您可以通过rpi配置工具启用设备树并禁用serial,如下面一节所述。您仍然需要将pps-gpio行添加到/etc/modules。
如果你是现代的Pi,跳过下面的内容!
回到软件上,我们需要一个内核来处理GPIO端口上的PPS脉冲。让我们安装一个:
git clone https://github.com/davidk/adafruit-raspberrypi-linux-pps.git
cd adafruit-raspberrypi-linux-pps/
sudo mv /boot/kernel.img /boot/kernel.img.orig
sudo cp kernel.img /boot
sudo mv modules/* /lib/modules
sudo sh -c "echo 'pps-gpio' >> /etc/modules"
我们需要禁用Pi的serial的默认用法,即提供tty。打开/boot/cmdline.txt并删除所有引用ttyAMA0的元素。我的看起来像这样:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
接下来,打开/etc/inittab并注释这行:
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
潜回这里,未来的读者们!以下仍然适用于现代Pis。
我们还希望配置udev,将GPS模块和PPS放在ntpd期望的位置:
sudo nano /etc/udev/rules.d/80-gps-to-ntp.rules
# Change MODE of ttyAMA0 so it is readable by NTP and provide a symlink to
# /dev/gps0
KERNEL=="ttyAMA0", SUBSYSTEM=="tty", DRIVER=="", SYMLINK+="gps0", MODE="0666"
# Symlink /dev/pps0 to /dev/gpspps0
KERNEL=="pps0", SUBSYSTEM=="pps", DRIVER=="", SYMLINK+="gpspps0", MODE="0666"
接下来,我们将安装并删除ntpd–我们将返回更新版本。
sudo apt-get install ntp
sudo apt-get remove ntp
sudo apt-get install libcap-dev
安装和编译支持PPS的ntpd。
wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-dev/ntp-dev-4.2.7p340.tar.gz
tar zxf ntp-dev-4.2.7p340.tar.gz
cd ntp-dev-4.2.7p340/
./configure --prefix=/usr --enable-all-clocks --enable-parse-clocks --enable-SHM --enable-debugging --sysconfdir=/var/lib/ntp --with-sntp=no --with-lineeditlibs=edit --without-ntpsnmpd --disable-local-libopts --disable-dependency-tracking --enable-ipv6 && make && sudo make install
现在我们已经完成了重新启动以加载新内核所需的所有信息:
sudo reboot
首先,我们可以验证是否可以看到NMEA语句:
cat /dev/gps0
你应该看到NMEA字符串!按Ctrl+C组合键终止它。接下来,让我们测试PPS。
pi@ntpi ~ $ dmesg | grep pps
[ 0.000000] Linux version 3.1.9adafruit-pps+ (davidk@bender) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #21 PREEMPT Sun Sep 2 10:57:58 PDT 2012
[ 1.148909] usb usb1: Manufacturer: Linux 3.1.9adafruit-pps+ dwc_otg_hcd
[ 14.707851] pps_core: LinuxPPS API ver. 1 registered
[ 14.712724] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 14.728437] pps pps0: new PPS source pps-gpio.-1
看来我们弄好了。如果需要更完整地验证,请检查pps-utils包。
下一个:告诉ntp这个闪亮的新本地时钟!
我们需要先做一件事-如果你的本地网络有一个DHCP服务器宣布时间服务器,而你想使用你的本地NTP配置,您需要编辑/etc/init.d/ntp并注释以下行:
#if [ -e /var/lib/ntp/ntp.conf.dhcp ]; then
# NTPD_OPTS="$NTPD_OPTS -c /var/lib/ntp/ntp.conf.dhcp"
#fi
打开/etc/ntp。配置并调整它。下面这一节应该能让你开始运转:
server 127.127.20.0 mode 24 minpoll 3 maxpoll 4 iburst true prefer
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 flag4 1 time2 0.093
这里的设置有文档记录在这里并且可以配置为适合您的模块。time2值可能需要更大(0.4左右),您可能希望保留或删除在ntp.conf中配置的现有服务器,或者将它们重新配置为地理位置上的本地。您可以了解time2偏移量,方法是在使用的任何mode值上加128,然后在ntpd重新启动后查看/var/log/ntpstats/clockstats中的计时。选择第一个看到的NMEA字符串的时间偏移量,这就是你的数字。
注:上面的模式24选择一些timing strings,并假设与GPS的通信波特率为9600。
重新启动ntpd,等待几分钟,让一切都平静下来,然后验证一切正常:
pi@ntpi ~ $ ntptime
ntp_gettime() returns code 0 (OK)
time d489d596.2b0cfe14 Sat, Dec 29 2012 20:48:22.168, (.168167784),
maximum error 2000 us, estimated error 1 us, TAI offset 0
ntp_adjtime() returns code 0 (OK)
modes 0x0 (),
offset 2.518 us, frequency 79.473 ppm, interval 1 s,
maximum error 2000 us, estimated error 1 us,
status 0x2007 (PLL,PPSFREQ,PPSTIME,NANO),
time constant 3, precision 0.001 us, tolerance 500 ppm,
pi@ntpi ~ $ ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
oGPS_NMEA(0) .GPS. 0 l 8 8 377 0.000 0.002 0.004
+ns0.luns.net.uk 157.44.176.4 2 u 63 64 17 44.161 3.389 0.709
-ntp.oceanmediag 192.93.2.20 2 u 5 64 37 34.806 2.048 0.585
+dns1.rmplc.co.u 193.62.22.74 2 u 63 64 17 36.375 2.488 0.282
*mail1.itdojo.or 10.10.120.2 2 u 56 64 17 51.280 3.977 0.270
pi@ntpi ~ $ ntptrace
localhost: stratum 1, offset 0.000001, synch distance 0.001090, refid 'GPS'
请注意ntpq-p中GPS_NMEA(0) 前的 o 表示正在使用PPS。如果你没有启用PPS,你的时间会很糟糕,就像我们在scope跟踪中看到的那样。为了说明这一点,这里比较了NMEA only和PPS之间的系统性能。
(译者注:图像靠右侧的稳定线为启用PPS,除此之外未启用PPS)
你真的,真的想确保你的系统正在使用PPS,这就是我要说的。
我遇到的另一件事是GPS报告了错误的时间或者没有报告它的时间偏移量-只要确保启用了GPZDA语句就可以避免这种情况。这种情况的症状可能包括巨大的偏移量,以及在其他对等方的对等方列表中被标记为虚假标记(x)。只需确保模块配置正确即可。这是我配置模块时所做的:
- 启用位置锁定
- 禁用除GGA、GSA、GLL和ZDA之外的所有NMEA字符串
- 将更新速率设置为1Hz,并将输出同步设置为UTC
- 将波特率设置为9600(更高不更好!)
这似乎工作得很好,而且我对解决方案的低成本的性能非常满意-它只需要打开一个盒子,它将是一个很好的稳定的家庭网络时间参考。我仍然对用接收器从MSF那里获得时间感兴趣,但我们这里接收到的MSF信号相当差,所以我们会看看这是否可行与Pi。
考虑到在广播网络中保持准确的时间是多么的重要,特别是对于外部节目源,这是一件非常好的事情,设备已经工作,过程也记录下来了。
向Raspberry Pi论坛这里做了很多基础工作(legwork)来解决这一切问题的人们致敬!
稍后更新
我把NTPi放在我工作台的一个角落里,上面有一个GPS天线,视野相当好(在视图中记录/绘制GPS卫星是我未来想要做的扩展)。即使是偶尔的偏离,至少也不能完全通过其他复杂的测量!(at least from this minimally-complex and not-entirely-thought-through amateur measurement!)