こんにちは。ロビットの望月です。
だんだん暖かくなってきて春を感じている今日この頃でございます。
皆様はいかがお過ごしでしょうか。
こちら帰り道でふと見上げたら桜が咲いていたので思わず撮ってしまいました。
いわゆる夜桜でございます。そして相変わらず写真を撮るのが苦手です。
さて今回はRaspberry PI 3 Model BでGPSモジュールを使ってみたので、それについて少し話せればと思います。
ハードウェア
SBC(Single Board Computer)の代表格とも言えるラズパイですが、Amazonでもプライムで販売してたりして、欲しいと思ったらすぐに手に入る時代になりました。実店舗だと秋葉原にある秋月電子で取り扱ってたかと思います。
そして、その時代の流れに乗って早速ポチりました。
専用ケース付のものが出回っているので、大好きなブラックを選んでみました。この中にボードが入ってます。かっこいぃ。
本来ならラズパイ用のケースでしたらロビットでも作れてしまいますが、価格もあまり変わらなかったので今回は手を抜きます。
あとはGPSモジュールですが、性能などによって価格が結構ばらつくようです。
とりあえず動く程度で良かったので、同じくAmazonで販売されているこちら(NEO-6M)にしてみました。
価格は1000円ほどで、ボードにつながっている黄色の四角い物体がアンテナになります。
衛星から発信されている情報をこのアンテナで取得し、ボード上のチップで処理が行われて、RS232でのシリアル通信にてGPS情報が出力されてくるようです。
今回はラズパイに取り付けてしまいたかったので、はじめに適当な箇所にドリルで貫通穴を開けます。
そして、アンテナはケース内に入れてしまうと感度が悪くなるので、取り急ぎ外側に両面テープで固定してしまいました。
次に、GPSモジュールの基板に【VCC、GND、RX、TX】の4ピン取り付ける箇所があるので、それぞれピンヘッダをハンダ付けします。そのあとは単純にラズパイ側のピン配置を確認して配線するだけです。GPSモジュールのVCCは3V~5VでOKとのことなので、ラズパイから3.3Vを供給しておきました。
こんな感じになりました。
ちなみにこのGPSモジュールにはEEPROM(不揮発性メモリ)がついており、設定情報を保持しておくようになっています。またバックアップ用の豆電池もついているのですが、へたっていることが多いらしく、取り換えが必要な場合もあるようです。
配線できたら先ほど開けた穴を使ってネジで固定します。
この時に表に取り付けたアンテナも基板に接続しておきます。
ハンダ付けした箇所が汚いですが、そこはご愛敬ということで。。。
簡単ですが、これにて完成。
ソフトウェア
続いて接続したGPSモジュールからデータを取ってきたいと思います。
まずOSをインストールします。
ラズパイが対応しているOSは色々ありますが、手持ちが8GBのSDカードしかなかったこともあり、安牌を取ってRaspbianのLite版を入れました。
インストール手順については検索すれば山のように出てくるのでここでは省きます。
その後、必要に応じて以下諸々の作業を行います。
これらの手順ついてもググれば必ず出てきますので省略します!
また今回プログラムをNode.jsで書きたかったので、こちらもインストールしておきます。
そして重要なのがシリアルポートの設定になります。
上でも書きましたがGPSモジュールからはシリアル通信でデータをもらえるので、ラズパイ側で動くNodeプログラムでもシリアル通信ができるようにしておく必要があります。
インストールコマンドは以下です。
npm install serialport
ただし、Raspberry Pi 3にはシリアル通信に使うUARTがBluetoothに割り当てられてしまっており、インストールしただけでは使えないようなので、以下記事を参考にさせていただき、RX・TXピンに割り当てられるように設定を行います。
http://qiita.com/yamamotomanabu/items/33b6cf0d450051d33d41
これで環境が整いました。早速プログラムを書いてみます。
sample.js
var serialPort = require('serialport'); var sp= new serialPort("/dev/ttyAMA0", { baudrate: 9600, dataBits: 8, parity: 'none', stopBits: 1, flowControl: false, parser: serialPort.parsers.readline("\n") }); sp.on('open', function (err) { console.log('serialPort: Port open'); }); sp.on('data', function (data) { console.log('serialPort: data received = ' + data); });
データを取ってくるだけでしたらコードはこれだけで十分です。
このjsファイルをラズパイ内の適当な場所に保存して下記コマンドを叩きます。
(Tera TermでSSH接続して実行しています)
node sample.js
コマンドラインでこのように表示されれば正常です。
ただここで表示されるデータですが、パッと見ではよく分からないものになっています。
(もともとモザイクされてて分からないかと思いますが…)
一般にGPSデータには緯度・経度の情報が含まれており、これによって地球上のどの位置にいるのかがわかります。しかし、GPSモジュールからはNMEAフォーマットと呼ばれる形でデータが送られてくるので、そのままでは高校の時に地理の授業で習うような「°」で表記された形になっていません。そのため少々変換する必要があります。
// 一部追加 sp.on('data', function (data) { if (data.indexOf('$GPRMC') !== -1) { gpsData = parse(data.split(',')); } console.log('latitude= ' + gpsData.latitude + ', latitude= ' + gpsData.longitude); }); // 追加 function parse(data) { var latitude = 0; var longitude = 0; [f:id:robit-inc:20170410112310p:plain] var lat = data[3].split('.'); var lat_deg = parseFloat(String(Math.floor(lat[0] / 100))); var lat_min = parseFloat(String(lat[0] % 100) + "." + lat[1]); latitude = lat_deg + (lat_min / 60) var lng = data[5].split('.'); var lng_deg = parseFloat(String(Math.floor(lng[0] / 100))); var lng_min = parseFloat(String(lng[0] % 100) + "." + lng[1]); longitude = lng_deg + (lng_min / 60); return { latitude, longitude }; }
先ほどのコードを上記のように変更すると以下のような結果になり、ちゃんと「°」で表記された緯度・経度情報になっていることがわかります。
これでラズパイでGPS情報を取得することが無事にできました。