ラズパイでStratum 1 NTPサーバーを試してみました。その方法は全てネット上にある記事のつまみ食いです。

 

↓ そのつまみ食いの結果がこれです。精度もStratum 1と言って良いのでは?

↑ グラフ中央の跳ね上がり(下がり)の原因は、ntpとgpsbを再起動させた為です。

 

どんなつまみ食いだったかを備忘録として残して置きます。

秋月のGPSキット(K-13850)とラズパイ4で試しました。

始めに見落としがちな事を。
このGPSを使用する場合、1PPS出力がアクティブLowである事を意識して置かないと、私みたいにハマってしまいます。そのパルスは ↓


秋月の取説PDFからコピぺ

このような波形の時は、/boot/config.txt に assert_falling_edge=true が必要になります。これを記述して置かないと100msズレて参照リストから外れたサーバー “x”印になってしまいます。

 

GPSとラズパイの結線


カラー図は秋月からのコピぺ

 

インストール

$ sudo apt update
$ sudo apt install ntp
$ sudo apt install gpsd gpsd-clients pps-tools

 

設定

$ sudo vi /boot/cmdline.txt

console=serial0,115200の削除
$ sudo vi /boot/config.txt

末尾に追加
enable_uart=1
dtoverlay=pps-gpio
dtparam=gpioin=18
dtparam=assert_falling_edge=true
$ sudo vi /etc/modules

末尾に追加
pps-gpio
$ sudo vi /etc/default/gpsd

START_DAEMON="true"
USBAUTO="false"
DEVICES="/dev/ttyS0 /dev/pps0"
GPSD_OPTIONS="-n"
$ sudo vi /etc/ntp.conf

server 127.127.28.2 minpoll 4 maxpoll 4 prefer
fudge  127.127.28.2 refid GPS stratum 14
server 127.127.22.0 minpoll 4 maxpoll 4
fudge  127.127.22.0 refid PPS stratum 0

server ntp.nict.jp iburst

 

自動再起動設定

$ sudo systemctl enable gpsd.service
$ sudo reboot

 

上記の手順で作動確認出来たRaspbianは ↓

2019-09-26-raspbian-buster-lite
2019-09-26-raspbian-buster
2020-02-05-raspbian-buster-lite
2020-02-05-raspbian-buster

ラズパイ7桁時計(自作中)の1/10秒表示とGPSの1ppsを比べてみました。

↓ 右端の7セグLEDが1/10秒で、GPSの赤LEDのフラッシュ時間も1/10秒です。

 

Stratum 1 のNTPサーバーと参照同期中のラズパイ7桁時計の1/10秒と、GPSの1PPSを比べる為に、高速度カメラ(iPhoneのスローモーション240fps)で撮影した動画です。

1/10秒単位の表示もバッチリ合っていますね。

このラズパイとGPSは繋げていません。別々に作動しています。

 

↓ ラズパイ7桁時計のソースコード

/*
 * clock2.cpp
 * 
 * 1/10秒表示テスト
 * 
 * 7桁ダイナミック表示対応
 * 時刻 08:34:27.6 の場合
 * 表示順序は 6 -> 7 -> 2 -> 4 -> 3 -> 8 -> 0
 *
 */
 
#include <iostream>
#include <pigpio.h>
#include <unistd.h>

#define H 0x1
#define L 0x0
#define COM_ON 0x1
#define COM_OFF 0x0

using namespace std;

void mainLoop(void);

int main(void)
{
    if (daemon(0, 0) == 0) { // デーモン関数
        mainLoop();
    } else {
        cout << "error" << endl;
    }
    return 0;
}

void mainLoop(void)
{    
    int i, j;
    int num[7];
    struct timespec ts;
    struct tm lotm;
		       // .1秒 1秒 10秒 1分 10分 1時 10時
	          // Common 1   2   3   4   5   6   7
    static int common[7] = {25, 24, 23, 18, 22, 27, 17};
                    // GPIO 25  24  23  18  22  27  17

	             // 7seg a   b   c   d   e   f  g   dp
    static int nanaseg[8] = {21, 20, 16, 26, 19, 6, 13, 12};
                     // GPIO 21  20  16  26  19  6  13  12

    static int segdata[12][8] = { // 7セグメントデータ
      // a  b  c  d  e  f  g  dp
	{H, H, H, H, H, H, L, L}, // 0
	{L, H, H, L, L, L, L, L}, // 1
	{H, H, L, H, H, L, H, L}, // 2
	{H, H, H, H, L, L, H, L}, // 3
	{L, H, H, L, L, H, H, L}, // 4
	{H, L, H, H, L, H, H, L}, // 5
	{H, L, H, H, H, H, H, L}, // 6
	{H, H, H, L, L, L, L, L}, // 7
	{H, H, H, H, H, H, H, L}, // 8
	{H, H, H, H, L, H, H, L}, // 9
	{L, L, L, L, L, L, L, L}, // Blank
	{L, L, L, L, L, L, L, H}, // dp
    };
    
    // pigpioライブラリ初期化
    if (gpioInitialise() < 0) exit(1);
    
    // コモン用GPIOピンをアウトプット設定
    for (i = 0; i < 7; i++) {
	gpioSetMode(common[i], PI_OUTPUT);
    }
    
    // セグメント用GPIOピンをアウトプット設定
    for (i = 0; i < 8; i++) {
	gpioSetMode(nanaseg[i], PI_OUTPUT);
    }
    
    /*
     *
     * 時刻取得及びダイナミック表示ルーチン(無限ループ)
     *
     * 時刻取得、1桁2ミリ秒表示×7、時刻取得、1桁2ミリ秒表示×7の繰り返し
     *
     */
    while (1) {
	
	clock_gettime(CLOCK_REALTIME, &ts); // 時刻の取得
	localtime_r(&ts.tv_sec, &lotm); // ローカル時間に変換
	num[0] = ts.tv_nsec / 100000000; // 0.1秒の桁取得
	num[1] = lotm.tm_sec % 10;       //   1秒の桁取得
	num[2] = lotm.tm_sec / 10;       //  10秒の桁取得
	num[3] = lotm.tm_min % 10;       //   1分の桁取得
	num[4] = lotm.tm_min / 10;       //  10分の桁取得
	num[5] = lotm.tm_hour % 10;      //   1時の桁取得
	num[6] = lotm.tm_hour / 10;      //  10時の桁取得
	
	for (j = 0; j < 7; j++) { // 7桁ダイナミック表示ルーチン

	    for (i = 0; i < 8; i++) { // 7セグメントデータセット
		gpioWrite(nanaseg[i], segdata[num[j]][i]);
	    }
	    gpioWrite(common[j], COM_ON);   // 7セグLED点灯
	    gpioDelay(2000);                // 2ミリ秒点灯維持
	    gpioWrite(common[j], COM_OFF);  // 7セグLED消灯
	}
    }
    
    // pigpioライブラリ終了処理
    gpioTerminate(); //  これは無限ループに含まれないので不要?
}
$ g++ -Wall -pthread -o clock2 clock2.cpp -lpigpio -lrt
$ sudo ./clock2

 

ラズパイをPi4からZeroに変えました。CPU使用率の変化は

Pi4:約8.0%
Zero:約10.5%

 

このプログラムの表示遅延は最大で約14.8ミリ秒(0.0148秒)、最小は限り無くゼロのはず。その理由は約14.8ミリ秒置きに時刻取得して、表示を更新しているからです。

↓ 0.1秒桁用7セグLEDのコモン端子に繋がるオンオフを、オシロスコープで観測した画像です。