M5Stackでモールス信号練習機を作ってみた


https://github.com/gitnabeshin/M5Stack_CWTrainer

![IMG_3198D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/8a9f616b-c410-f9e7-5ff3-edc5b147b452.jpeg)


# はじめに
* 天空の城ラピュタ、崖の上のポニョ、紅の豚、インターステラー、オブリビオン、、、
 * 印象深いあのシーン、このシーン。
 * インターネットやスマホで何でも済んじゃう時代だけど、人類の危機で役立つのはやっぱモールス信号でしょ？

と思い、以前Arduinoでモールス信号デコーダを製作した。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Arduino モールス信号デコーダ、ダイソーの小物ケースに穴を開けてLCDとメニューボタンとスピーカーをまとめてみた。見た目スッキリして良い感じ。<br>ソフト的にまだかなり機能追加できる余地があるので、もりもりモード追加して行こう。 <a href="https://t.co/HMJG84qV5P">pic.twitter.com/HMJG84qV5P</a></p>&mdash; Nabeshin (@desmoquattro996) <a href="https://twitter.com/desmoquattro996/status/1178209488492302336?ref_src=twsrc%5Etfw">September 29, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

* さらに機能拡張するためには
 * これはこれで、一つの方向性として良い。
 * が、さらに機能追加して行くとなると、LCDが16 * 2 文字、（あっても20 * 4 文字）で表現力に制限がある。
* M5Stackで解決
 * そんな中、数年前に夢のデバイスが発売された。
 * 十分な解像度のLCD、ボタン、バッテリと言った要素が最初から揃ったM5Stackに実装することで一気に解決した。
 * 新たなデバイス開発の可能性を感じたので、ここにまとめておく。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">M5Stackでモールス信号デコーダ作ってみた。<br>せっかくなのでメニューも付けて英語、日本語切り替え出来るようにした。以前Arduino &amp; LCDで作った時よりコンパクトで、TFTの表現力は桁違い。まだまだアップデート出来そう。 <a href="https://t.co/2TfDWVDavx">pic.twitter.com/2TfDWVDavx</a></p>&mdash; Nabeshin (@desmoquattro996) <a href="https://twitter.com/desmoquattro996/status/1305151059505999875?ref_src=twsrc%5Etfw">September 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## M5Stack
* https://m5stack.com
 * 2017年に発売された、ESP32、LCD(320*240)、バッテリ、ボタン、その他の機能てんこ盛りで5000円以下と言うめっちゃリーズナブルな価格のデバイス。
 * 関連製品リリースの勢いは加速する一方であり、今後も盛り上がっていくのは間違いない。

![IMG_3207D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/f762d848-4198-80aa-9396-b9bac42b0853.jpeg)


# 構成
* M5Stackを使う。これにより、ハード設計はほぼ不要となる。
 * 自分は高機能寄りのM5Stack Fireで開発している。
 * 現在M5Stackはフラッシュメモリを4MB搭載モデルBasicと16MB搭載のそれ以外のGray, Fire, core2がある。
 * もちろん後者の方がプログラムサイズを気にせず実装できるが、今の所、自分のコードはBasicにも収まる。
* （追記）M5Stack core2には非対応
 * 発売されたばかりのcore2を追加ゲットし、試したが、同じコードは動かないらしい。。そのうち調査したい。
* 表現の幅は段違い
 * LCDの解像度は320*240もある。16 * 2 文字制約に比べたら、もう何文字でも、しかも図形も描画できる。
 * カラー表示できる。スピーカも搭載されている（確か、Basicだけ無かった気がするが）。
 * という事で、もう本当言うことなし。
* 電鍵が使える
 * GPIOに電鍵つないで使える。
 * 電鍵、と言っても要はスイッチなので、片方の端子には入力用のGPIO、もう片方をGNDにつなげば良い。
 * M5Stack Fireの場合、GPIO 26 が使えるのでGROVEコネクタから上記2本の導線を取り出し、電鍵に接続する。
 * 自分はメルカリで中古の電鍵を4000円くらいで手に入れて使っている。


![IMG_3209D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/afaa564a-b254-e016-ca97-d8ed3012048a.jpeg)


* M5Stack単体でも使える
 * 電鍵の打ち心地は最高であることは間違いないが、持ってる人ってそんなにいない気がする。
 * せっかくM5Stack使うので、真ん中のBボタンをキーに割り当てる事で単体で使えるようにした。
 * 長時間の練習には向かないが、とにかく体験してみる、ってことはできる。

![IMG_3107D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/9180d863-fd18-71d2-3eb4-be2bf94fba09.jpeg)


# 符号化方式
* こちらのサイトを参考にさせて頂いた。
 * http://jh7ubc.web.fc2.com/arduino/CW_decoder.html
* モールス信号を8bitの中間コードで表現
 * dot（短音）は0、dash（長音）は1とし、先頭にスタートビット1を加えて末尾ビット詰めにする。
 * 先頭ビットからスタートビットまでは可変で0で埋める。
 * 例えば、a(トン、ツー)の場合だと 00000101（末尾の01がトン、ツー）になる。
 * この要領で、アルファベットとカナを表現する。

# 入力との紐付け
* 電鍵の場合
 * GPIOをプルアップしておき、スイッチがONになった時にLOWに落ちるようにし、digitalRead()する。
 * このLOWの時間を計測し、しきい値以下ならdot, しきい値以上ならdashとする。
 * 最後に HIGHの時間がdotの時間の3倍だったら1文字入力完了とし、そこまでの入力をモールス信号としてデコード処理する。
* M5Stackボタンの場合
 * これも同じ。digitalRead()がM5.BtnB.isPressed()になるだけ。

# GitHub
* という事で、以下に公開しました。
 * https://github.com/gitnabeshin/M5Stack_CWTrainer
* Zipでダウンロードするなり、git cloneなりして入手できます。
* Arduino IDEを起動し、M5Stack_CW_Trainer.inoを開いて自分のM5Stack構成でビルド＆書込み、で使えます。
 * （Arduino IDEでM5Stack用の開発環境構築手順はここに記載があります。）
 * https://docs.m5stack.com/#/en/arduino/arduino_development

![IMG_3204D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/c2c8b844-188d-63e1-5468-b24f1b0e6d7d.jpeg)


# 特徴
* 選べる入力方法
 * 電鍵（M5Stack の入力用GPIO を使用します。）
 * M5Stack Bボタン（M5Stack単体で使えます。電鍵が無くてもお手軽に練習が可能です。）
* 言語
 * 英語
 * 日本語（かな）
* トレーニングモード
 * NEXTボタンを押す度に画面上部に次の文字と信号図形が表示され、そのモールス信号音が出ます。
 * お手本に習い、電鍵、またはM5Stackボタンで信号をインプットします。
 * 正解なら、自動で次の文字に切り替わります。正解するまで何度もリトライできます。
* フリーモード
 * 画面全体を使い、長文のインプットが練習できます。
 * お手本の表示は無いので、慣れた方向けのモードです。 
* WEB画面からのモールス信号変換
 * Wifi接続したPC、スマホ、タブレットで入力した単語をモールス信号に変換できます。
 * 変換可能な文字は、英語、日本語（ひらがな、カタカナ）です。
 * M5StackはSoftAPモードで起動するため、Wifiルータは不要です。
 * アクセスポイント名、パスワードは、TrainerConfig.h で変更可能です。
 * 接続先のURLはメニュー画面からQRコードとして表示されます。
* 単音信号の判定時間が調整可能 
 * ゆっくり練習したい初心者向けに、メニュー画面から単音信号の判定時間を延長することができます。
 * 10ms単位で時間を伸ばすことが可能です。
* メニュー画面
 * 上記は全てメニュー画面から設定出来ます。
 * 初期設定値を変更したい場合は、TrainerConfig.hを書き換えます。
* WiFiステータスとバッテリ残量表示
 * 画面の右上端にWiFiアクセスポイント有効状態ステータスを表示
 * その隣にバッテリ残量を表示

## 日本語モードを使う場合
* 日本語を表示するには、SDカードのルートディレクトリにフォントファイル"*.vlw"を格納しておく必要があります。
  * こちらのコードでは、フリーの"genshin-regular-16pt.vlw" を使用しています。
  * （こちらから入手可能です。 http://jikasei.me/font/genshin/ ）

## 初期設定
* **TrainerConfig.h**

```
// ------------------------
//  Default configuration 
// ------------------------
#define DEFAULT_INPUT_METHOD  INPUT_M5_BTN_B          //M5Stack Button (or INPUT_TELEGRAPH_KEY)
#define SET_DEFAULT_LANG()    MODE_setEnglishMode()   //MODE_setJpMode();
#define DEFAULT_DOT_TIME      (140)                   //Time of dot period detection(ms)
#define TELEGRAPH_KEY_GPIO    (26)                    //TELEGRAPH_KEY GPIO 26 (for INPUT_TELEGRAPH_KEY)

// --------------------------
// ESP32 SoftAP Configuration
// --------------------------
#define TRAINER_SSID          "M5_CWTrainer"
#define TRAINER_PASS          "m5stack"
#define TRAINER_IP_ADDR       192,168,0,12
#define TRAINER_SUBNET        255,255,255,0
```

# 操作画面

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">M5stack モールス信号トレーナーのUIアップデート、日本語モードでも使えます。<br>あとWi-Fiとバッテリ残量表示も追加、オマケで電源OFFアクションも追加しました。M5stack こんなに機能盛り込んで動くの凄い！<br>そろそろコード公開しようと思います。<a href="https://twitter.com/hashtag/M5Stack?src=hash&amp;ref_src=twsrc%5Etfw">#M5Stack</a> <a href="https://t.co/6qeJzgdmhj">pic.twitter.com/6qeJzgdmhj</a></p>&mdash; Nabeshin (@desmoquattro996) <a href="https://twitter.com/desmoquattro996/status/1317629433415487488?ref_src=twsrc%5Etfw">October 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

![IMG_3198D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/ea86539f-12cc-fddd-cf7a-61b5ca2f2083.jpeg)

![IMG_3200D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/fff29819-e1bf-4c52-5197-03075eac466d.jpeg)


* 電源ONで、トレーニングモードで起動。
 * NEXT ボタン押下で練習開始。
 * Bボタンで信号入力。
 * MENUボタン押下で、メニュー画面に切り替え。

* メニュー画面
 * SCROLL で項目を切替え、OKで選択。
 * SAVE&EXT で再び練習モードに復帰。

![IMG_3201D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/36e16d86-43b3-42d8-d6d5-7a07d7ffa08d.jpeg)


* スマホからのエンコード画面を表示するための情報はこれ。
 * パスワードは表示しないようにしてあります。
 * **TrainerConfig.h** でお好きなものを指定できます。

こんな感じでエンコードできます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">M5Stack モールス信号デコーダ、<br>スマホから入力した任意の文字をM5Stack側でエンコード出来るようにした。<br>この機能、直感的でめっちゃ良い！！<br><br>耳で聞き取った音のリズムを覚えて、そのまま入力できちゃう。 <a href="https://t.co/YOqea5ZgjU">pic.twitter.com/YOqea5ZgjU</a></p>&mdash; Nabeshin (@desmoquattro996) <a href="https://twitter.com/desmoquattro996/status/1308036863244947457?ref_src=twsrc%5Etfw">September 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# さいごに
* M5Stackを使った構成ならでは、のアイデアじゃ無いでしょうか？
 * あの発明王エジソンは、モールス信号でプロポーズしたらしい。
 * あとはこれで（我が家のように）小学生の子供とくだらない言葉を練習するもよし、
 * 本格的にアマチュア無線資格獲得に向けて勉強するもよし、
* 個人的には、次回ラピュタ放送日が何よりも楽しみです。（笑