M5Stamp C3でリモートIDを作りたい

# はじめに

この記事は、

**2022年6月20日以降に登録するドローンに搭載が義務付けられている「リモートID」をArduinoで自作したい**

という内容です。
「したい」なので、まだ完成してません。。。備忘録も兼ねて逐次更新していきます。

「Arduinoだって？そんな初心者向けな開発環境なんか興味ないぜ！」
という方は、どうぞお帰りください。

私個人の解釈を元に記事を書き散らしてているだけなので、間違いなど多くあると思います。
ガンガンご指摘をお願いしますm(__)m

# 目次

１ページが長くなってきたので、別記事作って退避させています。

0. [リモートIDとは（仕様書・製品・概要・国アプリ）](https://qiita.com/hsgucci/items/b28cea274d8f94bb18b9)　（別ページ）
0. [開発の方向性](#開発の方向性)
0. [マイコンの選定](#マイコンの選定)
0. [BLEの学習](#bleの学習)
0. [使用した機材](#使用した機材)
0. [AndroidスマホへOpen Drone IDアプリのインストール](#androidスマホへopen-drone-idアプリのインストール)
0. [M5Stamp C3のArduino開発環境の準備 ](https://qiita.com/hsgucci/items/b57a3908894064b68554)　（別ページ）
0. [M5Stamp C3でBLE5 Long Range のテスト](https://qiita.com/hsgucci/items/1800200dd7104228e337)　（別ページ）
0. [M5Stamp C3でOpen Drone IDを動かす準備](https://qiita.com/hsgucci/items/e825341af4927a72be7d)　（別ページ）
0. [Open Drone IDのサンプル「Random Flight」を試す
](#open-drone-id%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%ABrandom-flight%E3%82%92%E8%A9%A6%E3%81%99)
0. [M5Stamp C3にGPSを繋げて動作確認](#m5stamp-c3にgpsを繋げて動作確認)
0. M5Stamp C3とGPSでOpen Drone ID(BLE4)の送信
0. Random FlightのBLE5化
0. M5Stamp C3とGPSでOpen Drone ID(BLE5)の送信


# リモートIDとは

こちらのページに退避しました。

　　[リモートIDとは（仕様書・製品・概要・国アプリ)](https://qiita.com/hsgucci/items/b28cea274d8f94bb18b9)

# 開発の方向性

国内第３(?)のリモートID機器を発売予定の　[Braveridge](https://www.braveridge.com/product/archives/49)　さんは、こんな [ブログ](https://blog.braveridge.com/blog/archives/252) を書かれています。
このブログの最後に書かれていらっしゃる話が、私も全く同感です。
すなわち、リモートIDは、以下３つになるであろう、という部分です。

0. 外付けタイプ（筐体あり、電池内蔵）
1. 内蔵タイプ（筐体なし、外部給電、GPS搭載）
2. 内蔵タイプ（筐体なし、外部給電、MavLink入力）

1.は、現在ある国内製品と同じ、バッテリー内蔵タイプです。
2.は、バッテリー無しで電力だけドローン本体からもらいます。
3.は、MAVLink通信ができるフライトコントローラ（ArduPilotやPX4など）から機体情報をもらって転送します。

1.と2.は電源部分こそ違えど、機能はスタンドアローンです。
ドローン本体から機体情報をもらうことはできないので、
リモートIDが送信する、

- GNSS(GPS)情報：緯度・経度・Geo高度・対地速度
- 気圧高度：気圧センサによる高度推定
- その他：垂直移動速度、地上なのか飛行中なのかのフラグ

などのデータは、装置自身が計算する必要があります。

つまり、姿勢推定やミキシング、モータ出力が無いだけで、<font color=red>**実質フライトコントローラを作るのと同じ**</font>　なのです(T_T
ちょっと無理そう。

3.であれば、現在MAVLinkでもサポート作業が進行中なので、なんとか作れそうな予感がします。

https://mavlink.io/en/services/opendroneid.html

というわけで、
本記事では3.の**MAVLinkベースのリモートID装置**を考えていこうと思います。

ArduPilotやPX4もオープンソースなわけですから、
それを利用する**リモートIDもオープンに作りたい**ですよね～

また「番号登録を行う専用スマホアプリ」の開発は、私の手に余るお話です。

とりあえずの目標は <font color=blue>**機体情報を投げまくるだけの、機能が半分だけのリモートIDデバイス**</font> とします（苦笑

***
(**2022年5月26日追記**)
気圧高度や，操縦者の緯度経度は，オプション項目，すなわちデータ発信しなくても良いのだそうです。
えええ，，，MAVLinkから詳細貰わなくても，もうGNSSだけで良くね？という気分になってきました(T_T


# マイコンの選定

Wi-Fi NANはよくわからなかったので、
「BLE5.0でLong Range通信に対応したマイコン」
が必要だと思いました。

候補としては、以下の３つを見つけました。


- [nRF52833](https://www.switch-science.com/catalog/list/?keyword=nRF52833) が乗ったマイコン：　具体的には [Micro:bit V2](https://www.switch-science.com/catalog/7952/)
- [nRF52840](https://www.switch-science.com/catalog/list/?keyword=nRF52840) が乗ったマイコン：　具体的には [MDBT50Q](https://www.switch-science.com/catalog/6761/)
- [ESP32-C3](https://www.switch-science.com/catalog/list/?keyword=ESP32-C3) が乗ったマイコン：　具体的には [M5Stamp C3](https://www.switch-science.com/catalog/7474/)　または [M5Stamp C3U](https://www.switch-science.com/catalog/7894/)

Bluetoothの本家、NORDIC社の製品であるnRFシリーズがやはり最初に挙がります。
また、最近流行りのWi-Fi内蔵マイコン、ESP8266やESP32といった製品を出しているEspressifも、BLE5対応のRISC-Vマイコンを出しました。

私が重要視したポイントは「<font color=blue>**Arduinoとして、開発が簡単にできること**</font>」です。
フライトコントローラのArduPilotやMultiWii(betaflight系の前身)も、元々はArduinoのATmega328で作っていたのですから、「やっぱ最初はArduinoだろ！」なノリです(^o^


NORDIC製品であればEmbedded StudioやKailやIARのソフトで、
EspressifであればESP-IDFで開発することもできるのですが、
そこまでガチ勢寄りになると、初心者には敷居が高くなります(T_T

で調べたところ、NORDIC製品はBluetoothを管理するプロトコルスタック「SoftDevice」がS140というバージョンでなければLong Range通信ができないそうです。

[Micro:bit V2は頑張ればできそう](https://qiita.com/hisayan/items/617c3e690cb31ec6edb8)ですが、Arduinoとして使うときはまだ無理なようです。
またMicro:bitは、最近の半導体不足の影響で全く手に入りません(T_T)
ラズパイもそうですが、イギリス物が全滅な感。
子供のマイコン入門に使われているので、初心者向けの第一候補だったのですが、現状では見送りです。

MDBT50Qは[スイッチサイエンスの説明通り](https://www.switch-science.com/catalog/6761/)にやって、Arduino IDEでS140が使えることを確認しました。
しかし当該製品はUSBシリアル接続専用なので、ラズパイやJetsonといったコンパニオンPCに挿す用に使おうと思います。
他の[nRF52840製品](https://www.switch-science.com/catalog/list/?keyword=nRF52840)なら、UARTでPixhawkに接続もできますね。
ただ、Arduinoブートローダーが最初から入っている製品を買わないとセットアップが大変です。

---
(**2022年6月20日追記**)
Seeedstudioから凄く小さいnRF52840マイコンが出ていますね！
https://www.switch-science.com/catalog/8145/
これと、超小型のGPS装置
https://helimonster.jp/?pid=167785099
を組み合わせると、システムが小さく作れそうです。

---

で、最終的に選んだのはM5Stamp C3シリーズです。
最近流行りのM5Stack社のラインナップの一つで、Arduino開発環境の準備も比較的簡単でした。
Long Range通信の出力もできたので、たぶん使えそうです。
たぶん、というのはLong Range(LE Coded PHY)のなかのS=8モードでの動作確認はまだできていないからです。
このあたりの専門的な話は，後述します。

と、ここまでしょうもない感想文にお付き合いいただきありがとうございました。
大事な話はここから下の記事ですね(-_-;)

# BLEの学習

ここでBLEについて勉強しておきましょう。
まずは「Bluetooth」と「BLE」の違いから。

　　[【サルでもわかるBLE入門】（１） BLEの基礎](https://www.musen-connect.co.jp/blog/course/trial-production/ble-beginner-1/)

Bluetooth Classic(いわゆるBluetooth)とBluetooth Low Energy(BLE)は、
似て非なるものだそうなので、混同しないように注意しましょう。

***
BLEの内容については、ここを読んでください。

　　[開発視点の超簡単BLE入門](https://monomonotech.jp/kurage/webbluetooth/ble_guide.html)

今とりあえず必要なポイントは以下の２つです。

<dl>
  <dt>GAP</dt>
  <dd>通信役割や接続手順に関するルール。Advertise, Scan, Connect, Disconnectの手続きを担う</dd>
  <dt>Advertise(アドバタイズ)</dt>
  <dd>ペリフェラルが「私を見つけて！」と電波を発する行為</dd>
</dl>

GAPの中にAdvertiseという機能があって、それで周囲のデバイスに自分の存在を発信している、という話です。
つまり、リモートIDはAdvertiseの機能を使って、ドローンの情報を発信していることになります。
***
次はLong Range通信の勉強です。

　　[変更点②：4倍の通信距離](https://techweb.rohm.co.jp/iot/knowledge/iot02/s-iot02/07-s-iot02/5238)

ポイントはいわゆる「Long Range」と呼んでいる機能は、「<font color=red>**LE Coded**</font>」という機能だという話です。
（厳密には「**LE Coded PHY**」？）
更に、400ｍ届かせるにはLE Codedの中の「<font color=blue>**S=8**</font>」というモードにする必要があることになります。

国交省の規格書、
「水平距離で300m 以上離れた地点から受信可能であること」とか抽象的に書かずに、
「BLE5.0のLE Coded PHY S=8の機能で発信すること」って書いてほしかったよ。。。(T_T)
***
次はAdvertiseの勉強です。

　　[変更点③：8倍の通知データ容量](https://techweb.rohm.co.jp/iot/knowledge/iot02/s-iot02/07-s-iot02/5259)

ポイントはこの図。
![BT5-4_f2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/e965e35d-d167-9f22-816a-4b7e2f3a5393.png)
Advertiseで送信できるデータ長は、
BLE4が37バイトまでだったのに対して、BLE5は255バイトまで増えた、という話です。

これを踏まえてASTM F3411-19の仕様書を見てみると、以下のような図がありました。
![ble4_legacy_advertise.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/51bb7a9a-3374-df28-65f5-4e936530909d.png)
![ble5_extended_advertise.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/3524dae9-f94c-98ef-cd11-bf687c442406.png)

オレンジと緑の部分が、先の比較のペイロードに該当しているのがわかります。
そして、BLE4のレガシーなAdvertiseでは１回に25バイト(実質24バイト)しかドローンのメッセージを送れないので、何回も送る必要があり、
BLE5の拡張Advertiseではその25バイトを複数個まとめて１回で送信できてしまう、という事になりますね。
で、海外ではBLE4のレガシーAdvertiseの使用も許されているけど、日本はBLE5の拡張Advertiseオンリーということになります(T_T
***
というわけで、まとめると、

<font color=red>**BLE5のLE Coded PHY S=8を使って、拡張Advertiseで１度にまとめてデータ送信をする**</font>

が当面の目標になることがわかりました。


# 使用した機材

私が使用した機材は、以下の通りです。

- M5Stamp C3　(マイコン)
- Oppo Reno5 A （中古スマホ）
- Thinkpad X1 carbon 2015年モデル　（中古ＰＣ）

M5Stamp C3Uも持っていますが、最初はC3で試しました。
両方とも動作確認はしましたので、C3でもC3Uでも，どちらでも大丈夫です

動作確認用のスマホは、BLE5.0以上に対応し，かつLE Coded PHYにも対応している必要があります。
ネットで色々調べて、中古が比較的安いOppo Reno5 Aにアタリを付けました。
最悪Pixel6を買う覚悟をしていましたが、LE Coded PHYの拡張アドバタイズの受信に成功したので、大丈夫そうです。
だだし前述しましたが、いちばん大事なS=8モードの動作確認はまだです(T_T)

Windows10のＰＣをArduino開発環境としました。中古のX1カーボンが安かったので使っています。

# AndroidスマホへOpen Drone IDアプリのインストール

Open Drone ID公式のスマホ用受信アプリはGoogle Mapsを使っているため、
APIキー取得の都合で、自分でソースプログラムをビルドする必要があります。
この作業が結構大変です。

その手順を解説してくれているサイトがこちらです。

https://github.com/ToshihiroMakuuchi/receiver-android-jp/wiki

なんと、**Betaflight ConfigratorやQGroundControlの日本語化**で多大な貢献をされた，あの**まっく まるちぷろとこる氏**が、
公式Gitからフォークして日本語化を進めてくれています！

[Mission Plannerの日本語化](https://diydrones.com/group/japan-arducopter-group/forum/mission-planner?commentId=7447824%3AComment%3A1578805)のお手伝いをした私としても、
様々なドローン用ソフトの日本語化に貢献していきたいと思います。
あ、ちなみに [UgCSの日本語化](https://github.com/hsgucci404/ugcs_jp) も進めておりますのでよろしくお願いします。


以降、本記事でM5Stamp C3の動作確認は、「まっく氏版」で行っています。


# M5Stamp C3のArduino開発環境の準備

こちらのページに退避しました。

　　[M5Stamp C3のArduino開発環境の準備 ](https://qiita.com/hsgucci/items/b57a3908894064b68554)

# M5Stamp C3でBLE5 Long Range のテスト

Arduino-ESP32の標準Exampleを使って、BLE5のAdvertiseの動作テストを行います。

こちらのページに退避しました。

　　[M5Stamp C3でBLE5 Long Range のテスト](https://qiita.com/hsgucci/items/1800200dd7104228e337)

# M5Stamp C3でOpen Drone IDを動かす準備

Open Drone IDを動かすためにArduinoの環境設定を行います。

こちらのページに退避しました。

　　[M5Stamp C3でOpen Drone IDを動かす準備](https://qiita.com/hsgucci/items/e825341af4927a72be7d)

# Open Drone IDのサンプル「Random Flight」を試す

Open Drone IDを試すのに良いサンプルがあります。「Random Flight」です。

[M5Stamp C3でOpen Drone IDを動かす準備](https://qiita.com/hsgucci/items/e825341af4927a72be7d)で環境設定が完了していれば、
[**ファイル**]-[**スケッチ例**]-[**id_open**]-[**random_flight**]
で開くことができます。

![menu_random_flight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/811399a1-4fca-4f2c-76da-8f9bd7b32a84.png)

このサンプルを動かすと下の動画のように動きます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">M5Stamp C3でOpen Drone IDのサンプル「Random Flight」を動かしています。<br>(Qiita記事用) <a href="https://t.co/mlUrN00Uxu">pic.twitter.com/mlUrN00Uxu</a></p>&mdash; hsgucci404 (@hsgucci404) <a href="https://twitter.com/hsgucci404/status/1527916195315580929?ref_src=twsrc%5Etfw">May 21, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

時々刻々とバーチャルなドローンの位置が変わっているのがわかると思います。
ちなみに、青いマーカーがホーム地点で、赤いマーカーがドローンの現在位置になります。
他の`id_open`系サンプルの「finland」や「rebel_colonies」は、プログラムは非常に短く簡単なのですが、マーカーが移動しないので面白くありません。
一方random_flightは、200ミリ秒ごとにランダムな方位へ移動します。

コンパイルし、M5Stamp C3に書き込んで動作確認してみましょう。

シリアルモニタへの出力は以下のようになります。
![randomflight_print.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/ceb1d111-2197-97b7-8a04-8d570a36792d.png)
このように、**緯度・経度・方位・速度・方位変化量**が変化している出力が出ていればOKです。

どのあたりを飛んでいるようにエミュレートしているかは、プログラム中に書いてあります。
![randomflight_default_latlon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/0be0974c-ab7f-f4b9-156f-25f67d8d961a.png)

ホーム地点　北緯52度46分49.89秒、西経0度42分26.26秒を、単位を度分秒ではなく**度**に計算しているのがわかります。
スマホのOpen Drone IDアプリ(まっく氏日本語版)だとこんな感じになります。
![randomflight_zoomout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/1d636140-eea9-ca5c-4f1c-d985f70c778f.png)

イギリス模型飛行機協会のバックミンスターの飛行場だそうです。
[British Model Flying Association](https://nationalcentre.bmfa.org/)

## ホーム地点の変更

先程のホーム地点の計算式を見て、わかっちゃった人も多いと思いますが、
Random Flightのホーム地点は簡単に変更できます。
別に度分秒で与える必要もありません。

例えばArduPilotの登録済みロケーションを参考にして、、、
https://github.com/ArduPilot/ardupilot/blob/master/Tools/autotest/locations.txt

`KawaguchiLake=35.4712023,138.7450261,965,90`

だから、北緯35.4712023、東経138.7450261だとこうなります。
![randomflight_kawaguchiko_latlon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/5603c694-420e-8e05-2431-879b9c760cd7.png)

これでコンパイルして書き込むと、
![randomflight_kawaguchiko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/4f17fe05-5001-53e8-1865-5e7f4e5833f1.png)
このように河口湖のドローンエンジニア養成塾の会場にホーム地点の周辺を飛ぶように変更できました。

# M5Stamp C3にGPSを繋げて動作確認

バーチャルにランダム飛行するだけでは面白くありませんね。
実際の位置(緯度経度)を元にマーカーが表示・移動すると達成感も一塩です。

M5Stamp C3にGPSユニットを接続し、GPS座標を使ってOpenDroneIDを発信したいですね。
この章では、GPSの接続や動作確認を行います。
すなわち、実際の発信ではなく準備作業です。発信は次の章からです。

## 準備するもの

M5Stack社の製品には、Grove端子を使って接続する「Unit(ユニット)」という周辺機器がラインナップされています。
その中にはGPS受信機もあります。
これを入手しましょう。

https://www.switch-science.com/catalog/5694/

このGPSを接続するためには、Greve端子が必要です。
M5のStackやStickなどのシリーズにはGrove端子が標準搭載されているのですが、Stampシリーズには付いていません。
ですが、端子を取り付ける2.0mmピッチの穴は空いているので、そこにコネクタをハンダ付けする必要があります。

単品バージョンのC3やC3Uを買っていれば、Groveコネクタや分解用の六角レンチも付いているので、すぐに作業が始められます。

https://www.switch-science.com/catalog/7474/

https://www.switch-science.com/catalog/7894/

5個セット版には何も付いていないので、コネクタだけ別で購入しましょう。

https://www.switch-science.com/catalog/1123/


## M5Stamp C3にGroveコネクタをハンダ付けする