macでシリアル通信

シリアル通信はいつもはFreeBSDを使っているのですが,そのためだけにシリアルポートがついていてFreeBSDをインストールしたPCを持って歩くのもちょっとつらいものがあるので,普段持ち歩いているMacBook Airで使えないかどうか調べてみました。

まずusb-serial変換ケーブルが必要です。

これは手元の道具箱を漁ったらなにかケーブルが出てきました。メーカー名も型番も何も書かれていないケーブルでしたので,チップがなにかもわかりません。そこらに転がっていたらWindows 10のPCに差してデバイスマネージャを見たらProlificなんちゃら,と書かれていましたので,ProlificのPL-2303だろうとあたりをつけます。

チップメーカーのサイトにドライバが落ちているので落としてきてインストールします。古いMacBook Airでいまだに10.6.8 (snow leopard)を使っているので,対応するファイルを落とします。

展開してドライバをインストールして再起動します。

その後,usb-serial変換ケーブルをusbポートに突っ込みます。すると,/dev/tty.usbserialというデバイスファイルが現れますので,これを使えばシリアル通信ができるようになります。

もっとも安直な通信方法はscreenコマンドを使います。コンソールから

screen /dev/tty.usbserial 9600

とかすると通信が出来ます。終了は,c-A c-\です。

また,Macからはenterキーを叩いてもCRしか送れないのでLFを送る必要があるときはCtrl-jで送ります。
CR+LFを送るにはenterキーをたたいてからCtrl−jです。

意外に簡単です。GPSのNMEAセンテンスが表示されるかどうか,適当なGPS端末と接続してみましたが問題なく表示されています。

LFの送信に思い切りはまりましたが,これで仕事に使えそうです。

Raspberry Pi 2でntpサーバー(5) 時刻合わせ編

Raspberry Piは電源が切れると時計が止まってしまって、再起動時には最後に電源を落としたときの時刻から時計が再開されます。そうすると電源が切れている期間が長いと、ntpdがGPSに同期するのを諦めてしまいます。これを避けるためには電池でバックアップされたハードウェアクロックを入れるしかないわけですが、とりあえずdateコマンドでどうにかならないか、と試してみました。

まず、dateコマンドの使い方から。時刻を2016年10月30日20時15分にあわせるためには、

sudo date -s "10/30 20:15 2016"

とやります。これだけでOKです。

どういう動作をしているのかよくわかりませんが、RPiの内蔵時計の時間が大きく狂っているとそもそもGPSをロックしないようです。いつまで放っておいても受信せず、FIXとシルク印刷されている赤色LEDが点滅を続けます(ちゃんとGPSにロックしたらLEDは消灯します)。

dateこまんどでほぼ正しい時刻を与えればとりあえずntpdもGPSに同期をしようとするようです。

たぶん、これで、スタンドアロンでもどうにか使えるのではないか、という気がしてきました。道のりは長い...

ThinkPad 240Zでntpサーバー(4)

ThinkPad 240Zでntpサーバーを作る話はずいぶん前(5年も前!)に少し書いていますが、このときは、Garmin GPS 18LVCを使っていました。18LVCのシリアル通信の速度は4800bpsでした。

その後、いろいろあって、ebayあたりでよく売られている中古のOCXOを入れたGPSDOを買ってみたのでこれを使ってntpサーバーにしてみようと考えました。このGPSDOは10MHz、1ppsをBNC端子からそれぞれ出力し、さらにRS-232で、NMEAのセンテンスと1ppsを出力する、という素敵な仕様です。シリアルからのデータをFreeBSDに入れればすぐにNTPサーバーができるじゃないか、というのがそのこころです。

この機械のRS-232は2pin=TX, 3pin=RX, 8pin=PPSの9pinのメスのシリアルコネクタです。普通はオスじゃないか、と思うのですが、下手にピンがでていてショートしたら危ない、と考えたのかもしれません。そこでまずはケーブルを作るところから始めなくてはなりません。

とりあえず、手元のメス-メスのシリアルケーブルを途中でぶった切って、片側のコネクタはそのまま240Zに接続するために使います。切り口からケーブルを出してみるとなぜか5本はいってました。全線結線じゃないんだぁ、と思いつつ、2-->2, 3-->3, 8-->1 (GPSDO --> 240Z)となるようにつないでフレームグラウンドはとりあえず気がつかなかったことにしてGPSDOと240Zを接続します。

240Zの環境はFreeBSD 8.2R, ntpdは4.2.4p5がインストールされていました。また、GPSDOのRS-232は9600bps, 8bit, non-parity, 1 stop bitというごくありふれた設定です。また、GPSモジュールはublox NEO 6M 0-001が入っているようです。

1. /etc/ntp.confの設定
ntpdは4800bpsがデフォルトなので9600bpsで接続しなくてはなりません。OS標準のものは接続速度を変えられませんが、あとからコンパイルしてインストールしたntpdは変えられるバージョンです。どうやって変えるのか悩みましたが、Generic NMEA GPS Receiverのマニュアルを見るとドライバの設定が書いてあります。

どうやら、serverにmodeオプションをつければよいようです。mode 0がデフォルトで4800bps, mode 16が9600 bps, mode=32が19200bps, mode=48が38400, mode=64が57600, mode=80が115200と書いてあります。ですので、mode 16と書けばよいのでしょう。

あと、ppsとnmeaセンテンスのタイミングのオフセットを設定しなくてはなりません。Garmin 18LVCは同じタイミングで両者が出力されるようですが、ublox neo 6mはそうでもないようです。オシロで見ると、確かにppsの立ち上がりのあと60msほどしてからTXから信号が来ているようです。これくらいだと気にしなくてよいような気もするのですが...。

というわけで、ntp.confは
server 127.127.20.1 mode 16 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.1 flag1 1 flag3 1 time2 0.06 refid GPS
としました。

2. ntpdの起動
/etc/rc.d/ntpd start
としてntpdを起動します。ところがなぜかちゃんと時計が同期しません。ntpq -pで見るとwhenがpollを越えてやたら大きくなっていてreachの値が増えません。

ntpdをいったん止めて、
jerm -b 9600 /dev/gps1
とやって見ているとコンソールにnmeaセンテンスが流れてきます。しかし、すぐには流れてこないのです。どうもしばらく待たないとセンテンスが送られてきません。いろいろ調べてみると、このGPSDOはrunというLEDインジケータが点滅しているときはnmeaセンテンスを出力しているのだけれども、これが消灯するとppsは出しているけれどもnmeaは出力していないらしい、ということがわかって来ました。そして、jermでセンテンスを見るだけなら問題ないのに、ntpdで接続すると突然runのLEDが消灯してしまうことに気がつきました。

これはなんとも困ったことです。そこで、GPSDO側のRXを外してみました。要するに3pinを物理的にはずしてしまったということです。こうすれば、PC側からntpdが何か変な信号を送ってもGPSDOは気がつかないままにデータを垂れ流してくれるだろう、というわけです。

案の定、3pinを外したら普通に動き始めました。素晴らしい。

3. 1秒狂う!
これでOKかと思っていたのですが、ふと思い立って、別のPCからntpdateをやってみたところ、なぜかきっちり1秒ずれることがわかりました。このPCは研究室のntpサーバーに同期していて研究室のntpサーバーはGarmin 15tmという商品名で国内で売られているGarmin 15Lというモジュールから出力されるppsに同期しているstratum 1のntpサーバーです。Garmin 15Lはppsとnmeaセンテンスのオフセットはないことになっているのでたぶん時刻は正しいと思われます。ublox 6mがどうなのかまったくわからないのですが、ntpdateで研究室のntpサーバーとGPSDO由来の240Zに交代で接続してみました。つまり、
/usr/sbin/ntpdate 192.168.x.yyy
/usr/sbin/ntpdate 192.168.x.zzz
とやったということです。すると240Zのほうが正確に1秒進んでいます。どちらが正しいのかはなんとも言えませんが、15Lを信じることにして(根拠なし)、ubloxのほうに1秒のオフセットを与えることにします。

ntp.confのfudgeにtime2の値を-1.0にしてみました。
server 127.127.20.1 mode 16 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.1 flag1 1 flag3 1 time2 -1.0 refid GPS

これでなんとか同じ時刻を示すようになった...ような気がします。こんな感じ。

/usr/sbin/ntpdate 192.168.x.yyy
21 Oct 10:27:35 ntpdate[13882]: adjust time server 192.168.x.yyy offset -0.000048 sec
/usr/sbin/ntpdate 192.168.x.zzz
21 Oct 10:27:37 ntpdate[13883]: adjust time server 192.168.x.zzz offset 0.000016 sec

こういう状況でのオフセットの設定はtime1ではなくてtime2で設定すればよいようです。でも,同期するまでかなり時間がかかります。うーむ。

あとからもうちょっと考えてみたのですが、ひょっとしたらGarminのGPSモジュールって最近のうるう秒に対応していなかったりするのかもしれません。ちゃんと調べて見ないといけませんが、もしそうだとすると、Garmin 15Lのほうが1秒狂っていることになります。もう、何を信じていいのかわからなくなってきました。

gpsdo.jpg