SORACOMとM5Stackを使ってポケベルを現代に復刻させた

本記事は[SORACOM Advent Calendar 2020](https://qiita.com/advent-calendar/2020/soracom)の8日目の記事です。
昨日は@0x6bさんの[SORACOM Napter で簡単に SSH できる nssh を作りました](https://0x6b.github.io/nssh/)という記事でした。SIMの名前でSSHできるのはとても便利ですね！

さて今回、SORACOMとM5Stackを使って**「ポケベル」**を2020年の現代に復刻させてみました。
完成したシステムの動画を上げていますので、そちらを見てもらえるとイメージしやすいかと思います。

https://twitter.com/Y_uuu/status/1336091773240688643
<a href="https://twitter.com/Y_uuu/status/1336091773240688643" target="_blank">![マイムービー 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/3a776bed-f49e-f7eb-9ff3-10257c80f6d9.jpeg)</a>

M5StackとSORACOM, AWSを組み合わせて作っています。(詳しくは後述)

![Untitled_pokebell_-_Cacoo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/b734e022-c264-7715-e779-36747e4b736b.png)

## ポケベルとは

こんな感じの端末へ電話機を使ってメッセージを送信できるサービスです。
![pocket_bell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/7a1dfca3-4590-3226-4ea8-d6bed46016e6.png)
Wikipediaだと[無線呼び出し](https://ja.wikipedia.org/wiki/無線呼び出し)というタイトルで解説がされていますね。


当初は数字しか送れなかったのですが、1990年代後半にカタカナやアルファベットを送信できるようになったことをきっかけに、ビジネスマンはもちろん、当時の中高生の間でもブームになったようです。

会社の先輩曰く、「高校で休憩時間に公衆電話待ちの行列ができるほど」のブームだったとか。

ちなみに筆者自身、ポケベルを知らない世代です。高校入学時に買ってもらった携帯電話はDocomo SH901iCでした。

## 当時のポケベルの仕様

「ポケベル」がどういったサービスなのかイメージできない人も多いと思うので、使い方をざっくり解説します。

### 入力の開始と終了

当初のポケベルは上述の2タッチ入力には対応しておらず、「発信後、入力した数字がそのまま送信される」というものでした。つまり、「084」と入力すれば「084(おはよう)」がそのまま送信されます。その後、2タッチ入力に対応して以降、「*2*2」と入力することで、2タッチ入力モードへ切り替えることができるようになりました。

「##」と入力すると、入力を終了し、メッセージを送信します。

### 2タッチ入力

いわゆる[ポケベル打ち](https://ja.wikipedia.org/wiki/2%E3%82%BF%E3%83%83%E3%83%81%E5%85%A5%E5%8A%9B)です。下のような表が定義されていて、電話機で2つのキーをダイヤルすると、その組み合わせで文字列が打ち込まれます。

<table class="wikitable">
<tbody><tr>
<td colspan="2" rowspan="2">
</td>
<th colspan="10">2 桁 目
</th></tr>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>0
</th></tr>
<tr>
<th rowspan="10">1<br>桁<br>目
</th>
<th>1
</th>
<td>あ</td>
<td>い</td>
<td>う</td>
<td>え</td>
<td>お</td>
<td>Ａ</td>
<td>Ｂ</td>
<td>Ｃ</td>
<td>Ｄ</td>
<td>Ｅ
</td></tr>
<tr>
<th>2
</th>
<td>か</td>
<td>き</td>
<td>く</td>
<td>け</td>
<td>こ</td>
<td>Ｆ</td>
<td>Ｇ</td>
<td>Ｈ</td>
<td>Ｉ</td>
<td>Ｊ
</td></tr>
<tr>
<th>3
</th>
<td>さ</td>
<td>し</td>
<td>す</td>
<td>せ</td>
<td>そ</td>
<td>Ｋ</td>
<td>Ｌ</td>
<td>Ｍ</td>
<td>Ｎ</td>
<td>Ｏ
</td></tr>
<tr>
<th>4
</th>
<td>た</td>
<td>ち</td>
<td>つ</td>
<td>て</td>
<td>と</td>
<td>Ｐ</td>
<td>Ｑ</td>
<td>Ｒ</td>
<td>Ｓ</td>
<td>Ｔ
</td></tr>
<tr>
<th>5
</th>
<td>な</td>
<td>に</td>
<td>ぬ</td>
<td>ね</td>
<td>の</td>
<td>Ｕ</td>
<td>Ｖ</td>
<td>Ｗ</td>
<td>Ｘ</td>
<td>Ｙ
</td></tr>
<tr>
<th>6
</th>
<td>は</td>
<td>ひ</td>
<td>ふ</td>
<td>へ</td>
<td>ほ</td>
<td>Ｚ</td>
<td>？</td>
<td>！</td>
<td>－</td>
<td>／
</td></tr>
<tr>
<th>7
</th>
<td>ま</td>
<td>み</td>
<td>む</td>
<td>め</td>
<td>も</td>
<td>￥</td>
<td>＆</td>
<td>機</td>
<td>機</td>
<td>機
</td></tr>
<tr>
<th>8
</th>
<td>や</td>
<td>（</td>
<td>ゆ</td>
<td>）</td>
<td>よ</td>
<td>＊</td>
<td>＃</td>
<td></td>
<td>機</td>
<td>機
</td></tr>
<tr>
<th>9
</th>
<td>ら</td>
<td>り</td>
<td>る</td>
<td>れ</td>
<td>ろ</td>
<td>１</td>
<td>２</td>
<td>３</td>
<td>４</td>
<td>５
</td></tr>
<tr>
<th>0
</th>
<td>わ</td>
<td>を</td>
<td>ん</td>
<td>゛</td>
<td>゜</td>
<td>６</td>
<td>７</td>
<td>８</td>
<td>９</td>
<td>０
</td></tr></tbody></table>
※[Wikipedia](https://ja.wikipedia.org/wiki/2%E3%82%BF%E3%83%83%E3%83%81%E5%85%A5%E5%8A%9B)より引用

つまり、「65 05 24 64 04 93」と入力すれば「ホ゜ケヘ゛ル」と表示できるということです。

## 復刻版ポケベルの仕様

当時のポケベルの仕様に思いを馳せつつ、以下のような仕様で作ることにしました。

### 送信

公衆電話を模擬した端末を製作し、当時のポケベルと同様数字キーを入力することでメッセージを送信します。
ただし、「入力した数字がそのまま送信される」という動作は実装せず、2タッチ入力のみ対応とします。2タッチ入力しかできないのですが、入力開始時には「*2*2」の入力が必要です。

### 受信

当初、受信したメッセージをSlackの専用チャンネルへ自動投稿する仕様としていました。
![Slack___iot-poc___fusic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/d9580c61-bf82-ac41-5476-10571b8586c5.png)
実際に作ってみて、「これポケベルじゃなくない？」「なんか味気ない」といった気持ちが湧いてきたので、受信機も自作することにしました。

本当はTwilio経由でSMS送信できると、当時のポケベルをより忠実に再現できるのですが、Sigfoxだと1回のデータ送信を12バイト以内に抑える必要があり、電話番号を送信すると肝心のメッセージをほとんど送信できなくなってしまうため断念しました。「要件より先に手段を決めてしまうと、こうなるよ」というよくある失敗例なので、お仕事では気をつけましょう。

## システム構成

![Untitled_pokebell_-_Cacoo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/b734e022-c264-7715-e779-36747e4b736b.png)
当初は[SORACOM Orbit](https://soracom.jp/services/orbit/)を使って、2タッチ入力→カタカナ変換を実装する予定でした。しかし、Soraletを作成しても一向に変換される様子がなく、サポートへ問い合わせることに。

結論としては、「SORACOM OrbitはSORACOM Air for Sigfoxに対応していない」とのこと。[制限事項](https://dev.soracom.io/jp/orbit/limitations/)の冒頭に書いており、完全に私の確認不足でした。

このため、[SORACOM Funk](https://soracom.jp/services/funk/)を使って、AWS Lambdaへ転送する作戦に変更しました。処理の流れとしては以下の通りです。

1. ユーザが送信機を使ってメッセージ(数字の羅列)を入力→送信する
2. SORACOM FunkにてAWS Lambdaへ直送する
3. AWS Lambdaがメッセージ(数字の羅列)をメッセージ(日本語)に変換し、SlackとAWS IoT Coreへ転送する
4. 受信機がSORACOM Beam経由でAWS IoT Coreのtopicをsubscribeする
5. 受信機が受信したメッセージを表示する

## システムの構成要素

### マイコン: M5Stack

みんな大好きM5Stackです。ポケベルにおける発信機(つまり公衆電話の代わり)・受信機として使います。

![iOS_の画像__5__jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/05a5ac8c-92fd-ebef-73c2-df9c6c0bbe80.png)
https://www.switch-science.com/catalog/3647/

「手元にあったから」というのが正直な選定理由ですが、筐体自体コンパクトで簡単に他機器と接続でき、プログラミングも容易という点で、結果的に良い選択だったと思っています。

### 数字キー: Qwiic - キーパッド（12ボタン）

当初は自分で数字キーを自作することも視野にあったのですが、こんな製品を見つけました。

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

まさに今回作りたい送信機のキーにうってつけです。
![YuheiOkazakiさんはTwitterを使っています_「M5StackでQwiicキーパッドの入力をLCDに表示するところまではいけた。これがピッタリ収まるケースを3Dプリンタで作りたい_https___t_co_e2aDzHr2jQ」___Twitter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/58169890-b9d3-697d-624c-bf1b6d8856ff.png)
接続方法を確認したところ「Qwiicシステム」というI2C通信を行うための4ピンコネクタであることが確認できました。自分で接続しても良かったのですが、変換ケーブルが見つかったのでこれを利用することで簡単に接続できました。

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

### 送信機の通信手段: SORACOM Air for Sigfox
![iOS_の画像_jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/fc66e3f3-6b95-5119-d90a-81857f0aee3c.png)
「Sigfox通信でSORACOMを利用したい」という思いだけで選定しました。3Gと比較してデバイスや通信のコストを約半分に抑えられるのが魅力です。

代償として以下のような制約があります。

- 1回にできる送信データは最大12バイト
- 1日の最大送信回数は140回
- 通信速度は100bps

実際にやってみた感想としては「なかなかキツイ制約」でした。
Sigfoxを使ってみたい方は、この制約を受容してでもコストを下げたいか吟味するようにしましょう。

### 受信機の通信手段: SORACOM Air for セルラー plan-D
![iOS_の画像__3__jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/5d0c3930-7976-fd5a-ad64-b43c7c8ad719.png)
既にお察しかもしれませんが、Sigfoxは下りの通信回数が4回/日に制限されており、受信側SIMとして使用するのは非常に困難です。
やむを得ず、急遽[M5Stack用 3G 拡張ボード](https://soracom.jp/products/kit/3g_module_m5stack/)とplan-DのSIMを発注し、これを使うことにしました。

## 送信機の組み立て

当初は、M5StackとキーバッドをGrove-Qwiic変換ケーブルで接続するだけの予定でした。
しかし、これだと収まりが悪く使い勝手もよくありません。

弊社の後輩が自宅に3Dプリンターを持っていると聞いていたので、ピッタリ収まるケースを作ってもらうことにしました。ケースに入れると一気に完成度が増しますね。
![iOS の画像 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/92638be8-e86e-aefa-4015-0a3077e35cbd.jpeg)
ケースにキレイに収める都合上、GroveコネクタではなくM5Stack下部のピンを利用するようにしました。(実際は、後輩が気を利かせて変えてくれたらしく、納品されてしばらくしてから気づきました。職人！！！)

ちなみに、色は一般的な公衆電話をイメージして選定しています。

## 送信機のプログラム

長いので興味がある方はGitHubを参照ください。

https://github.com/yuuu/pokebell/blob/master/arduino/sender/pokebell.ino

以下、ポイントです。

- Sigfoxを使った通信処理を書く際には参考になるかと思います。(ほぼSORACOMさんが公開されているサンプルですが...)
- [DTMF](https://ja.wikipedia.org/wiki/DTMF)(いわゆるダイヤル音)を可能な範囲で再現しています。M5Stackで合成音を出すのは難しいので、高音側のみです。
- 入力された数字は4bit単位でpackingして送信しています。従って1回の送信で `12byte * 8bit / 4bit = 24ダイヤル = 12文字` まで入力可能です。

## 受信機のプログラム

こちらも長いので興味がある方はGitHubを参照ください。

https://github.com/yuuu/pokebell/blob/master/arduino/receiver/pokebell.ino

以下、ポイントです。

- 3G SIMを使った通信処理を書く際には参考になるかと思います。(ほぼSORACOMさんが公開されているサンプルですが...)
- LCDに日本語を表示するために、外部フォントを読み込んでいます。
- ポケベル感を出すために着信音を再現しています。

## AWS Lambdaのプログラム

やっぱり長いので、興味がある方はGitHubのソースコードを参照ください。

https://github.com/yuuu/pokebell/blob/master/funk/app.rb

以下、ポイントです。

- AWS SAMを使いました。
- 言語はRubyを使っています。簡単に書けるのが良いですね。
- Slackへの投稿はIncoming Webhookを使っています。
- AWS IoT Coreへのpublishは[AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/)の[Aws::IoTDataPlane::Client](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/IoTDataPlane/Client.html)を使いました。
- Lambdaに付与しているRoleに `iot:publish` のPolicyを付与しておけば認証を省略できます。
- 2タッチ入力の変換処理は以下のようにテーブルを作た上で、数字を2文字ずつ取り出して変換しています。

```ruby
TABLE = [
  # 0     1     2     3     4     5     6     7     8     9
  [ '０', 'ワ', 'ヲ', 'ン', '゛', '゜', '６', '７', '８', '９' ], # 0
  [ 'Ｅ', 'ア', 'イ', 'ウ', 'エ', 'オ', 'Ａ', 'Ｂ', 'Ｃ', 'Ｄ' ], # 1
  [ 'Ｊ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'Ｆ', 'Ｇ', 'Ｈ', 'Ｉ' ], # 2
  [ 'Ｏ', 'サ', 'シ', 'ス', 'セ', 'ソ', 'Ｋ', 'Ｌ', 'Ｍ', 'Ｌ' ], # 3
  [ 'Ｔ', 'タ', 'チ', 'ツ', 'テ', 'ト', 'Ｐ', 'Ｑ', 'Ｒ', 'Ｓ' ], # 4
  [ 'Ｙ', 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', 'Ｕ', 'Ｖ', 'Ｗ', 'Ｘ' ], # 5
  [ '／', 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ', 'Ｚ', '？', '！', 'ー' ], # 6
  [ '　', 'マ', 'ミ', 'ム', 'メ', 'モ', '￥', '＆', '　', '　' ], # 7
  [ '　', 'ヤ', '（', 'ユ', '）', 'ヨ', '＊', '＃', '　', '　' ], # 8
  [ '５', 'ラ', 'リ', 'ル', 'レ', 'ロ', '１', '２', '３', '４' ], # 9
]

data = JSON.parse(event['payload'])['data'] if event['payload']
message = data.chars.each_slice(2).map do |row, col|
  TABLE[row.to_i][col.to_i]
end
message.join
```

## 動作確認

冒頭の動画の通りです。
送受信は行えているのですが、仕組み上時間がかかるのが難点ですね。

https://twitter.com/Y_uuu/status/1336091773240688643
<a href="https://twitter.com/Y_uuu/status/1336091773240688643" target="_blank">![マイムービー 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/3a776bed-f49e-f7eb-9ff3-10257c80f6d9.jpeg)</a>

## 考察

2020年に復刻させたポケベルと、1990年代ポケベルの仕様を比較してみました。

|観点|1990年代後半|2020年|
|---|---|---|
|文字数制限|およそ14文字|12文字(Sigfoxの制約)|
|回数制限|300回/月まで受信可、以降は追加料金発生|140回/日(Sigfoxの制約です)|
|送信速度|ほぼ即時送信(のはず)|送信→受信までに30秒ほどかかります(Sigfoxの制約で通信速度が100bpsであることがボトルネックになっています)|
|送信コスト|通常の電話料金/回|SORACOM Air for Sigfox 通信料金: 1440円/年<br>SORACOM Air for Sigfox デバイス登録料金: 1440円/年<br>※各種クラウドサービスの料金は微々たるものなので省略 |
|受信コスト|基本料金およそ2000円/月|SORACOM Air for セルラー  plan-Dの基本料金: 10 円/日<br/>SORACOM Air for セルラー plan-Dの通信料金: 0.2 円/MB|

Sigfoxの制約があるとはいえ、当時のポケベルよりもコストパフォーマンスが良さそうです。
筆者自身ポケベルを使ったことはありませんが、良い時代になったなあと実感しました。

## 感想

ポケベルを使ったことがない世代が、ポケベルを使った感想です。ご査収くださいm(_ _)m

- 2タッチ入力が面白い。脳トレ感がある！
- 文字数が非常に少ないので、ミスコミュニケーションが頻発しそう。
- Slack、Zoomといった多様かつ高度なコミュニケーション手段があることは、非常に恵まれているのだと改めて実感しました。

余談ですが、このネタのためだけにSigfoxと3G SIMのデバイスを自費購入し、個人用のSORACOMアカウントも作成したので、2021年はSORACOMにどっぷり浸かってもっと面白いことをしたいと思います。

## まとめ

SORACOMとM5Stackを使って、ポケベルを現代に復刻させることができました。
ポケベル世代の皆さまからの感想やフィードバックをお待ちしております。

## 参考資料

https://gist.github.com/ma2shita/1784800f5bf4bf376b6e86fed7b7beae
https://qiita.com/ma2shita/items/fef1608fc9cf3a7bd46a
https://blog.soracom.com/ja-jp/2020/10/15/howto-use-sigfox-module-for-m5stack-with-soracom-air/