5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【IoT入門】GPSトラッカーで遊んでみた話

Last updated at Posted at 2019-07-16

IoTデバイスとして各種センサーを接続可能な汎用GNSS/GPSトラッカー、マエストロ・ワイヤレス社()のBOLEROをいじる機会があったので、使い方を簡単に紹介する。
image.png

:香港に本社を置くメーカー。建機等の車両動態管理、産業機械などの遠隔監視に強み。2019年7月、Lantronix社に買収された。BOLEROの仕様はこちら

基本知識

本記事に興味を示す読者なら既にご存知のことと思うが、最初に基礎的なことから解説する。

IoTとM2M

IoTとは、あらゆるモノがインターネットに繋がる概念をいう。この〝モノ〟にあたるのをエッジデバイスといい、インターネットに繋ぐための中継装置をゲートウェイという。ゲートウェイを通してクラウドに蓄積された膨大な情報、これをビッグデータというが、このビッグデータを分析し、新たな価値を生み出してビジネスに活用することこそIoTの本質と言っても過言ではない。
IoTで収集したデータをすべて送信しようとすると大容量の通信回線が必要になり、コストの増大やレイテンシ(遅延)が懸念される。これを解決する技術としてIoTデバイス側に処理機能を持たせるエッジコンピューティングがあり、近年注目されている。

M2Mは機器同士が直接ネットワークで接続し、相互に情報をやり取りする。情報をインターネットやクラウドに送るところまでの機能は持っていない。なので、M2MはIoTのサブセットといえる。

GPSとGNSS

人口衛星によって地上の現在位置を特定するものを衛星測位システムと呼ぶが、その中でも地球すべてを測位可能なものをGNSSと呼ぶ。
広く周知されているGPSはアメリカが開発したシステムであり、GNSSのひとつである。他にロシアのGLONASS、EUのGalileo、中国の北斗、日本の「みちびき」(準天頂衛星システム:QZSS)などがある。

今日のGNSS測量ではGPSを含む複数のGNSSを併用し、より効率的で精度の高い測量が可能になっている。

ロガーとトラッカー

GNSSロガーは位置情報を端末に記録する(=ログを取る)だけ。GPS電波を受信できても送信することはできない。位置情報を閲覧するにはパソコンなどに接続する必要がある。

一方、GNSSトラッカーは携帯電話の回線(3G/LTE)で位置情報をサーバに送信するため、パソコンやスマホなどでリアルタイムに位置情報を確認できる。ただしデータ通信専用のSIMを契約することになるので、携帯電話同様に月々の費用が発生する。近年MVNOの出現により、リーズナブルな料金でトラッカーを運用できるようになった。

GSMと3G

GSMは第2世代携帯電話の通信方式のひとつで、多くの国で使用されており、発展途上国では未だ主流である。

3Gは第3世代携帯電話の通信方式のひとつで、電波が届く範囲が4G(LTE)よりも広く、さまざまな場所で通信できるという利点がある反面、通信速度が4Gより遅いというデメリットがある。動画再生やネットサーフィンは快適とは言えないが、少量のデータ通信で問題になることは殆どないだろう。

ちなみにアナログ携帯電話が1G(第1世代)、デジタル携帯電話が2G(第2世代)で、これに続く3G(第3世代)という意味である。

使ってみよう

小箱を開梱すると、BOLERO本体、制御ボックス、プリペイドSIMカード(評価用)、USBシリアル変換アダプタ、ACアダプタ、取説が入っている。
BOLEROに給電を始めると、まもなく赤色のLEDが点灯または点滅する。
他のGPSトラッカー同様、GPS、3G/GSMそれぞれの電波状態が、ステータスLEDで分かるようになっている。

状態 意味
消灯 電源が入っていない。
点灯 GPS状態は良好である。(4つ以上のGPS衛星が捕捉できている)
点滅 GPS状態は不良である。(使用中のGPS衛星が3つ以下)
消灯 GSM通信(3G/GSM)ができていない。
点灯 クラウドのサーバ(TCP/IP)と通信中。
点滅 GSM通信(3G/GSM)ができる状態である。

SIMカードを装着してみよう

BOLERO本体のネジを外してハードケースを開けると、SIMカードを2枚差せることが判る(Dual SIM対応)。
KDDI系IoTベンチャーSORACOM社が、MVNOで提供しているデータ通信専用SIM(SORACOM Air SIM)を装着した。SORACOM Air SIM はAmazonで1枚から購入可能だ。
image.png
無論、SORACOM認定デバイスのひとつである。
https://soracom.jp/support_partners/certified_device/nexty-bolero-45/

パソコンと接続してみよう

制御ボックスを、USBシリアル変換アダプタを介してパソコンと接続する。
パソコンで操作するときのみ、BOLEROを制御ボックスと接続する。
名称未設定2.png
パソコンでJava製の専用ソフトを起動し、シリアルポートを指定すると、コンフィグレーションの書き込みや専用スクリプトの動作確認ができる画面になる。
image.png

センサーと接続してみよう

可変型直流安定化電源と光電センサを下図の通り接続してみた。
可変型電源は、アナログ測定した電圧値(IO1)がサーバに送信されるか確認するために用意。
光電センサは、デジタル測定した物体検出のオンオフ変化(IO2)がサーバに送信されるか確認するために用意した。
このときパソコンと接続していれば、シリアル入力でもセンサーの状態を確認できる。
image.png
bolero.jpg

コンフィグレーションを書いてみよう

BOLEROはノンプログラミングで、センサーのデータと**GPS位置情報(NMEA 0183フォーマット)**をサーバに送信できる。
そのための設定情報(コンフィグレーション)を一部だが以下に抜粋する。
BOLEROのコンフィグレーションとはコマンドの羅列であり、先頭から順番に1行ずつ実行される。
イベントの概念を持ち、「もし~なら~を実行する」というIf文のような定義もできる。
ステータス表示用のLED(緑と赤)もプログラマブルに制御可能だ。

コンフィグレーション例
$PFAL,CNF.Set,DEVICE.BAT.CHARGEMODE=eco  // 内蔵バッテリの充電タイミング
$PFAL,CNF.Set,DEVICE.GPS.AUTOCORRECT=off,5.0,58,50,10,50  // GNSSの自動補正(位置情報算出のためのパラメータを設定し、指定した条件を満たさないとGNSSは有効としない)
$PFAL,CNF.Set,DEVICE.GPS.CFG=3  // 位置情報を有効とする衛星捕捉数を設定
$PFAL,CNF.Set,TCP.CLIENT.SENDMODE=2,1000  // データを不揮発性メモリに保存した後、TCP送信する
$PFAL,CNF.Set,TCP.CLIENT.TIMEOUT=300000,30000  // GNSSトラッカーの応答時間、TCP接続が失敗した時の次の接続までの時間を設定
$PFAL,CNF.Set,GPRS.AUTOSTART=1  // ネットワークの準備ができたら自動で接続/再接続する
$PFAL,CNF.Set,GPRS.TIMEOUT=1,600000  // 600秒間、通信が無ければネットワークを切断(消費電力を抑えるため)
$PFAL,GSM.Band=auto  // 使用するGSM帯域を自動設定にする

// NMEA 0183 メッセージの出力可否(1=出力、0=出力しない)
$PFAL,CNF.Set,PROT.GGA=1
$PFAL,CNF.Set,PROT.GLL=1
$PFAL,CNF.Set,PROT.GSA=1
$PFAL,CNF.Set,PROT.GSM=1
$PFAL,CNF.Set,PROT.GSV=1
$PFAL,CNF.Set,PROT.RMC=1
$PFAL,CNF.Set,PROT.VTG=0

// 緑LED(3G/LTEの状態)のイベント制御
$PFAL,CNF.Set,AL21=GSM.eOpfound:IO12.Set=cyclic,200,200  // GSM事業者を見つけたら
$PFAL,CNF.Set,AL26=GSM.eOplost:IO12.Set=low  // GSM事業者を見失ったら
$PFAL,CNF.Set,AL22=GSM.GPRS.eConnected:IO12.Set=cyclic,400,400  // GPRSネットワークに接続したら
$PFAL,CNF.Set,AL25=GSM.GPRS.eDisconnected&GSM.sOpValid:IO12.Set=cyclic,200,200  // GPRSネットワークと切断したら
$PFAL,CNF.Set,AL23=TCP.Client.eConnected:IO12.Set=high  // サーバと接続したら
$PFAL,CNF.Set,AL24=TCP.Client.eDisconnected&GSM.sOpValid:IO12.Set=cyclic,400,400  // サーバと切断したら

// 赤LED(GPSの状態)のイベント制御
$PFAL,CNF.Set,AL27=Sys.Device.eStart&GPS.Nav.sFix=valid:IO13.Set=high  // 4つ以上のGPS衛星が捕捉できたら
$PFAL,CNF.Set,AL18=Sys.device.eStart&GPS.Nav.sFix=invalid:IO13.Set=cyclic,200,200  // 使用中のGPS衛星が3つ以下になったら
$PFAL,CNF.Set,AL19=GPS.Nav.eFix=valid:IO13.Set=high  // 4つ以上のGPS衛星が捕捉できたら
$PFAL,CNF.Set,AL20=GPS.Nav.eFix=invalid:IO13.Set=cyclic,200,200  // 使用中のGPS衛星が3つ以下になったら

$PFAL,CNF.Set,DEVICE.PFAL.SEND.FORMAT="$",NOCKSUM,"","$<end>"  // メッセージフォーマット

// リモートサーバのIPアドレスおよびポートを指定(アカウントを取得すればマエストロ社のクラウドサービス trace4you に送信して可視化できる)
$PFAL,CNF.Set,TCP.CLIENT.CONNECT=1,12.34.56.78,8888
$PFAL,CNF.Set,TCP.CLIENT.ALTERNATIVE=1,12.34.56.78,8888

// APN(Access Point Name)の設定 ... SORACOM Air の場合
$PFAL,CNF.Set,GPRS.APN=soracom.io
$PFAL,CNF.Set,PPP.PASSWORD=sora
$PFAL,CNF.Set,PPP.USERNAME=sora

///////////////////////////
//  センサーのイベント制御
///////////////////////////

// IO1 に接続した電圧値を30秒ごとにテキストでサーバへ送信する
$PFAL,CNF.Set,AL30=SYS.Device.eStart:SYS.Timer6.Start=cyclic,30000
$PFAL,CNF.Set,AL31=SYS.Timer.e6:TCP.Client.Send,8,"IO1 &(ANA1) Voltage"&TCP.Client.FlushSendBuffer

// IO2 に接続した光電センサーのON/OFFが変化したらテキストでサーバに送信する
$PFAL,IO2.Config=DI  // OnとOffのデジタル入力とする
$PFAL,CNF.Set,AL32=IO.e2=Redge:TCP.Client.Send,8,"IO2 Rising edge"&TCP.Client.FlushSendBuffer  // IO2 が Low から High に変わったら
$PFAL,CNF.Set,AL33=IO.e2=Fedge:TCP.Client.Send,8,"IO2 Falling edge"&TCP.Client.FlushSendBuffer  // IO2 が High から Low に変わったら

// 後処理
$PFAL,CNF.Backup  // 現在のユーザ設定をバックアップ
$PFAL,Sys.Device.Reset  // 5秒後に再起動

サーバに送信してみよう

サーバとの接続は、ただのTCPソケットなので、次のような簡単なPythonプログラムを数行書くだけでデータを受信できる。

tcp_server.py
import socket
from contextlib import closing

def main():
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  with closing(sock):
    sock.bind(('0.0.0.0', 8888))
    sock.listen(10)
    while True:
      conn, addr = sock.accept()
      with closing(conn):
        raw_data = conn.recv(1024)
        print(raw_data.decode())
  return

if __name__ == '__main__':
  main()

ただし、このプログラムはソケット通信の多重化まで考慮していない。acceptが処理をブロックする間、他のクライアントと通信できないのだ。
シングルプロセスかつシングルスレッドのままで多重化したいならselectもしくはselectorsモジュールを使う。selectモジュールの使い方は@homines22さんの記事【selectモジュールによるポーリング】が詳しいので参照して欲しい。

実行結果
$ python3 -V
Python 3.6.8

$ python3 tcp_server.py
$IO1 12.483 Voltage
$GPRMC,000057.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>
$IO2 Rising edge
$GPRMC,000058.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>
$IO2 Falling edge
$GPRMC,000102.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>
$IO1 12.682 Voltage
$GPRMC,000107.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>
$IO2 Rising edge
$GPRMC,000109.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>
$IO1 13.659 Voltage
$GPRMC,000117.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>
$IO1 15.448 Voltage
$GPRMC,000127.000,V,0000.0000,N,00000.0000,E,,,060180,,
$<end>

送信に失敗したデータはBOLEROの内蔵メモリに蓄えられ、次回接続成功時に再送してくれる。

以上、駆け足で説明したがイメージが伝われば幸いである。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?