Nefry BTとMIT App InventorをつかったandroidアプリとのBLE通信をやってみた話

#こんにちは
東海大学で学生をやっているものです．
[「研究室のみんなとNefry BTを使ってはじめIotデバイスをつくってみた」](https://qiita.com/minwinmin/items/d1f296b8a9cd1a2c22f6)の続きです．
さて，タイトルにもあるようにNefry BTを使ってAndroidアプリでBLE(Bluetooth Low Energy)による通信を行ってみました，という内容で書いてみます．
なので，いろいろ参考にしながらやってみました．
初心者なので，あまり詳しいことやよくわかっていないことが多いです．
それでも，ちょっとでも参考になれば幸いです．

実際につくってみたものはGithub上にあげています．
https://github.com/minwinmin/NefryBT_BLE_AndroidApp

#概要
・AndroidアプリからNefry BTをLチカさせる
・Nefry BTのversionは1.0.5を使用
　(Nefry BTの最新版だと何故かうまくいきませんでした…)
#マイコン側のプログラム
まず，Nefry BTに入っているサンプルプログラム(BLE_notify)を参考にして改良していきました．
では，説明していきます．
github上にあげたBLE_LED2_success.inoというプログラムを見ながらだとわかりやすいかと思います．

###UUIDの設定
まず，UUIDのSeviceとCharacteristicを設定しましょう．
これは，調べれば自動で生成してくれるサービスがあるので任意で設定してください．

```c++
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
```
###実現したい機能
Androidアプリのボタンが押されたら，Nefry BT上のLEDがランダムに光が変化するプログラム．
そこで，このプログラムでは下記のように，何か「文字列」がアプリから送られてきたらLEDの発光がランダムに変化するというようになっています．

```c++
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic2) {
      std::string j = pCharacteristic2->getValue();
         
         randomSeed(analogRead(A0));
         
         if (j.length() > 0) {
         red=random(255);          //random関数は0-255の数値をランダムに返します。
         green=random(255);
         blue=random(255);
         Nefry.setLed(red,green,blue);
         delay(1000);
         Nefry.println("On");   
         }else{
         Nefry.println("Off");
         }
    }
};
MyCallbacks myCallbacks;//名前を端的にわかりやすくした
```

###BLEの初期設定
```c++
// Create the BLE Device
  BLEDevice::init("MyESP32");

  /////////////////////////////////////////////////////////////////////
  //BLEServer *pServer = BLEDevice::createServer();
  BLEServer *pServer = new BLEServer();
  ///上の2行は同じ意味のようだが，Nefry BTのバージョンによってエラーが出るので，その都度，どちらかを置き換えて使うこと．
  ///最新のバージョンだと上の一行が正しい
  //////////////////////////////////////////////////////////////////////
```

```c++
   // Create the BLE Service
  BLEService *pService2 = pServer->createService(SERVICE_UUID2);
   //serviceのどういうことをやるかをcharacteristic(特性)を指定する，READ，WRITEなど 
  BLECharacteristic *pCharacteristic2 = pService2->createCharacteristic(
                                         CHARACTERISTIC_UUID2,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic2->setCallbacks(&myCallbacks);//特性を指定したclassにもどす．機能の追加には＆をつける．classはpythonみたいな感じ．読み込んだ値なども格納されている．
  pCharacteristic2->setValue("Hello");
　pService2->start();
```

```c++
pServer->getAdvertising()->start();
```
こんな感じで一通りvoid setup()の中にプログラムを書きます．

#Androidアプリ
「Androidアプリをつくってみた」といっても，Android studioを使いこなせるだけの技術力があるわけではないので，お手軽にアプリをつくれる(はず)の[MIT App Inventor](http://appinventor.mit.edu/explore/)というものを使ってみました．まずは上記のサイトにアクセスしましょう．
そして，まず，Github上にあげたプログラムを動かしてみましょう．
https://github.com/minwinmin/NefryBT_BLE_AndroidApp/tree/master/Androidapp_BLE

###MIT app inventorの導入とBLE機能の追加
1．MIT app inventorにアクセス
上記のアドレスにアクセスして，Creat apps!をクリック.
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/212276/6b721daa-5830-58ff-cfb6-faacdff47510.jpeg)

2．BLE機能を追加
MIT App InventorでBLE機能を使うにはライブラリをいれる必要があります．
フォルダ内にある「edu.mit.appinventor.ble.aix」を下記の手順でいれてください．まず，「start new project」で新規プロジェクトを作成してください．
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/212276/dccfab06-894a-7d48-9f3a-78906e9061fc.jpeg)
左にある「Extension」をクリックし先ほどのaixファイルをimportしてください． 
![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/212276/b9ebbe5c-0db2-d6fc-509f-43d2710db812.jpeg)
これでBLE機能が使えるようになるはずです．

3．プログラムをimport
下記の画像のように，BLE_NefryBT.aiaをimportしてください． 
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/212276/37307eed-14d2-4f97-d64f-32858e991d45.jpeg)
このように出るはずです．
![図6.png](https://qiita-image-store.s3.amazonaws.com/0/212276/17ef89ea-db98-1517-99bb-1c7f02e17109.png)


4．プログラムの動作確認
上部にあるconnectをクリックします．
次に「Al companion」をクリック.QRコードと文字列が出てきます．これをアプリ側でQRコードを読み込むか文字列を入力します．アプリについて下記に示します．
![図7.png](https://qiita-image-store.s3.amazonaws.com/0/212276/12ec6e0b-e314-b047-1b67-8cd99232bf2c.png)
例えば，下記のような感じ
![図8.png](https://qiita-image-store.s3.amazonaws.com/0/212276/8620af47-54a2-5e5b-3ed9-12f24f5c5993.png)

5．Androidのスマートフォンに「MIT AI2 Companion」というアプリを導入
ダウンロードし，起動したら4で現れたQRコードもしくはコードを入力したらアプリが起動します．(アプリをapk形式に出力し，直接，スマートフォンにインストールするという方法もあります．)
![6.jpg](https://qiita-image-store.s3.amazonaws.com/0/212276/114837c0-a439-00a5-9101-3d098c601fb9.jpeg)

###アプリ側の使い方
![図９.png](https://qiita-image-store.s3.amazonaws.com/0/212276/2ef35612-3fa5-a4a1-ca3a-589fa2addc7e.png)
1．スマートフォンのBluetooth設定をonにしてアプリ上で「scan」を押す
2．「Available Devices」を選択し，Nefry BT側で設定したデバイス名を選択する．これでペアリングが完了
3．「Control」を押すことで，Nefry BT上でLチカができます．(下のgif画像よりわかると思います．)
![LチカBLE.gif](https://qiita-image-store.s3.amazonaws.com/0/212276/a271ee25-486c-79db-64c8-9fbbeb564b3e.gif)

###Androidアプリの中身
MIT App Inventorを開き「Block」をクリックし，どういったプログラムになっているか見てみましょう．
では，まずNefry BTとスマートフォンをペアリングする必要があります．
以下の画像に示しているものががBLEもしくはBluetoothを使うために必要である基本的なプログラムです．これは，どんなプログラムでも使いまわせると思います．
![BLE＿App.png](https://qiita-image-store.s3.amazonaws.com/0/212276/496e3576-3fab-78ed-dd46-47278a4151c7.png)
:grin:
次に，「Botton1」つまり「Control」というボタンが押された時のプログラムを記述します．それが下記の画像です．
ここで重要なのは，あらかじめNefry BTに書き込むプログラムで設定した「serviceUUID」と「characteristicUUID」を一致させることです．
今回は，「Control」というボタンが押されたら，「Hello」という文字列をNefry BT側に送っています．これで，Nefry BTでLチカすることができます．
![Controlボタン.png](https://qiita-image-store.s3.amazonaws.com/0/212276/7ae07d7e-085f-2c13-69c4-c07810f7a107.png)

#まとめ
BLEが使えるようになったときは，**とても嬉しかった**です．
まったくBLEの知識もAndroidアプリの知識もなかったのですが，なんとなくやってみたらなんとなく出来てしまいました．
なので，あんまり内容の正確さに自信がないのですが，少しでも参考になれば幸いです:grin: