RaspberryPi[8] ラズパイにGPSを接続してNTPサーバーにする。

USB GPSの接続

ラズパイにUSBのGPSを接続してみます。使用するGPSは UbloxのGPSです。UbloxはU-centerというソフトがありますが、Windows版しかないようなので、当面はコンソール使用して、そのうちプログラム化するつもりです。

まずは、USBにGPSを指して、

lsusb とたたいて、USBの接続を確認します。こんな感じです。

$lsusb

BUs 001 Device 003: ID 1546:xxxx U-Blox AG u-block GNSS receiver

GPSとデバイスと通信する gpsd デーモンがあるようなので、まずはこれをインストールします。

$sudo apt-get install -y gpsd gpsd-clients

$sudo gpsmon

で、GPSのデータが表示されます。どうも、tcp://localhost:2947 とも出るので、これでアクセスができるのかなと。

DEVICEも表示されてました。私の場合は、/dev/ttyACM0 でした。

gpsd の自動機能

/etc/default/gpsd を修正します。

DEVICES="/dev/tty/XXXX" 私の場合は、/dev/ttyACM0

GPSD_OPTIONS="-N -F /var/run/gpsd.sock -b -n"

あとは修正なしで。

gpsdの自動起動を有効にする

$sudo systemctl enable gpsd

NTPサーバーの構築

NTPサーバとしてchronyをインストールします。

$ sudo apt-get install chrony

/etc/chrony/chrony.conf の設定 GPSを使うときに下記追記が必用

refclock SHM 0 refid GPS offset 0.05

chronyサービスの自動起動有効

$ sudo systemctl enable chrony

時刻同期の確認

$ chronyc sources -v

USBから読むCプログラム

ここのコードを参考にしました。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

#define SERIAL_PORT "/dev/ttyACM0"

int main(int argc, char *argv[])

{
    unsigned char buf[255];
    int fd;                          
    struct termios tio;       
    int baudRate = B9600;
    int i;
    int len;


    fd = open(SERIAL_PORT, O_RDWR); 
    if (fd < 0) {
        printf("open error\n");
        return -1;
    }

    FILE *rp = fopen("log.txt", "w");

     if (rp == NULL) {
        perror("ファイルを開けませんでした。");
     return 1;
    }


    tio.c_cflag += CREAD;               // 受信有効
    tio.c_cflag += CLOCAL;              // ローカルライン(モデム制御なし)
    tio.c_cflag += CS8;                 // データビット:8bit
    tio.c_cflag += 0;                   // ストップビット:1bit
    tio.c_cflag += 0;                   // パリティ:None

    cfsetispeed( &tio, baudRate );
    cfsetospeed( &tio, baudRate );

    cfmakeraw(&tio);                    // RAWモード
    tcsetattr( fd, TCSANOW, &tio );     // デバイスに設定を行う
    ioctl(fd, TCSETS, &tio);            // ポートの設定を有効にする

    // 送受信処理ループ

    while(1) {
        len = read(fd, buf, sizeof(buf));
        if (0 < len) {
            for(i = 0; i < len; i++) {
                printf("%c", buf[i]);
                fprintf(rp, "%c", buf[i]);
            }
        }
    }

    fclose(rp);                              // デバイスのクローズ
    close(fd);      
    return 0;
}