RN4020でUARTをつかってtoioコア キューブを動かしてみる

# RN4020でUARTをつかってtoioコア キューブを動かしてみる
　toioコア キューブはBLE通信で制御できる「とてもかわいい」二輪ロボットです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/58299e82-b770-36a7-aa3f-fbdade4d7f5c.jpeg" alt="toio core cube" width=50%>


　これまで、スマートフォンのアプリ、パソコンのpythonライブラリを使い、BLEを直に使ってtoioコアキューブを動かす方法を記事にしてきました。

* [Android/iOSアプリのLightBlueでtoioコア キューブを動かしてみる](https://qiita.com/kenichih/items/ef5fde749c9a20bfa2bc)
* [Pythonライブラリ bleakでWindows10/macOS/Linux上でtoioコア キューブを動かしてみる](https://qiita.com/kenichih/items/8baa27b3aecc94dd8193)

　スマホ、パソコン、ときて今度はUARTを使ってtoioをうごかします。まあ、RN4020を使うんですが。

　本記事は[toio™(ロボットトイ | toio（トイオ）) Advent Calendar 2019](https://qiita.com/advent-calendar/2019/toiotomo)の一つとして準備していたのですが、書き終えるよりも前にカレンダーのスロットが埋まってしまい、Advent Clenderには載せられなかったものです。(笑)

　BLEもUSBも使えないパソコン、マイコンでもUARTが使えればRN4020をつないでtoioコアキューブを動かすことができます。

## mirochip RN4020って？

microchip社のUART-BLE変換モジュールです。
https://www.microchip.com/wwwproducts/en/RN4020

BLEのペリフェラル、セントラルどちらとしても使え、UARTで制御することができます。

通信仕様についてはこちら
[RN4020 Bluetooth® Low Energy モジュール ユーザガイド](http://ww1.microchip.com/downloads/jp/DeviceDoc/70005191A_JP.pdf)

ただ、RN4020単体だと端子のピッチが2mmなので工作には向きません。
秋月電子通商で2.54mmへのピッチ変換＆電源変換の機能のついたボードがありますのでそちらのほうがおすすめです。
[ＲＮ４０２０使用　Ｂｌｕｅｔｏｏｔｈ　Ｌｏｗ　Ｅｎｅｒｇｙ　モジュール [AE-RN4020-XB]](http://akizukidenshi.com/catalog/g/gK-11102/)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/10c278e5-10fa-8719-5ed0-833bdb35b166.jpeg" alt="AE-RN4020-XB" width=50%>

3.3V、5.0V両対応なので、Arduino、Teensy、Feather、IchigoJam、Maix、M5StickVなどなど。いろいろなものにそのまま直結で使うことができます。

## まずはPCに繋いで試してみます。

　一応本記事でも解説はしますが、こちらの記事を参照いただくほうがわかりやすいと思います。
　[RN4020をBLEセントラルとして利用する。](http://masato-ka.hatenablog.com/entry/2017/12/10/222043)

### 準備
- USBとシリアルターミナルが使えるPC、またはRaspberry Pi
- USBシリアル変換アダプタ 
    - [FTDI USBシリアル変換アダプター](https://www.switch-science.com/catalog/2782/) がおすすめです。ソケットの端子配列がAE-RN4020-XBのピン配列と揃っているので、AE-RN4020-XBにヘッダピンをつければそのまま挿して使えます。
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/85ad9437-8dc1-f5b8-872c-0050daae0cfa.jpeg" width=50%>

- PCまたはRaspberry PiとAE-RN4020-XBを繋ぎます。
- Raspberry Piの場合は、USBポートに[FTDI USBシリアル変換アダプター](https://www.switch-science.com/catalog/2782/)を使って繋いでもいいですが、RaspberryPiのGPIOポートの+5V(2)、GND(6)、TxD(8)、RxD(10)と、AE-RN4020-XBを直接ジャンパケーブルでつなぐやり方もあります。

### シリアルターミナルの設定と接続確認

　Windowsの場合はtera termなどのシリアルターミナルアプリを、MacOSやraspbianなどの*nix系OSではscreenコマンドなどを使ってRN4020をつないだシリアルポートを開きます。
　シリアルポートの設定は8N1 いわゆる 8bit nonパリティ、ストップビット1、baud rateは115200、フロー制御なしに設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/d05a19e6-e476-9f8d-40fe-7551719d7289.png" alt="tera termでの設定例" width=50%>
tera termでの設定例

　RN4020はデフォルトではローカルエコーなしないので、ターミナルアプリで打ち込んだコマンドが表示されずにわかりにくいため、以下では「+」コマンドでローカルエコーありに設定します。

```
+　　　ローカルエコーオン
Echo On
SF,1 　工場出荷値にリセット。必要があれば。
AOK
H　　ヘルプの表示 とはいっても以下の一行が出るだけ、
Details in User Guide
```

コマンドの結果が表示されればうまく通信できています。

　さらに、RN4020を「SR」コマンドでセントラルモードに設定します。設定を有効にするには「R」コマンドで再起動コマンドが必要です。

```
SR,80000000
AOK
R,1
Reboot
CMD
```

RN4020が再起動後にSRコマンドの設定が有効になります。一度設定を有効にしておくと工場出荷リセットをしない限りこの設定は有効です。

再起動するとエコーバックはオフになるので、以下の説明で分かりやすくするために再度、オンにしておきます。

```
+
Echo On
```
　

### toio コアキューブの発見と、デバイスアドレスのメモ

　まずはtoioコアキューブを発見し、デバイスアドレスをメモします。

　toioコアキューブの電源をオンにし、「F」コマンドを入力します。周辺にあるBLE機器の一覧が表示されます
　デバイスアドレス、属性、128bit Service UUIDs、電波強度が表示されます。
　128bit Service UUIDが「10B201005B3B45719508CF3EFCD7BBAE」のものがtoioコアキューブです。とはいえ、ぱっと見ではどれがtoioコアキューブなのかわかりにくいので、RN4020の近くにtoioコアキューブを置いてFコマンドを使い、一番強度が強いものを探すという手もあります。

　以下の説明で出てくるデバイスアドレスは仮のものです。デバイスアドレスは個々のtoioコアキューブで違いますので、お手元のtoioコアキューブでは違う値になります。

```
F
AOK
F91F6F1D3A25,1,,10B201005B3B45719508CF3EFCD7BBAE,-27
D08B7F373CC5,1,,10B201005B3B45719508CF3EFCD7BBAE,-1E
B052164A564E,0,,CBBFE0E1F7F2340684E084CBB3D09DFC,-4C
X
AOK
```

　「F」コマンドはずっとと機器の発見を続けますのでXコマンドでBLE機器の発見を終了します。

上の例では、一番上とその次の「F91F6F1D3A25,1,,10B201005B3B45719508CF3EFCD7BBAE,-27」と「D08B7F373CC5,1,,10B201005B3B45719508CF3EFCD7BBAE,-1E」がtoioコアキューブです。電波強度としては２番目のほうが強いので、一番近いtoioコアキューブであろうデバイスアドレス「D08B7F373CC5」をメモしておきます。

### 接続、キャラクタリスティック一覧とハンドルの確認

　先ほど確認したデバイスアドレスを使って、まずはtoioコアキューブに接続します。「E」コマンドの後に、属性「1」、デバイスアドレス「D08B7F373CC5」の順で指定します。

```
E,1,D08B7F373CC5
AOK
Connected
ConnParam:0040,0000,0190
```

　接続できると、toioコアキューブからおなじみの接続音「♪ピロピロピー」が聞こえます。

　つづいて「LC」コマンドでキャラクタリスティック一覧を表示します。

```
LC
10B201005B3B45719508CF3EFCD7BBAE
  10B201015B3B45719508CF3EFCD7BBAE,000D,02
  10B201015B3B45719508CF3EFCD7BBAE,000E,10
  10B201025B3B45719508CF3EFCD7BBAE,0011,04
  10B201025B3B45719508CF3EFCD7BBAE,0012,10
  10B201035B3B45719508CF3EFCD7BBAE,0015,08
  10B201045B3B45719508CF3EFCD7BBAE,0018,08
  10B201065B3B45719508CF3EFCD7BBAE,001B,02
  10B201065B3B45719508CF3EFCD7BBAE,001C,10
  10B201075B3B45719508CF3EFCD7BBAE,001F,02
  10B201075B3B45719508CF3EFCD7BBAE,0020,10
END
```

　キャラクタリスティックのUUID(例えば10B201015B3B45719508CF3EFCD7BBAE)、ハンドル(例えば000D)、パーミッション(例えば02)が表示されます。
　UUIDの意味は[toioコアキューブ通信仕様](https://toio.github.io/toio-spec/docs/ble_communication_overview.html)を参照してください。例えば「10B201015B3B45719508CF3EFCD7BBAE,000D,02」は[読み取りセンサーのキャラクタリスティック](https://toio.github.io/toio-spec/docs/ble_id)です。
　ハンドルはこのあとに説明する読み(read)、書き(write)、通知(nitify)の受信、のために使うIDです。
　パーミッションは、ぞれぞれのキャラクタリスティックの特性を示します。上にある例では以下のような意味になっています。

|値|意味|
|:--|---|
|02|read|
|04|write without rsponse|
|08|write|
|10|notify|

### モーションセンサーの値を読む、LED点灯、モーターの回転、

　「LC」コマンドでキャラクタリスティックとハンドルがわかったなら、ハンドルを使って読み書きしてみます。

#### モーションセンサーの値を読む
　キャラクタリスティックの値を読むには「CHR」コマンドを使います。
　[モーションセンサーのキャラクタリスティック](https://toio.github.io/toio-spec/docs/ble_sensor)は「10B201065B3B45719508CF3EFCD7BBAE」で、「read」のハンドルを使うので、「001B」になります。

　以下はtoioコアキューブを天面を上(普通の置き方)、天面が下(裏返しで車輪が上)、正面が上(toioロゴが上)の状態で、「CHR,001B」したときの結果です。レスポンスの値が変化しており、５バイトめの姿勢検出の値がそれぞれの姿勢(どの面が上か)を表しています。

```
CHR,001B
R,0101000001.
CHR,001B
R,0101000002.
CHR,001B
R,0100000004.
```

#### LED点灯
　キャラクタリスティックに値を書き込むには「CHW」コマンドを使います。
　[LED点灯のキャラクタリスティック](https://toio.github.io/toio-spec/docs/ble_light)は「10B201035B3B45719508CF3EFCD7BBAE」なので「write」のハンドル「0015」を使います。書き込みたい値のバイト列をハンドルに続いて指定します。
　以下のの例ではLEDを160ms、赤色に点灯します。

```
CHW,0015,03100101FF0000
AOK
```

#### モーター
　もう一つ「CHW」コマンドで値を書き込む例です。
　[モーターのキャラクタリスティック](https://toio.github.io/toio-spec/docs/ble_motor)は「10B201025B3B45719508CF3EFCD7BBAE」なので「write with no response」のハンドル「0011」を使います。

　以下の例では左車輪を前に100の速度、右車輪を後ろに20の速度で動かします。

```
CHW,0011,01010164020214
AOK
```

　モーター停止は以下のようにします。(左右の車輪の速度をゼロにします)

```
CHW,0011,01010100020100
AOK
```

### ボタン状態、読み取りセンサーの状態の通知をうける

　「CHR」コマンドでは現時点の状態(キャラクタリスティックの値)を読むことができますが、状態が変化したときを知りたい場合は、ずっとそのキャラクタリスティックの値を読み続ける必要があります。通知(notify)を受けるようにすることで、状態(キャラクタリスティックの値)の変化が起きたことを随時知ることができます。
　通知を受けるようにするには「CHW」コマンドを使います

#### ボタンの通知開始
　[ボタンのキャラクタリスティック](https://toio.github.io/toio-spec/docs/ble_button)は「10B201075B3B45719508CF3EFCD7BBAE」なので「notify」のハンドル「0020」を使います。
 「0100」を書き込むと通知の開始、「0000」を書き込むと通知の終了になります。

```
CHW,0020,0100
AOK
```

　ボタンの通知を開始状態にしてtoioコアキューブのボタンを押すと以下のような通知が来ます。

```
Notify,001F,0180.
Notify,001F,0100.
```

　ボタンが押されたときが「0180」、ボタンが離されたときが「0100」と２バイトめの値で状態変化を知ることができます。


#### 読み取りセンサーの通知開始
　[読み取りセンサーのキャラクタリスティック](https://toio.github.io/toio-spec/docs/ble_id)は「10B201015B3B45719508CF3EFCD7BBAE」な
ので「notify」のハンドル「000E」を使います。

```
CHW,000E,0100
AOK
```

　toioコアキューブを「トイオコレクション」のマットやカードの上に置くと、座標位置などの変化があるたびに通知が来ます。

```
Notify,000D,016701C1009D007201C5009D00.
Notify,000D,016601C2009C007101C5009C00.
Notify,000D,016601C1009E007101C5009E00.
Notify,000D,016601C2009C007101C5009C00.
Notify,000D,016601C1009D007101C5009D00.
Notify,000D,016701C100A1007101C500A100.
Notify,000D,016601C100A1007001C500A100.
Notify,000D,016601C200A0007001C600A000.
Notify,000D,03.
```

　最後のNotify,000D,03.はマットからtoioコアキューブをはずしたときなど、「読み取りセンサーがtoio IDを読み取れなかった」ことを示します。 


<!--
## RN4020のスクリプト機能で動かしてみる

タイマーでLED点灯とモーター
-->

# まとめ
- RN4020を使うとシリアル通信を使ってtoioコアキューブを操作できるようになる
- BLE機能のないarduino、Raspberry Pi2、WHじゃないRaspberry Pi Zero、Ichigojam、シリアルポートしかないレトロPCなどに使えます。
- [M5StickV](https://www.switch-science.com/catalog/5700/)につないで使おうと思ってましたが、[UnitV](https://www.switch-science.com/catalog/6212/)が出たので今だと[M5StickC](https://www.switch-science.com/catalog/5517/) + [UnitV](https://www.switch-science.com/catalog/6212/)の組み合わせで同じことできますね。