● Raspberry Pi Zero W与GPS模块搭建NTP授时服务器

0. GPS模块

因为GPS模块仅做测试,不用于生产环境,我选了一块便宜的GT-U8模块。使用USB串口模块接好GPS模块后,收到GPS上报数据。 gps

1. 配置国内软件源

  • 修改sources.list文件 sudo nano /etc/apt/sources.list
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
  • 修改raspi.list文件 sudo nano /etc/apt/sources.list.d/raspi.list
deb http://mirror.tuna.tsinghua.edu.cn/raspberrypi/ stretch main ui
deb-src http://mirror.tuna.tsinghua.edu.cn/raspberrypi/ stretch main ui

2. 更新 RaspberryPi

sudo apt-get update
sudo apt-get dist-upgrade
sudo rpi-update
sudo reboot

rpi-update启动时会更新自己,如果报以下错误:

!!! Failed to download update for rpi-update!
!!! Make sure you have ca-certificates 
installed and that the time is set correctly

直接更新固件的方法:

sudo UPDATE_SELF=0 rpi-update

3. 配置串口信息

  1. 打开串口。输入命令:
sudo raspi-config
  • 选择第3项

  • 选择P6

  • 选择"No",关闭串口登录

  • 选择"Yes",打开硬件串口通讯

  • 设置完成后界面

  • 退出,sudo poweroff 关机

4. GPS模块连接GPIO接口

raspberry pi gps model
5v vcc
Ground GND
GPIO 16(RxD) TX
GPIO 15(TxD) RX

  • 通电后启动,在路由器内为主板设置固定IP。SSH远程连接主板,输入以下命令:

    cat /dev/ttyS0
    
  • 会看到以下结果(马赛克隐藏了经纬度),红框中为UTC时间,时区以系统设置的timezone为准:

5. 配置PPS

  • gpio readall 查看所有针脚,选择上图BCM针脚GPIO 18,插好PPS针脚。

树莓派的引脚主要有3种编码规则: 1、BCM 2、BOARD 3、WiringPi

BCM、BOARD编码主要用在Python的RPi.GPIO库,WiringPi主要用在C++等平台(没用过)。

BCM是Broadcom芯片系列的名字,BCM编码规则与芯片上系统中信道编号相对应,不同版本的树莓派可能会有不同的定义。

BOARD是树莓派硬件上的物理引脚编号,相对稳定。

安装 PPS-tools

sudo apt-get install pps-tools
sudo apt-get install libcap-dev

可能遇到包依赖问题,需要适当降级。

sudo apt-get install 包名=版本

配置 PPS-tools

1.使用 sudo nano /boot/config.txt 修改文件,在文件的最后加入 dtoverlay=pps-gpio,gpiopin=18 保存退出。

2.使用 sudo nano /etc/modules 修改文件,在文件的最后加入 pps-gpio 保存并退出。

3.重启。

验证 PPS 是否工作

  • 使用 lsmod | grep pps 验证模块是否正常加载。若输出如下信息系正常:

  • 使用 dmesg | grep pps 命令检查 PPS GPIO 是否被配置,若输出如下信息系正常:

  • 使用 sudo ppstest /dev/pps0 将会看到类似下面的输出: 正常情况下每一秒输出一条,如果发现输出间隔不是一秒,可能是连线错误或者 GPS 模块未设置导致的。

6.配置 NTP 服务

有两个方案可以实现 NTP 服务,ntpd 和 chrony。但是 RaspberryPi 源中的 ntpd 是一个阉割的版本,里面不含 PPS 支持。

chrony 的优点有: 同步更快,只需要几分钟收敛到最小误差,而 ntpd 可能需要几个小时。 对变频环境有优化。 对于断线和延迟有更好的优化。 chrony 的缺点(可以弥补): 仅支持 PPS,对于 GPS 的串口连接的 NMEA 语句没有支持,但可以通过 gpsd 的共享内存的方式来获取。

安装 GPSD

sudo apt install gpsd gpsd-clients python-gps
#sudo apt-get install ncurses-term

可能又会遇到包依赖问题,需要适当降级。

安装中可能会遇到很多坑,比如:

1. Error opening terminal: xterm.
2. 'xterm': unknown terminal type.
3. Error opening terminal: xterm-256color

运行 sudo apt install ncurses-base ,然后运行 whereis terminfo,找到 /etc/profile,在尾部增加如下内容:

export TERMINFO=/lib/terminfo/

运行 source /etc/profile 生效。

修改 sudo nano /etc/default/gpsd 文件如下:

DEVICES="/dev/ttyS0"
GPSD_OPTIONS="-n -G"

配置 GPSD 开机启动

sudo systemctl enable gpsd.socket #启用
sudo systemctl start gpsd.socket #开启
sudo systemctl restart gpsd.socket #重启
sudo systemctl status gpsd.socket #查看状态

检查 GPSD

使用 sudo cgps -s 来查看 GPSD 的数据,如果你在开阔的地方,你将会看到类似下面的输出:

安装 chrony

sudo apt install chrony

修改配置文件 sudo nano /etc/chrony/chrony.conf 确保有以下内容(如果没有则添加)

#修改
makestep 1 3
makestep 1.0 -1
#新增
leapsectz right/UTC
refclock PPS /dev/pps0 lock GPSD prefer refid PPS
refclock SHM 0 offset 0.0 delay 0.2 refid GPSD

allow
makestep 1.0 -1表示超过1秒立刻修正,不回归
rtcsync每11分钟自动矫正系统rtc时钟
allow 允许局域网所有设备使用本服务器时间

配置完成后通过 sudo service chrony restart 重启服务。

可以通过下面两个命令来查看连接状态:

watch -n1 chronyc sources -v
watch -n1 chronyc sourcestats -v

6.开启NTP服务

chrony应该自带ntp服务,所以不用单独安装ntpserver,直接连接IP的123端口即可。

下图是为公司写的一个子母钟配置工具,可以完美获取到Raspberry Pi Zero W同步的GPS时间。

参考文章: https://blog.csdn.net/xiaohu50/article/details/78731534