Intel EdisonでAdafruit Ultimate GPSを使う

以前にRaspberry Pi用に購入したAdafruit Ultimate GPSがあったので、Edisonで使えないか試してみました。

GPSのモジュールは小さく1円玉ぐらいのサイズです。

外付けのアンテナも取付可能ですが、これ単体でも小さいアンテナが付いているので、GPSの信号を受診することが可能らしい。
(Raspberry Pi用に買ったけど、一度も使ったことがない)

Edisonとの接続ですが、せっかくUSB OTGに対応しているので、GPSモジュールとUSBでつなげようとしたけど、うまく出来ずに断念しました。

次に、EdisonはUART(Universal Asynchronous Receiver Transmitter)の入出力のbreakout boardピンにも配置されているので、そっちに接続して試してみることに。

GPSのモジュールは3.3v〜5vの電源で駆動するので、手っ取り早くUSBから5vを取ってGPSモジュールに印加します。

GPSモジュールのRXをEdisonのJ19 - pin 8 GP131 UART1_TXにつなぎ、TXをJ18 - pin 13 GP130 UART1_RXにつなぎます

GPSモジュールに電源をつなぐと、赤いLEDが点滅し始めます。
GPSの信号を受信できている状態で/dev/ttyMFD1をcatしてみるとズラズラとデータが出力されてくるのが確認できます。

次にnodejsでこのデータを読み取れるように、受信したデータをログ出力するだけのスクリプトを書きます。
(Adafruitが公開しているGPSのライブラリはC++で書かれているのですが、Cで書くのも辛いのでnodejsであればserial通信用のライブラリもあるし、JavaScriptで進めたいと思いました。)

var SerialPort = require("serialport").SerialPort;
var port = "/dev/ttyMFD1";
var serialPort = new SerialPort(port, {
  baudrate: 9600
}, false);

console.log("Open port: "+ port);
serialPort.open(function (error) {
  if (error) {
    console.log('Failed to open: '+error);
  } else {
    console.log('open');
    serialPort.on('data', function(data) {
      console.log('data received: ' + data);
    });
  }
});

このスクリプトを実行すると、、

root@sparkgene-edison:~/node_gps# node reader.js
Open port: /dev/ttyMFD1
open
data received: $GPGGA,030937.000,3500.2796,N,13900.6471,E,1,07,1.29,43.9,M,39.3,M,,*57
$GPGSA,A,3,15,13,29,05,193,02,30,,,,,,1.54,1.29,0.85*37
$GPRMC,030937.000,A,3500.2796,N,13900.6471,E,0.28,322.35,240115,,,A*63
$GPVTG,322.35,T,,M,0.28,N,0.51,K,A*36

data received: $GPGGA,030938.000,3500.2797,N,13900.6471,E,1,07,1.29,43.9,M,39.3,M,,*59
$GPGSA,A,3,15,13,29,05,193,02,30,,,,,,1.54,1.29,0.85*37
$GPRMC,030938.000,A,3500.2797,N,13900.6471,E,0.18,221.91,240115,,,A*62
$GPVTG,221.91,T,,M,0.18,N,0.33,K,A*3D

data received: $GPGGA,030939.000,3500.2797,N,13900.6470,E,1,07,1.29,43.9,M,39.3,M,,*59
$GPGSA,A,3,15,13,29,05,193,02,30,,,,,,1.54,1.29,0.85*37
$GPRMC,030939.000,A,3500.2797,N,13900.6470,E,0.43,243.74,240115,,,A*63
$GPVTG,243.74,T,,M,0.43,N,0.79,K,A*32

お〜、なんか受信できてるけどさっぱりわからんww

で、Adafruitのライブラリを読んでると、GPGGAとかの文字からパース処理をしているのがわかったので、ググってみるとGPSのモジュールからはNMEAというフォーマットでデータが出力されるとのことでした。

なるほど。
ということはJavaScriptで受信したデータをフォーマットに合わせてパースすれば人にやさしいデータに変換できるということ。
そんなわけで、まだ一部分のやっつけ的なソースですが、パースする処理を書いてみました。
https://github.com/sparkgene/node_gps/blob/master/gps_reader.js

このソースを使って、もう一度受信しているデータをパースしてみると、、

root@sparkgene-edison:~/node_gps# node gps_reader.js
Open port: /dev/ttyMFD1
open
Time(UTC): 6:38:57.0
Status: A
Latitude: N 35.001221666666665
Longitude: E 139.00406666666667
Time(UTC): 6:38:58.0
Status: A
Latitude: N 35.00122
Longitude: E 139.00406833333334
Time(UTC): 6:38:59.0
Status: A
Latitude: N 35.00122
Longitude: E 139.00406833333334
Time(UTC): 6:39:0.0
Status: A
Latitude: N 35.00122
Longitude: E 139.00406833333334
Time(UTC): 6:39:1.0
Status: A
Latitude: N 35.00122
Longitude: E 139.00406666666667
Time(UTC): 6:39:2.0

緯度経度が見やすくなりました。
上記のデータは一部書き換えているのであれですが、実際にキャプチャーできたデータをgoogle mapで見てみると、10m以内ぐらいの誤差でばっちりと現在地を表示しました。

室内で試したので、屋外に出たり、アンテナを繋いだらもっと精度は高くなるかも。