Edison + Adafruit Ultimate GPSでGPSデータを取得する

EdisonにAdafruit Ultimate GPSを接続してGPSデータを取得した際の作業メモ。

Ultimate GPSからのGPS情報取得は、AdafruitがC++で用意したライブラリもありますが、
他の情報からnode.jsのserialportで取得可能そうだったので、node.jsで取得します。

# 用意したもの

- Intel Edison Kit for Arduino(Intel Edison + Intel Edison Board for Arduino)
- [Adafruit Ultimate GPS](https://www.adafruit.com/product/746)
- ブレッドボード

最終形態はこんな感じになります。

![IMG_3776.JPG](https://qiita-image-store.s3.amazonaws.com/0/19870/881ded5b-6cfc-e229-db8f-134f666e61d7.jpeg)

※なお、Intel Edison Kit for Arduinoの組み立て部分のお話は割愛します
※Adafruit Ultimate GPSは、購入時にピンヘッダが付属していました。はんだ付けして用意しています。

# EdisonとUltimate GPSの接続

下記の通り、それぞれ接続します

|Ultimate GPS側|Edison側|
|:-----------|:-----|
|VIN|POWER 5V|
|GND|POWER GND|
|RX|DIGITAL TX|
|TX|DIGITAL RX|

Ultimate GPSのVINは 3.0-5.5VDC。Arduinoボードから電源が取れて便利！

# Node.jsの準備

## 仕様概要
データ取得については、下記のような仕様で取得します

- シリアル通信によりデータを取得する → serialportを使用
- Ultimate GPSのoutputは[NMEA 0183](https://ja.wikipedia.org/wiki/NMEA_0183) → パースにnmea-0183を使用

## npmでserialportとnmea-0183のインストール

npmでインストール

- [npmjs: serialport](https://www.npmjs.com/package/serialport)
- [npmjs: nmea-0183](https://www.npmjs.com/package/nmea-0183)

```
# npm install searialport nmea-0183
```

## 取得用プログラム

```js:read_gps.js
var com = require("serialport");
var nmea = require("nmea-0183");

var port = "/dev/ttyMFD1"; //シリアル通信での取得元
var baudrate = 9600; ///製品仕様で確認
var line_end = '\r\n';

var serialPort = new com.SerialPort(port, {
	baudrate: baudrate,
	parser: com.parsers.readline(line_end)
});

serialPort.on('open', function(err) {
	if(err) {
		console.log('serialPort: error');
	} else {
		console.log('serialPort: open');
		
		serialPort.on('data', function(data) {
			try{
				var gps = nmea.parse(data);

				console.log('-----------' + gps['id']);
                                console.log(data);
				console.log(gps);
			}catch(e){
				console.log(e);                 
			}   
		});                              
	}
});
```

# GPS情報の取得

Edisonに電源を入れて、いざ取得！

## Ultimate GPSの動き
電源が入れば、基盤に備え付けのLEDが点滅します。

- 細かい点滅をしている間はGPSの衛星を探している状態で1秒ごとに1回点滅
- 衛星をとらえて、データが取得できる状態になると15秒ごとに1回点滅

最初にEdisonに電源を入れた際、ずっと1秒に1回の点滅でした。
失敗したかなと思ってEdisonをrebootすると、今度は数10秒すると点滅の間隔が開く状態になりました。
なぜそうなったかは、まだよくわかりません。

## プログラム起動してデータ取得

node.jsでデータを取得します。（緯度・経度はxで潰しています。）

```
# node read_gps
Open port: /dev/ttyMFD1
serialPort: open
-----------GPGGA
$GPGGA,163714.000,xxxx.xxxx,N,xxxxx.xxxx,E,1,06,2.10,34.5,M,39.3,M,,*56
{ id: 'GPGGA',
  time: '163714.000',
  latitude: 'xx.xxxxxxxx',
  longitude: 'xxx.xxxxxxxx',
  fix: 1,
  satellites: 6,
  hdop: 2.1,
  altitude: 34.5,
  aboveGeoid: 39.3,
  dgpsUpdate: '',
  dgpsReference: '' }
-----------GPGSA
$GPGSA,A,3,21,27,26,08,09,16,,,,,,,2.27,2.10,0.87*0D
{ id: 'GPGSA',
  mode: 'A',
  fix: '3',
  sat: [ '21', '27', '26', '08', '09', '16' ],
  pdop: 2.27,
  hdop: 2.1,
  vdop: 0.87 }
-----------GPRMC
$GPRMC,163714.000,A,xxxx.xxxx,N,xxxxx.xxxx,E,1.02,33.23,171215,,,A*59
{ id: 'GPRMC',
  time: '163714.000',
  valid: 'A',
  latitude: 'xx.xxxxxxxx',
  longitude: 'xxx.xxxxxxxx',
  speed: 1.02,
  course: 33.23,
  date: '171215',
  mode: '',
  variation: NaN }
-----------GPVTG
$GPVTG,33.23,T,,M,1.02,N,1.88,K,A*0E
{ id: 'GPVTG', course: 33.23, knots: 1.02, kph: 1.88, mode: 'A' }

(以下省略)
```
GPGGA or GPRMCの値で緯度(latitude)・経度(longitude)が取れています。

# 参考サイト

- http://pacenotes.jp/node_gps/
 - 受信プログラムについて、参考にしました。
- http://sparkgene.hatenablog.com/entry/20150127/1422368655
 - Arduinoを使用しないパターン。GPS情報のパースを自力でやってらっしゃる。
- http://piyajk.com/archives/302
- http://www.spa-japan.co.jp/tech_old/GM38m5.html
 - NMEAの内容について説明されている。