2017/09/24
どうも、クラゲです。
今回はBLE Nano V2にちょっとした回路を追加して、BLE通信でPCやスマホ側へ情報を送信したり、逆にPCやスマホ側からハードウェアを制御したりします!
今後様々な応用例も出していきますが、今回の回路をベースとして展開してゆきます
今回できることは、ハード側の半固定抵抗という小さなボリュームのツマミを回すと、PCやスマホ画面の数値が変更することと、PCやスマホ画面からLEDの点灯/消灯制御です。
BLE Nano2やmbed自体の開発が初めてという人はこちらを先に目を通しておいてください。
クラゲは、2017年9月現在のnRF52向けのmbed-osライブラリはバグがあると推測しています。
BLE通信が途中で切れたり、アナログ電圧入力の読み込みが不安定だったりします。BLE Nano2のVDD電圧をテスターで測定してみると結構電圧降下が大きいことから、無駄な消費電流もありそうです。
色々試してみましたが、現状は解決方法は無さそうです。ライブラリの更新に期待しましょう!
とりあえず、機能的にはそれなりに動くことは確認していますので、上記を考慮の上、読み進めてください。
BLE Nano以外に必要となる周辺部品です。
全て秋月電子のみで購入することが可能です。
ミニブレッドボード
http://akizukidenshi.com/catalog/g/gP-05155/
ミニである必要はないです。ブレッドボードがあれば何でも良いです。
ジャンパワイヤー 7本以上
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://os.mbed.com/users/electricbaka/code/BLENano2_SimpleTemplate/
このプログラムはBLEnanoの製造元RedBearLab作成のBLENano_SimpleControlsをベースに改良したものです。
簡単にプログラムの説明をします
急いでいる人は飛ばして次の項目に進んじゃってOKです
//------------------------------------------------------------//Definition//------------------------------------------------------------//max 20[byte]//160 * 0.625[ms] = 100[ms]//200000[us] = 200[ms]
TXRX_BUF_LENはBLEのデータバッファサイズでMAX20Byteと決まっていますので、20のままを推奨とします
DEVICE_LOCAL_NAMEは、Scanしたときに見つかる名前です。好きな文字列に変えてもらって構いません。
ADVERTISING_INTERVALはAdvertisingのインターバルで、短いほど見つかりやすくなります
TICKER_TIMEは、ハードウェア側で電圧値を読んでBLE送信するタイミングです。短いほど高頻度で情報を送信しますが、電力としては長い方がお得です
DIGITAL_OUT_PINでは、LEDを制御するためのピンを定義しています
ANALOG_IN_PINでは、どこで電圧値を読み込むのかのピンを定義しています。ANALOG_IN_PIN1とANALOG_IN_PIN2の2つを定義しました。
//------------------------------------------------------------//Object generation//------------------------------------------------------------BLE ble;DigitalOut ;AnalogIn ;AnalogIn ;
デジタル出力ピンをDIGITAL_OUT_PINにしてLED_SETという名前に設定しています。
アナログ入力ピンの1つをANALOG_IN_PIN1にしてANALOG1という名前に設定しています
もう一つをANALOG_IN_PIN2にしてANALOG2という名前に設定しています
//------------------------------------------------------------//Service & Characteristic Setting//------------------------------------------------------------//Service UUIDstatic const uint8_t base_uuid[] = ;//Characteristic UUIDstatic const uint8_t tx_uuid[] = ;static const uint8_t rx_uuid[] = ;//Characteristic Valueuint8_t txPayload[TXRX_BUF_LEN] = ;uint8_t rxPayload[TXRX_BUF_LEN] = ;//Characteristic Property Setting etcGattCharacteristic ;GattCharacteristic ;GattCharacteristic *myChars[] = ;//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//======================================================================void
変数s1, s2にアナログ読み込みした値を入力します。
s1には半固定抵抗で分圧された電圧値が入力されます。
s2には電源電圧値が入力されます。
s2に対するs1の割合を見ることで、半固定抵抗のツマミの位置を得ることができます。
本来、Vrefの設定をVddに変更すればs1のみで位置を得ることができますが、nRF52のVref設定レジスタが不明のためこのような対応にしています。
0〜1.0の小数値で入るので、1024倍して0〜1024の整数値に変換します
buf[0]には下位8bitを入力し、buf[1]には上位8bitを入力
最後にupdateCharacteristicValueにて、rxCharacteristicの値をbufで更新しています。
//======================================================================//convert reverse UUID//======================================================================void
AdvertiseするときにUUIDを逆にして渡す必要があります。
元のプログラムは手動で書いていましたが、ここでは逆に書く関数を用意しました。
//======================================================================//main//======================================================================int
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//------------------------------------------------------------while(1)}
最後は無限ループでBLEイベント待ちです。
ブレッドボードに回路を組んでいきます。
もちろん、ハンダごてや工具は一切不要です!
ジャンパー線はたったの7本です。色はお好みで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 Nano2ではじめてのBLE通信でした!