LoRa通信をLRA1のBASICで、GPSトラッカーを作っちゃおう!
この記事について
今回は、LRA1を使って簡単なGPSトラッカーを作ってみます。
LRA1にGPSモジュールを接続して、LoRaで緯度・経度を送信し、受信側のLRA1からPCにシリアル出力。
その値をPythonで受信して、地図に表示してみましょう。
🎀 GPSとLoRaとPythonが合体したら…もうIoTの入口って感じだよね〜!
配列変数 @[] の使い方
LRA1のBASICには、唯一の配列変数 @[ ]
が用意されています。
- 名前は
@
固定(@が変数名です)で、1種類のみ - 書き方は
@[0]
のように@
のあとに角括弧(通常の括弧でもOK) - インデックスは
@[0]
〜@[255]
の256個(整数値) - インデックスには式も使えます(例:
@[A+1]
) asave
/aload
コマンドで、配列全体をFlashに保存/復帰することができます
例えばこんな使い方ができます:
>@[0]=1:@[1]=1:for I=2 to 9: @[I]=@[I-1]+@[I-2]:next:?"5番目="@[5]
これだけでフィボナッチ数列が作れて、5番目の値まで表示できます。
🎀 えっ、これ1行で!? なんかカッコいい〜っ!
この配列変数は、後ほど説明するGPSのコマンドで利用します。
UART2って何?
LRA1にはUARTが2つあります。メインのUARTはPCとの通信などに使われますが、それとは別に UART2 が搭載されており、主に外部デバイス接続用として設計されています。
ポートは次のようになっています。
方向 | ポート | ピン番号 |
---|---|---|
TX | PA22 | 26 |
RX | PA23 | 20 |
UART2は、UPRINT
コマンドでPRINT
コマンドと同様に制御できます。
GPSモジュールやセンサとのシリアル通信 に便利です。
デフォルトのボーレートは 9600bps ですが、UBAUD
変数を設定することで ボーレートを指定できます。
>UBAUD=115200:UPRINT "Hello!!"
🎀 2つあるってだけで“並列で使える”って感じがして頼もしいよね〜っ!
GPSデータを取得する
LRA1のUART2に GPSモジュールをつなぐと、たった1つのUGPS
コマンドでNMEAフォーマットを受信・解析し、緯度・経度・高度などの情報を自動的に取得することができます。
引数にタイムアウトとHDOPの指定ができます。
>UGPS 10000 OK
実行後の結果は、以下のように配列変数に格納されます:
* @[0]
= シリアル秒 (UTC)、タイムアウト時は0になります
* @[1]
= 緯度(度×1,000,000)
* @[2]
= 経度(度×1,000,000)
* @[3]
= 高度(m×10)
* @[4]
= HDOP(×10)
たった1コマンドで、これらが自動的に入る仕組みです。
🎀 GPS受信結果が配列にバシッと入るとか、シンプルだけど力強い〜っ!
※ 9600bps以外のときは、前もってUBAUD
変数の設定をしてください。
GPSモジュールを接続する
📸 実際にLRA1-EBにGPSモジュールをつないだ様子がこちら!
この構成では、GPSモジュールの TX を LRA1 の UART2(RX)に接続します。
接続はたったこれだけ:
- GPSの TX → LRA1 の UART2-RX (PA23)
- 電源(VCC)
- GND(共通)
今回、しゃちらぼでは、GPSモジュールに「秋月電子のGPS受信機キット(AE-GYSFDMAXB)」を使いました。
本来5V動作ですが、今回はLRA1-EBの3.3V出力に接続して一応動作しています。
ただし、あくまで“とりあえず動いてる”だけなので、それぞれのモジュールに合わせて、必要なら外部から5Vを供給するようにしてください。
🎀 とりあえず動いてるけど、3.3Vで動かないGPSモジュールもあるから、モジュールの仕様はよーくチェックしてね〜っ!
📝 秋月電子のGP受信機キット(AE-GYSFDMAXB)は、現在販売終了となっています。
LRA1の`UGPS`コマンド は一般的なNMEAフォーマットに対応しているので、他のGPSモジュールを使用することも可能です。
シリアル時刻
UGPS
コマンドでは、GPSからは時刻(UTC)が取得でき、@[0] に格納されます。
このシリアル時刻は UTCの「2020/1/1, 00:00:00」からの経過秒数となります。
これをClock
変数に設定すると、現在時刻をRTCでカウントすることができます。
また、DateTime
関数を利用すると、このシリアル時刻を日時の文字列に変換することができます。
>ugps:clock=@[0]+32400 Ok >? datetime(clock) 2025/06/03 08:12:34 Ok
@[0]
にGPS時刻+32400
でJST(UTC+9)へ補正して、Clock
変数(RTC)に設定datetime()
関数で “YYYY/MM/DD hh:mm:ss” に変換して表示
🎀 これ、ログのタイムスタンプとかにもめっちゃ便利〜っ!
LoRaで送信してみる
取得したGPS情報をLoRaで送信する例:
100 Ubaud=9600 110 #=Null 120 Do 130 Ugps 100000 140 If @(0) Then 150 Clock=@[0]+32400 160 Print Datetime(Clock)","@[1]","@[2]","@[3]","@[4] 170 #[7]=12 180 Txdl[8]=@[1]' 緯度 190 Txdl[12]=@[2]' 経度 200 Txdw[16]=@[3]' 高度 210 Txdw[18]=@[4]' HDOP 220 Send 230 Delay 10000 240 EndIf 250 Loop
実行例
>RUN 2025/06/03 12:34:56 35688710,139690155,716,14
- 緯度・経度を
txdl[8]
とtxdl[12]
にセット(int32) - 高度を
txdw[16]
にHDOPをtxdw[18]
にセット(int16) #[7]=12
で送信バイト数を10バイトに設定(4+4+2+2)- 10秒ごとに送信
- 事前に
SF / BW / CR / GID / OWN / DST
は設定しておいてください
🎀 このへんのLoRa送信パターン、もう見慣れてきたよね〜!
受信&PCに出力してみる
LoRaで受信したGPSデータをUARTで出力する例:
100 Recv 0 110 Do 120 If Stat Then 130 If Stat=10 && Rxd[7]>=12 Then 140 Print %"{%22lat%22:"Rxdl[8]; 150 Print %",%22lon%22:"Rxdl[12]; 160 Print %",%22alt%22:"Rxdw[16]; 170 Print %",%22hdop%22:"Rxdw[18]"}" 180 EndIf 190 Stat=0 200 EndIf 210 Loop
実行例
>RUN {"lat":35688710,"lon":139690155,"alt":716,"hdop":14}
このプログラム例では、print 文で直接 JSON 文字列を構築します。
ただし、”(ダブルクォーテーション)は BASIC 内で特殊文字の扱いになるため、通常の文字列では使えません。
そこで、” を %22 として出力する パーセントエンコード形式を採用しています。
LRA1のBASICでは、文字列のダブルクオーテーションの前に%をつけるとパーセントエンコードになります。
🎀 “%22”って書くと、ダブルクォーテーションってことなんだね〜っ!
これで、Python 側では decode(‘utf-8’) → json.loads() の処理で問題なくパースできます。
* UARTにそのまま出力すれば、PCとつないでPythonで処理もOK!
- 事前に
SF / BW / CR / GID / OWN / DST
は設定しておいてください
🎀 ここで“UART経由で外に出す”ってのが、今回のミソなんだよ〜!
Pythonで地図に表示してみよう!
いままでは、LRA1のボード内で送受信や表示が完結していましたが、
やはり、PCやネットで受信データを扱いたいですよね。
そこで今回は、受信したデータをPCで処理をする実践をやってみます。
例として、GPSで受信した位置情報をPythonで地図に表示してみます。
今回のPythonコードは「一度だけGPS位置を受信して地図を作成する」方式です。
でも、地図ファイル(HTML)を上書き保存し続ければ、ブラウザをリロードするだけで最新の位置を確認することができます。
🎀 静的HTMLでも、F5連打でリアルタイムっぽく見せられるよ〜っ!
たとえばこんなコードで受信して地図に表示できます。
これを実行すると lra1_position.html
を上書き保存し続けるので、
このhtmlファイルをブラウザで表示すれば、地図表示を“リアルタイムっぽく”運用できます。
※ コード中のシリアルポート名は、環境に合わせてください。
Pythonコードの例
# このコードはUARTから新しい位置を受信したときのみ地図を更新します。 # JSON形式で1行に送られたデータを読み取って処理します。 import serial import folium import json ser = serial.Serial('COM3', 115200, timeout=1) lat = None lon = None alt = None prev_lat = None prev_lon = None prev_alt = None while True: line = ser.readline().decode().strip() if not line: continue # 空行は無視する try: data = json.loads(line) lat = data["lat"] / 1_000_000 lon = data["lon"] / 1_000_000 alt = data["alt"] / 10 except Exception as e: continue if lat is not None and lon is not None and alt is not None: if lat != prev_lat or lon != prev_lon or alt != prev_alt: m = folium.Map(location=[lat, lon], zoom_start=18) m.get_root().html.add_child(folium.Element('<meta http-equiv="refresh" content="10">')) folium.Marker([lat, lon], tooltip=f"LRA1 GPS (Alt: {alt} m)").add_to(m) m.save("lra1_position.html") print(f"位置を更新: {lat}, {lon}, 高度: {alt}m") prev_lat = lat prev_lon = lon prev_alt = alt else: print(f"同じ位置データ")
ここではPythonコードの詳細までは踏み込みません。
大事なのは、LRA1からUART経由でデータを受け取れること。
Python側ではLRA1から値を受信して、あとは好きなように処理すればOK!
🎀 UART出力さえ受け取れば、もう“自由の世界”がひらけるんだよ〜!
補足:Pythonの実行に必要なモジュール
今回紹介したPythonコードを動かすには、以下の2つのモジュールをインストールしておいてください:
- pyserial:シリアル通信用
- folium:地図表示用のHTMLファイルを生成するライブラリ
インストールは以下のコマンドでまとめてOK!
pip install pyserial folium
🎀 一度入れておけば、あとはそのまま使えるから安心だよ〜っ!
おまけ:地点の距離と方位角も計算できちゃう!?
実はLRA1には、2つのGPS座標から距離と方位角を出す Distance
コマンドまで用意されています!
@[0]=緯度1 @[1]=経度1 @[2]=緯度2 @[3]=経度2 Distance ' → @[4] に距離(m)、@[5] に方位角(deg)
地球楕円体モデル(WGS84)の赤道半径(6,378,137 m) を使って演算してます!
今回は紹介だけですが、「追跡」や「ルート解析」に使えます。
🎀 もうこれは…LRA1 BASICが“カーナビ語ってもいいレベル”じゃん!?
まとめ
今回は、
- LRA1でGPSを取得し、
- LoRaで飛ばし、
- 受信してPCに渡し、
- Pythonで地図に表示する
という一連の流れが完成しました。
これでもう、ちょっとしたIoTトラッカーとしては 十分な完成度です!
🎀 とりあえず、P2Pで簡単にできることを一通りやってみた!”って感じだね。
それと、LRA1のBASICなら、好みのフォーマットでUART出力できるから、
シンプルな環境でも外部連携ができる設計では、JSONを使うのが最強だと思います。
JSON使えば、Pythonとの連携もバッチリ!
🎀 “BASICでJSON”…これって、じつは“シンプルだけど世界につながる形”なんだよ!
📪 お問い合わせなど
技術的なご相談やご質問などありましたら、
📩お問い合わせフォーム
または、
📮info@shachi-lab.com までお気軽にどうぞ。
🎀 LRA1の使い方でも、記事の内容でも、気になることがあったらいつでもお問い合わせしてね〜っ!
🔗 関連リンク
しゃちらぼの最新情報や開発の様子は、こちらでも発信しています:
- 🌐しゃちらぼ公式サイト
- 🐦 X(旧Twitter):@shachi_lab
- 📗 Qiita:@shachi-lab
- 🐙 GitHub:@shachi-lab
- 📸 Instagram:@shachi_lab
ほんとは「しゃちらぼ(Shachi-lab)」なんだけど、見つけてくれてありがとう🐬
コメント