読者です 読者をやめる 読者になる 読者になる

twitterよりちょっと長いの

せっかくだから書き残すよ。

Raspberry Piで経度緯度を測る

Raspberry PiでGPSを使って経度緯度を測ります。
ちなみに私には電子工作の知識はない。いいね?

準備編

部品の接続

まず、GPSの電波を受信するために新しく部品が要ります。
私は以下の「u-blox GPSモジュール」を使いました。使ったRaspberry Piはtype A+です。www.aitendo.com

基本的にこちらの方の記事に習って作業を進めて、GPSの電波を受信しました。

互いの端子の接続は以下のとおりです。

  • uBlox -> Raspberry Pi
  • GND -> GND
  • TX -> RX(GPIO 15)
  • RX -> TX(GPIO 14)
  • VCC -> 5V

なお、GPSモジュールは窓際とか家の外とか電波を受信できそうなところに設置する必要があります。
電波を受信できていたらモジュールの(青い基板についている)緑色のLEDが点滅します。
私は自宅に引きこもって作業していたので電波を全然受信できなくて数日無駄にしました。
窓際には置いてたんだけどね。家の外に出したら受信できるようになりました。家の外に出よう。

設定ファイルの書き換え

設定ファイルも書き換える必要があります。

  • /boot/cmdline.txtの「console=ttyAMA0,115200」の部分を削除
  • /etc/inittabの「T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100」 の行をコメントアウト

その後、再起動します。ファイル書き換え間違えるとOS立ち上がらなくなります。気をつけましょう。
立ち上がらなくなった?焦らないで。レスキューモードとかで書き換えたファイルを元に戻してやれば大丈夫です。

ソフトウェアのインストール

gpsdとクライアントをインストールします。

sudo apt-get install gpsd gpsd-clients

その後、以下のコマンドを実行します。

stty -F /dev/ttyAMA0 9600
sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock
cgps -s

すると、こんなかんじの画面が出てきます。ヤッター!
f:id:AIN0204:20150830231846j:plain
ここで出てきた経度(Longitude)と緯度(Latitude)をGoogle Mapにでも入力してやるとこの数字がどの位置を表しているか確認できると思います。僕はかなりいい精度で自宅の自室を指していました。

上手くいかないんだけど?

ここで「うまく位置情報が取れないよ」という方は以下を確認してみてください。

  • GPSモジュールの接続とRaspberry Piとの接続はあっているか
  • GPSモジュールの緑のランプは点滅しているか
  • GPSモジュールは電波を受信できる環境にあるか
  • 最近、屋外に出ているか

プログラミング編

Pythonを使って経度緯度を読み取ります。
先ほどと同様に以下のページを参考にコードを書きました。
Nerd Inc.: Demystifying the uBlox 6 GPS Module

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import serial
from pynmea import nmea

ser = serial.Serial('/dev/ttyAMA0',9600)
gpgga = nmea.GPGGA()

gpsLat = -1
gpsLong= -1

data = ser.readline()
if (data.startswith('$GPGGA')):
    gpgga.parse(data)
    gpggaLat = gpgga.latitude     
    gpggaLong = gpgga.longitude
    # 受信できていない場合は空欄が返される
    if gpggaLat is not '':
        # GPSのNMEAフォーマットから変換する
        gpsLat = float(gpggaLat[0:1])  + float(gpggaLat[1:]) / 60
        gpsLong= float(gpggaLong[0:2]) + float(gpggaLong[2:]) / 60

print "Lat :" + str(gpsLat)
print "Long:" +str(gpsLong)

注意しなければいけないこととして、gpgga.latitudeとかでとってこれる値はNMEAフォーマットの値で普通の経度緯度ではないみたい(ごめんなさい、正しくは何て言うんだろう)です。そのため、変換してやる必要があります。それについては以下を参照してみてください。
Not In The Manual: Convert NMEA latitude & longitude to decimal

これで、いい感じに位置情報をプログラム上で使うことができるんじゃないでしょうか。ヤッター!
蛇足かもしれませんがモジュールのアンテナの扱いは気をつけましょう。私はもいでしまいました。グワーッ!