日記テスト運用中

不定期に更新中。高専・学生ロボコンといったNHKロボコンネタを主に。ほかにもいろいろ。

Raspberry Piの設定メモ

exFATの外付けストレージを認識させる

高専ロボコン全国大会の動画の入ったSDカードを再生しようとして再生できなく、ファイルシステムexfatを認識できないというメッセージが出たことから気づく。
こちらよりexFAT用のFUSEパッケージ群を導入すればよいことが分かり
Raspberry Piで快適コンピューターライフ(NAS構築編)

$ sudo apt install exfat-fuse exfat-utils

exfat-fuseexfat-utilsを導入。再起動後認識できた。グラフィカル環境では装着後所定の位置に自動マウントも確認。

みちびき対応GPSモジュールから現在時刻を取得

秋月電子通商のみちびき対応GPSモジュールを接続し、GPSから現在位置と現在時刻を取得。
そして同モジュールの1PPS出力を用い、より高精度な現在時刻を取得してみます。

参考にしたページ

本体の方は初代B+、RaspbianはWheezy,Jessie、Stretchとメジャーアップデートを3回乗り越えていたりするため、最近のデバイスだと設定が違うかもしれません? 本体装備のシリアル/UARTのデバイス名が/dev/ttyAMA0であるのですが、3やZeroだと/dev/ttyS0になるようです。

使用したキットはこちら。

GPS受信機キット 1PPS出力付き 「みちびき」3機受信対応: センサ一般 秋月電子通商-電子部品・ネット通販

太陽誘電のGYSFDMAXBを搭載したGPS受信キットです。小型なのが特徴でしょうか。みちびき対応はキットの出荷時期等によってはファームウェアの更新が必要です。

これとは別に、MakerFaire Tokyo 2018の秋月電子通商ブースにて先行販売されていた

GPS/GLONASS受信機(Galileo/BeiDou可)u‐blox M8搭載 みちびき3機受信対応: センサ一般 秋月電子通商-電子部品・ネット通販

u-blox M8搭載のこちらのモジュールを使ったことがあるのですが、どうもVccが5Vだとうまく起動してくれない? あるいは自分の確認不足があり上手く動かすことができず(スイッチサイエンス製のUSBシリアルコンバーターにおいて、シリアル側Vccが5Vでは動かず、ジャンパピンで3.3Vにレベルすると動く)、今回は前述のモジュールを用い動かします。

本体GPIOのシリアルをシリアルコンソールから汎用的に使えるシリアルにする

本体GPIOのシリアルが、ログイン可能なシリアルコンソールに割り振られているのを無効にします。

raspi-configで

raspi-config の Interfacing Options の Serial から、シリアル経由でのログインシェルとしての利用をNo、シリアルポートのハードウェア機能を有効にするかの質問でYesを回答。そして再起動。

直接変更する

あるい関連する設定ファイルの直接修正とシリアルコンソールログイン用のgettyを無効にする方法です。

/boot/cmdline.txtを次のように修正

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait
# dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 console=ttyAMA0,115200 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait

2行目は変更前の内容を残したコメント行です。ポイントはconsoleやkgdbocからttyAMA0および速度設定を外すことです。
そして/boot/config.txtに次のエントリを追加

enable_uart=1

シリアルコンソールの代わりに、本体の該当するピンを汎用的なUARTにします。

続いてシリアルコンソールのgettyを無効に。下記はinitやサービスがsystemdベースのシステムの場合です。

$ sudo systemctl stop serial-getty@ttyAMA0.service
$ sudo systemctl disable serial-getty@ttyAMA0.service
$ sudo systemctl status serial-getty@ttyAMA0.service
● serial-getty@ttyAMA0.service - Serial Getty on ttyAMA0
   Loaded: loaded (/lib/systemd/system/serial-getty@.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:agetty(8)
           man:systemd-getty-generator(8)
           http://0pointer.de/blog/projects/serial-console.html

シリアルコンソールの無効化を行ったら、シャットダウン。GPSモジュールと結線して、電源を入れなおすことになります。

GPSキットを結線する。

Raspberry PiのHATピンの右上は2番ピン、長辺方向にまっすぐ偶数番号のピンが続きますが、

  • 4番 VCC 5V
  • 6番 GND
  • 8番 BCM14 / TXD
  • 10番 BCM15 / RXD
  • 12番 BCM18 / PWM0

ときれいに並んでいます。そしてGPS受信キットのピン出力は

  • 5V
  • GND
  • RXD
  • TXD
  • 1PPS

と、簡単に繋げられる組み合わせになっていますので、幅5ピンのフラットケーブルやGPSキット側をボックスコネクタにしたりして、直結させます。

ですので12番ピン BCM18を1PPS入力とすることになります。

GPSキットからのデータ送信を確認。

GPSキットを接続して電源を入れたら、GPSキットの受信LEDが赤く点灯することを確認します。なおGPS衛星群の受信が完了し現在位置の確定・ロックとなりますと1秒ごと明るく点灯します。
何らかの方法で汎用シリアルポートへのアクセスと、読みだしてモジュールから送信されてくるか確認します。たとえば

sudo cat /dev/ttyAMA0

など。GPSモジュールが正しく接続されていれば、おおよそ1秒毎に$で始まるメッセージが飛び続けてくるはずです。

gpsdの導入と設定

シリアルポート等に接続されているGPS機器を、複数のプロセスが奪い合うことなく共用できるような仕組みとNMEA 0183出力より扱いやすいフォーマットにするのがgpsdデーモンの役割です。導入後はローカルのTCPの2467番ポートから各プロセスがGPS情報を包括的に照会できるようになります。

まずはパッケージの導入。gpsd、gpsd-clients、そしてこのあとの1PPS入力のためにpps-toolsをインストール。

sudo apt install gpsd gpsd-clients pps-tools

gpsdの設定を /etc/defaults/gpsd に次の記述をします

DEVICES="/dev/ttyAMA0"
GPSD_OPTIONS="-n"

GPS機器が接続されている先と、gpsdのオプションを指定します。設定が終わったら、gpsdを開始させます。

$ sudo systemctl start gpsd.socket

gpsdが取得したGPSの状態は、

gpsmon
cgps -s

などのコマンド、オプションで確認できます。どちらも「q」コマンドないしは「q」+Enterで終了します。
cgps -s を行った結果が次のような感じとなります。(注: 1PPS入力接続後となります)

lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqklqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
x    Time:       2018-12-01T  :  :  .   Z   xxPRN:   Elev:  Azim:  SNR:  Used: x
x    Latitude:              N               xx 193                 19      Y   x
x    Longitude:             E               xx   2                 27      Y   x
x    Altitude:     .  m                     xx   6                 29      Y   x
x    Speed:      0.7 kph                    xx 129                 28      N   x
x    Heading:    315.1 deg (true)           xx   5                 26      Y   x
x    Climb:      0.0 m/min                  xx 195                 25      Y   x
x    Status:     3D FIX (5 secs)            xx   7                 17      Y   x
x    Longitude Err:   +/- 6 m               xx   9                 18      Y   x
x    Latitude Err:    +/- 8 m               xx  13                 18      Y   x
x    Altitude Err:    +/- 4 m               xx  30                 23      Y   x
x    Course Err:      n/a                   xx  19                 25      Y   x
x    Speed Err:       +/- 57 kph            xx  29                 17      N   x
x    Time offset:     1.070                 xx 194                 00      N   x
x    Grid Square:     PM95rr                xx                                 x
mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqjmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

座標等は消しています。右のリストが受信した衛星のリストですが、一番上のPRNが193の衛星がみちびき初号機(QZS-1)となります。他に受信できているみちびきはPRNが195が該当します。対応ファーム効果が分かります。

正しくgpsdが動くようでしたら、起動時から動くよう有効にしましょう

$ sudo systemctl enable gpsd.socket
1PPS入力に対応する

利用したモジュールはPPS出力を持つので、1PPS入力のピンを定義、gpsd側もそれを認識させて精度を高めてみることにします。

まずは/boot/config.txtについて、UARTの有効化の記述の直後のあたりにでも、pps-gpioを有効にする記述と、pps-gpioに与えるパラメータ2つ(gpiopinとassert_falling_edge)を記述して設定します。ここで注意なのは後者のパラメータの側。

enable_uart=1
dtoverlay=pps-gpio
dtparam=gpioin=18
dtparam=assert_falling_edge=true

assert_falling_edgeをtrueにすることで、1PPS入力について下りエッジで反応するようにしています。今回用いた太陽誘電製のGPSモジュールは、アクティブローの端子であるためこのような設定となっています。同モジュールのPPS出力は、1秒ごとに100msほどアクティブロー状態となる動作であります。最初この設定を忘れていたために、後に誤差を確認する際NICTのサーバ群と100msほど確実にずれてしまうという事象に陥ることになりました。

gpiopinパラメータの値は各自のPPS出力がどこのGPIOに繋がっているかに応じて適宜変更してください。

1PPS入力に対応後gpsmonを実行すると、ちゃんと捕捉及びPPS信号が受け取れていれば、UART出力のダンプの合間に次のような出力が観測できるはずです。

------------------- PPS offset: -0.004157428 ------
 ------------------- PPS offset: -0.004157428 ------

画面上部のHUD部分について、下部にPPSの項目も出現します。

│PPS:  0.000139707           │
└──────── GSA + PPS ─────────┘
ntpdと接続して正確な時刻ソースにする

(以下続く)