2017/08/01
どうも、クラゲです。
今回はBLE Nanoにちょっとした回路を追加して、BLE通信でPCやスマホ側へ情報を送信したり、逆にPCやスマホ側からハードウェアを制御したりします!
今後様々な応用例も出していきますが、今回の回路をベースとして展開してゆきます
今回できることは、ハード側の半固定抵抗という小さなボリュームのツマミを回すと、PCやスマホ画面の数値が変更することと、PCやスマホ画面からLEDの点灯/消灯制御です。
BLE Nanoやmbed自体の開発が初めてという人はこちらを先に目を通しておいてください。
BLE Nano以外に必要となる周辺部品です。
全て秋月電子のみで購入することが可能です。
ミニブレッドボード
http://akizukidenshi.com/catalog/g/gP-05155/
ミニである必要はないです。ブレッドボードがあれば何でも良いです。
ジャンパワイヤー 6本以上
http://akizukidenshi.com/catalog/g/gC-05371/
オスーオスのジャンパワイヤであれば何でも良いです。URL先は20本セットの商品です。
半固定ボリューム10kΩ
http://akizukidenshi.com/catalog/g/gP-08012/
ツマミを回すことにより、抵抗値を変えることのできる抵抗です
LED
http://akizukidenshi.com/catalog/g/gI-11655/
もし、お手持ちのLEDがあれば、それでも大丈夫だと思います
抵抗220Ω
http://akizukidenshi.com/catalog/g/gR-25221/
もし手持ちに47Ω〜470Ωくらいの抵抗があれば、それでもいいです
ボタン電池 CR2032
http://akizukidenshi.com/catalog/g/gB-05694/
小型化のためにボタン電池を使います。近くのスーパーなどで売っているボタン電池でも問題ありません
CR2032ボタン電池ホルダー
http://akizukidenshi.com/catalog/g/gP-00706/
ボタン電池のケースです
BLE Nanoにファームウェアを書き込みます
こちらからプログラムをimportして書き込んで下さい。
https://developer.mbed.org/users/electricbaka/code/BLENano_SimpleTemplate/
このプログラムはBLEnanoの製造元RedBearLab作成のBLENano_SimpleControlsをベースに改良したものです。
簡単にプログラムの説明をします
急いでいる人は飛ばして次の項目に進んじゃってOKです
//------------------------------------------------------------//Definition//------------------------------------------------------------#define TXRX_BUF_LEN 20 //max 20[byte]#define DEVICE_LOCAL_NAME "BlueJelly"#define ADVERTISING_INTERVAL 160 //160 * 0.625[ms] = 100[ms]#define TICKER_TIME 200000 //200000[us] = 200[ms]#define DIGITAL_OUT_PIN P0_9#define ANALOG_IN_PIN P0_4
TXRX_BUF_LENはBLEのデータバッファサイズでMAX20Byteと決まっていますので、20のままを推奨とします
DEVICE_LOCAL_NAMEは、Scanしたときに見つかる名前です。好きな文字列に変えてもらって構いません。
ADVERTISING_INTERVALはAdvertisingのインターバルで、短いほど見つかりやすくなります
TICKER_TIMEは、ハードウェア側で電圧値を読んでBLE送信するタイミングです。短いほど高頻度で情報を送信しますが、電力としては長い方がお得です
DIGITAL_OUT_PINでは、LEDを制御するためのピンを定義しています
ANALOG_IN_PINでは、どこで電圧値を読み込むのかのピンを定義しています
//------------------------------------------------------------//Object generation//------------------------------------------------------------BLE ble;DigitalOut ;AnalogIn ;
デジタル出力ピンをDIGITAL_OUT_PINにしてLED_SETという名前に設定しています。
アナログ入力ピンをANALOG_IN_PINにしてANALOGという名前に設定しています
//------------------------------------------------------------//Service & Characteristic Setting//------------------------------------------------------------//Service UUIDstatic const uint8_t base_uuid = 0x71 0x3D 0x00 0x00 0x50 0x3E 0x4C 0x75 0xBA 0x94 0x31 0x48 0xF1 0x8D 0x94 0x1E ;//Characteristic UUIDstatic const uint8_t tx_uuid = 0x71 0x3D 0x00 0x03 0x50 0x3E 0x4C 0x75 0xBA 0x94 0x31 0x48 0xF1 0x8D 0x94 0x1E ;static const uint8_t rx_uuid = 0x71 0x3D 0x00 0x02 0x50 0x3E 0x4C 0x75 0xBA 0x94 0x31 0x48 0xF1 0x8D 0x94 0x1E ;//Characteristic Valueuint8_t txPayloadTXRX_BUF_LEN = 0;uint8_t rxPayloadTXRX_BUF_LEN = 0;//Characteristic Property Setting etcGattCharacteristic ;GattCharacteristic ;GattCharacteristic *myChars = &txCharacteristic &rxCharacteristic;//Service SettingGattService ;
ServiceUUIDとCharacteristicUUIDの設定です。
base_uuidというServiceが1つで、その下にtx_uuidとrx_uuidというCharacteristicが入っています。
これらのUUIDはReadBear Lab社のサンプルプログラムのUUIDと同じままにしています。
713D0000-503E-4C75-BA94-3148F18D941E
713D0003-503E-4C75-BA94-3148F18D941E
713D0002-503E-4C75-BA94-3148F18D941E
必要があれば変更してください。
ちなみに、この形式でて入力するのが大変なので、UUID変換ツールを作成しました。ご活用ください。
コメント文の “Characteristic Property Setting etc” の下では、それぞれのCharacteristicに対し、プロパティを設定してます。
tx_uuidはWRITEとREAD、rx_uuidはNOTIFYとREADをプロパティとして設定しています。
//======================================================================//onDisconnection//======================================================================void
切断時の処理です。Advertiseを開始します。
//======================================================================//onDataWritten//======================================================================void
セントラル(PC・スマホ側)からWRITEが来た時のイベント処理です
readCharacteristicValueで、txCharacteristicからValueを読み込みbufに代入しています。
memsetにて配列txPayloadをオール0で初期化しています
memcpyにて配列txPayloadにbufをコピーしています
ここの関数自体ではtxPayloadは使いませんが、セントラルからREADされたときに備えてこのようにしています。
buf[0]が1の場合はLED_SETを1にしてLEDを点灯させ、それ以外の場合はLED_SETを0にしてLEDを消灯させています。
//======================================================================//onTimeout//======================================================================voiduint8_t buf2;//Read Analog portfloat s = ANALOG;uint16_t value = s*1024;buf0 = value >> 8;buf1 = value;//Send outble;
変数sにアナログ読み込みした値を入力します。
0〜1.0の小数値で入るので、1024倍して0〜1024の整数値に変換します
buf[0]には下位8bitを入力し、buf[1]には上位8bitを入力
最後にupdateCharacteristicValueにて、rxCharacteristicの値をbufで更新しています。
//======================================================================//convert reverse UUID//======================================================================void
AdvertiseするときにUUIDを逆にして渡す必要があります。
元のプログラムは手動で書いていましたが、ここでは逆に書く関数を用意しました。
//======================================================================//main//======================================================================intuint8_t base_uuid_rev16;//Timer Setting [us]Ticker ticker;ticker;//BLE initble;//EventListenerble;ble;
Timer Settingにて、m_status_check_handleをTICKER_TIME(=200ms)の間隔でタイマー呼び出しする設定を行っています。
EventListenerにて、切断時と書き込み時に呼ぶ関数をここで定義しています。
//------------------------------------------------------------//setup advertising//------------------------------------------------------------//Classic BT not supportble;
クラシックBTはサポートせず、BLEデバイスとして認識してもらいます
//Connectable to Centralble;
デバイスがセントラルに接続可能であることを設定しています
//Local Nameble
LOCAL NAMEの設定です。
sizeofで -1 しているのは、終端記号を含めないようにしているためです。(BLEでは終端不要)
//GAP AdvertisingData;ble;
今回のUUIDは16bit短縮ではなく128bitであることを示しています。
サービスのUUIDをリバースしたものを第2の引数に入れ、第3の引数はそのサイズを設定します。
//Advertising Intervalble;
ADVERTISING_INTERVAL(=100ms)でAdvertiseパケットの送信周期を設定しました
//Add Serviceble;//Start Advertisingble;
サービスを登録し、Advertiseを開始します。
//------------------------------------------------------------//Loop//------------------------------------------------------------while1ble;}
最後は無限ループでBLEイベント待ちです。
ブレッドボードに回路を組んでいきます。
もちろん、ハンダごてや工具は一切不要です!
ジャンパー線はたったの6本です。色はお好みでOKです
結線図はこの通りです。(結線図は fritzing を使って描いています)
気をつける点としてはまずLEDの向き。足の短いほうが上図の足がまっすぐな方、つまり左側です。
電池ホルダーの + と - のジャンパー線は若干斜めになります。
抵抗は向きはないので逆向きでもOK
回路が組み終わったら、いよいよ実行確認です
BLE対応しているスマホやタブレットを用意しましょう。
(Macしかない人はLightBlueというアプリをインストールしてみてください。操作説明は省略しますが、ほぼ直感で使えると思います)
iOS端末の場合は”nRF Connect”、Android端末の場合は”nRF Connect for Mobile”という無料アプリをインストールします
以降では、iPod Touchでの実行画面を例に説明します。他のOSだったとしても、ほぼ同じ操作で出来ます。
アプリを起動したら、SCANを行います。
mbedプログラムで設定したDEVICE_LOCAL_NAMEが見つかるはずです。
(mbedプログラムを変更していなければ、”BlueJelly”という名前が出てきます。もしくは”nRF5_MCU0”と出る場合もあります。)
見つかったら CONNECTをタップします
Unknown Serviceがあると思いますので、それをタップします
ちなみにUUIDはmbedプログラムで設定した 713D0000-503E-4C75-BA94-3148F18D941E と一致していると思います。
Unknown Characteristicが2つ出てくると思います。それぞれのUUIDはmbedプログラムで設定したtx_uuidとrx_uuidと一致しています。
tx_uuid : 713D0003-503E-4C75-BA94-3148F18D941E
rx_uuid : 713D0002-503E-4C75-BA94-3148F18D941E
図の赤い丸はRead、青い丸はWrite、緑の丸はNotifyを意味しています
ブレッドボード回路の半固定抵抗ツマミを少し回してからrx_uuidをReadしてみてください
(rx_uuidはRaedとNotifyがある方です)
16進数表示なので分かりづらいですが、Valueが変化したのが分かると思います。
今度はNotifyを押してみてください
バツ印が付いているときがNotify中を示しています。このときにツマミを回すとリアルタイムでValueが変化すると思います。
ちょっとタップにくいですが、もう一度NotifyをタップするとNotifyがストップします。
最後にWriteをタップしてみましょう
ポップアップが表示されます。
1をWriteするのですが、入力値としては “01”と入力しないとエラーになります。
SENDをタップして、回路に繋げたLEDが点灯すれば成功です
消灯するには”00”を入力します。
先ほどは既存のスマホアプリを使ってBLE通信しました。これだと操作も面倒だし、応用が利きません。
そこでオリジナルアプリを作りたくなるのですが、開発方法としていくつかあります。
もっともポピュラーなのはAndroidまたはiOSのネイティブアプリ開発ですが、クラゲにとっては非常に面倒に感じます。
一番簡単なアプリ開発は、BlueJelly.jsを使うことです。BlueJellyを使えば、AndroidStudioやXcodeなどは一切使わずに、テキストエディッタのみで開発できます。
クラゲのブログページではBlueJellyに関する開発方法やBLE知識などたくさん公開していますで、そちらを参考にサクッとWEBでプログラミングしちゃいましょう!
https://monomonotech.jp/kurage
以上、BLE NanoではじめてのBLE通信でした!