
現在、IoTデバイスの開発が盛んに行われています。本記事では、無線通信規格の1つであるBLE(Bluetooth Low Energy)を使用して、組み込みアプリケーションデバイスで取得したI2Cセンサのデータをモバイルアプリケーションに転送する方法についてご紹介します。
概要
組み込みアプリケーションは、弊社製品のμC3/Compact及びμC3/BLE Stackと、STマイクロエレクトロニクス社のツールを使用して実装します。各種モバイルアプリケーションは、Apache Cordovaというモバイルアプリケーション開発フレームワークを使用します。
ハードウェア
ボード(ホストCPU) | STM32L496G-Discovery |
ボード(BLEコントローラ) | WYSBHVGXG |
I2Cセンサ | AE-SHT31 |
SD – micro SD 逆変換基板 | SDB-TFA |
STM32L496G-Discoveryには、ARM Coretex-M4のチップ:STM32L496AGが搭載されており、WYSBHVGXG及びAE-SHT31の制御を行います。
WYSBHVGXGには、NXP製のBLEコントローラチップ:88W8887を搭載。SDIOを介して88W8887と相互に通信し、BLE機能を制御します。AE-SHT31には、SENSIRION 社の高精度温湿度センサ :SHT31-DISが搭載されており、I2Cを介してSHT-31-DISから温湿度データを取得します。
以下、ハードウェア構成図です。(STM32L496G-DiscoveryをL496、AE-SHT31をSHT31とします。)
ソフトウェア
組み込みデバイス
RTOS | μC3/Compact |
BLE ホストスタック | μC3/BLE Stack |
IDE | EWARM 8.50.6 |
μC3/CompactはeForce製のμITRON仕様RTOS、μC3/BLE StackはeForce製のBLEホストスタックです。
一般的にBLEアーキテクチャは、以下の3つに分けられます。
・アプリケーション層
・ホスト層
・コントローラ層
μC3/BLE Stackはホスト層の機能を提供し、コントローラ層の機能を提供するデバイスと接続することにより、BLEの機能が使用可能になります。また、μC3/BLE Stackはコントローラ層とのインターフェースとして、SDIOをサポートしています。
以下、組み込みデバイスのソフトウェア構成図です。
モバイルアプリ
OS | Android 11 |
IDE | Android Studio Arctic Fox | 2020.3.1 |
フレームワーク | Apache Cordova 10.0.0 |
Cordova プラグイン | bluetoothle v6.6.1 |
このチュートリアルでは、Android StudioとApache Cordovaを使用して、Android上で動作するモバイルアプリケーションを作成します。
Apache Cordovaは、オープンソースのモバイル向けアプリケーション開発フレームワーク。bluetoothleは、CordovaからデバイスのBLE機能制御を可能にするプラグインです。
出典:eForce「Apache CordovaからAWS IoTにMQTTを利用してメッセージを送信する Vol.1 ~AWS SDK for javascript~」
処理の概要
- μC3/Compact(以下、μC3とします)の周期ハンドラを使用して、8秒周期でSHT31から温度と湿度を取得します。
- μC3/BLE Stack(以下、BLEスタックとします)を使用して、温度と湿度をGATTサーバで公開します。GATTサーバで公開する温湿度は8秒周期で更新します。このとき、サービスUUID及びキャラクタリスティックUUIDは、自動生成した適当な値を使用します。
- モバイルアプリで近くのBLEデバイスを検出し、コネクションします。
- コネクションが確立したら、同じく8秒周期でGATTサーバの温湿度キャラクタリスティック値にreadアクセスし、readした値を表示します。
ハードウェアの接続
L496とWYSBHVGXGをSD – micro SD逆変換基板で接続します。また、L496とSHT31をジャンパー線で接続します。
温湿度取得用I2C設定
温湿度センサについては、L496のI2C1を使用します。CubeMXを使用して、PB7、PB8のPull-up, down設定をPull-upに設定します。
BLEスタック設定
μC3/Configuratorを使用して、BLEスタックのコンフィギュレーションを行います。今回はすべてデフォルト値のまま使用します。
OSリソース
使用するμC3リソースは以下の通りです。
タスク
ID | 処理概要 |
ID_SENSOR_TASK | ・温湿度センサの値を、I2Cを使用して取得します。 ・固定長メモリプール及びメールボックスを使用して、温湿度の値をID_BLE_APP_TSKに送信します。 |
ID_BLE_APP_TSK | ・ID_SENSOR_TASKから受信した温湿度の値で、GATTサーバのキャラクタリスティック値を更新します。 ・モバイルアプリからのreadアクセスに対する応答処理を行います。 |
イベントフラグ
ID | 処理概要 |
ID_SENSOR_MBX | 周期ハンドラ:ID_SENSOR_CYCにで、イベントフラグをセットします。ID_SENSOR_TASKは、このイベントフラグで待ち状態が解除され、温湿度の取得処理を開始します。 |
メールボックス
ID | 処理概要 |
ID_TRH_MBX | ID_SENSOR_TASK – ID_BLE_APP_TSK間通信に使用します。 |
固定長メモリプール
ID | 処理概要 |
ID_TRH_MPF | ・ID_SENSOR_TASKで確保し、温湿度の値を格納します。メールボックス:ID_TRH_MBXを使用して、ID_BLE_APP_TSKに送信します。 ・ID_BLE_APP_TSKは、受信した温湿度の値でGATTサーバの値を更新した後、開放します。 |
周期ハンドラ
ID | 処理概要 |
ID_SENSOR_CYC | 8秒周期で起動されます。イベントフラグ:ID_SENSOR_FLGをセットし、ID_SENSOR_TASKの待ち状態を解除します。 |
ID_SENSOR_TASKの処理
1. get_mpf()をコールしてUserMSG用のメモリを確保します。UserMSGは、ID_SENSOR_TASK – ID_BLE_APP_TSKタスク間で温湿度情報をやり取りするための構造体です。
UserMSGは、メールボックスを使用してID_SENSOR_TASKから ID_BLE_APP_TSKに渡すため、構造体の先頭に必ずT_MGS型の変数を用意します。
T、RHはそれぞれ温度、湿度の値を文字列で格納するための配列です。SHT31で計測可能な温度、湿度の範囲はそれぞれ“125.00”~“-40.00″[℃]、湿度の範囲は“100.00”~“0.00″[%]であるため、7バイトの配列としています。
2. wai_flg()をコールして、SHT31の反応時間(8秒)を待ちます。ID_SENSOR_TASKの待ち状態は、8秒周期で起動する周期ハンドラ:ID_SENSOR_CYCのset_flg()コールによって解除されます。
3. HAL_I2C_Master_Transmit()、HAL_I2C_Master_Receive()を使用してI2C通信を実施し、SHT31から値を取得します。こちらの関数は、STマイクロエレクトロニクス社が提供しているHALドライバの関数です。HALドライバを使用することにより、ペリフェラルの機能を簡単に使用することができます。
4. SHT31から取得した値をSHT31の仕様にしたがって変換し、snd_mbx()によってID_BLE_APP_TSKに送信して、次のループに入ります。
ID_BLE_APP_TSKの処理
メイン処理
- BLEスタックの動作に必要となるDMA及びSDIOドライバを初期化します。ドライバはeForce製です。
- BLEスタック初期化APIであるble_ini()を実行します。このとき、BLEスタックにアプリケーションコールバック関数を登録します。
- ble_peripheral_start()を実行し、アドバタイジングやGATTサーバの設定を行います。
- 無限ループにて、rcv_mbx()でID_SENSOR_TASKからUserMSGの受信を待ちます。待ち状態が解除されたら、温度、湿度の値をble_temperature_buf, ble_humidity_bufにコピーします。最後にrel_mpf()をコールして、ID_SENSOR_TASKで確保した固定長メモリプールを開放し、次のループに入ります。
アプリケーションコールバック関数
BLEスタックは、コールバック関数を使用し、各種イベントの発生をアプリケーションに通知します。
BLEコネクションが確立されたことを通知するイベント:BLE_APP_CON_EVTが発生した場合、ble_dis_adv()をコールして、アドバタイズパケットの送信を停止します。
アドバタイズパケット送信がタイムアウトを通知するイベント:BLE_APP_ADV_TER_EVT及びBLEコネクションが切断されたことを通知するイベントBLE_APP_CON_CLS_EVTが発生した場合はble_ena_adv()をコールして、アドバタイズパケットの送信を再開します。
ble_peripheral_start()
ble_peripheral_start()では、ペリフェラルとしての動作に関する設定を行います。
- ble_set_gap_srv_device_name()、ble_set_gap_srv_appearance()をコールして、GAPサービスのDevice Nameキャラクタリスティック、Appearanceキャラクタリスティックを設定します。
- ble_ini_sensor_srv()を実行して、公開するサービスの設定を行います。ble_ini_sensor_srv()については後述します。
- Advertisementの設定を行うためのAPI:ble_cfg_adv()をコールします。ADV_CFG構造体:advの各種変数に各種設定値をセットし、ble_cfg_adv()に渡すことで、Advertisementの設定を行うことができます。
- set_ad_ini(), set_ad_local_name(), set_ad_uuid()を実行し、Advertising Dataを設定します。ここでは、Advertising DataにLocal NameとService UUIDを設定しています。
- ble_ena_adv()をコールし、ble_peripheral_start()を終了します。ble_ena_adv()は、Advertisementを開始するためのAPIです。
ble_ini_sensor_srv()
ble_ini_sensor_srv()では、GATTサービスの追加プロセスを実行します。
1. 今回使用するサービス及びサービスが保持するキャラクタリスティックの設定を行うための構造体を、グローバル宣言で確保します。
各自、
・T_BLE_SRVはサービス
・T_BLE_CHARはキャラクタリスティック
・T_BLE_CHAR_VALUEはキャラクタリスティック値
の設定のための構造体です。今回のアプリケーションでは、1つのサービスと温度用、湿度用でそれぞれキャラクタリスティック及びキャラクタリスティック値を2つ用意します。
2. サービス追加プロセスではT_BLE_SRVの設定を行い、ble_add_srv()をコールします。ble_add_srv()は、サービス定義プロセスを開始するためのAPIです。p_type, p_valueにそれぞれサービスタイプ及びサービスUUIDを設定します。
3. T_BLE_CHARの設定を行い、ble_add_char()をコールします。ble_add_char()は、サービスにキャラクタリスティックを追加するためのAPIです。cfg.property, p_char_uuidそれぞれキャラクタリスティックプロパティ、キャラクタリスティックUUIDを設定します。
4. T_BLE_CHAR_VALUEの設定を行い、ble_add_char_val()をコールします。ble_add_char_val()は、キャラクタリスティックにキャラクタリスティック値を追加するためのAPIです。cfg.p_type, cfg.cbkにそれぞれキャラクタリスティック値UUID、キャラクタリスティックにアクセスされたときのコールバック関数を設定します。
5. 今回は温度キャラクタリスティックと湿度キャラクタリスティックを用意するため、2~4をそれぞれに対して実行します。また、今回使用するサービスUUID及びキャラクタリスティックUUIDは、ツールを使用して生成したランダムな値を使用しています。
温度キャラクタリスティック値のコールバック関数
温度キャラクタリスティック値へアクセスがあったときの処理を記述したコールバック関数です。param->typeがBLE_CHAR_CBK_READ(readアクセス)があった場合、dat_lenにble_temperature_bufに格納されている文字列長、param->p_datにble_temperature_bufの値をコピーすることによりreadアクセスを要求したデバイスにble_temperature_bufの値を返すことができます。
つまり、Cordovaで実装したアプリケーションが、温度キャラクタリスティック値にreadアクセスを行うことで、L496が保持している温度の値を取得することができます。
ble_ad_char()コール時に、gt_ble_temperature_char.cfg.property = BLE_CHAR_PERM_RD(read許可)としているため、read以外のアクセスがあった場合はエラー処理としています。湿度キャラクタリスティック値のコールバック関数も同様の処理としています。
Cordovaアプリケーションの処理
このチュートリアルでは、CordovaのBluetoothleというプラグインを使用します。下記のコマンドを実行して、Bluetoothleをインストールします。
1. bluetootleの初期化メソッド、bluetoothle.initialize(initializeResult, params)を実行します。
2. スキャン開始メソッド、bluetoothle.startScan(startScanSuccess, startScanError, params)を実行します。このとき、paramsのservicesにサービスUUIDを設定することにより、スキャン対象のデバイスをフィルタリングすることができます。また、startScanResultのresultから、スキャンしたデバイスのDevice Nameやデバイスアドレスなどの情報が得られます。
3. コネクション開始メソッド、bluetoothle.connect(connectSuccess, connectError, params)を実行します。このとき、paramsのaddressにstartScanResultから取得したデバイスアドレスを指定します。
4. 3でコネクションに成功したら、デバイスのサービス、キャラクタリスティック及びキャラクタリスティックディスクリプタを検出するメソッド、bluetoothle.discover(discoverSuccess, discoverError, params)を実行します。このとき、paramsのaddressにstartScanResultから取得したデバイスアドレスを指定します。discoverSuccessのresult.services.uuidからサービスUUID、result.services.characteristic.uuidからキャラクタリスティックUUIDを取得できます。
5. キャラクタリスティック値へのreadアクセスメソッド、bluetoothle.read(readSuccess, readError, params)を8秒周期で実行するインターバルを起動します。このとき、paramsのaddress, service, characteristicにそれぞれデバイスアドレス、サービスUUID、キャラクタリスティックUUIDを指定します。readアクセスに成功すると、readSuccessのstatus.valueからreadした値を取得できます。
6. raedSuccessのstatus.valueは、base64でエンコードされているため、bluetoothle.encodedStringToBytes(string)にstatus.valueを渡し、デコードします。デコードした値をテキストボックスに表示します。
7. キャラクタリスティック値のreadを8秒おきに実行し、取得した値でテキストボックスの表示値を更新します。
モバイルアプリの動作概要は以下の通りです。
上記はアプリ起動時の表示です。右上のStart Scanをタップすると、周辺デバイスのスキャンを開始します。Start ScanはStop Scanという表示に変わります。Stop Scanをタップするとスキャンを停止します。
検出したデバイスを表示します。connectをタップすると、そのデバイスとのコネクションを開始します。
※sensorの下部には、BLEコントローラのパブリックデバイスアドレスが表示されますが、セキュリティの観点から黒塗りとしています。
前の画面で、connectをタップすると、表示がconnect→connecting→closeの順番で変化します。表示がcloseになると、コネクションの確立に成功したことを示します。
コネクションに成功すると、デバイスの温湿度キャラクタリスティック値をreadできるようになり、closeをタップすると、デバイスとのコネクション切断を開始します。
コネクションが確立した状態で、左側のタブをScan DeviceからMonitorに切り替えます。Temperature及びHumidity横のテキストボックスに、それぞれreadした温度キャラクタリスティック値、湿度キャラクタリスティック値が表示されます。
readアクセスを8秒周期で繰り返すので、テキストボックスの表示も8秒周期で更新されます。
弊社製品「μC3(マイクロ・シー・キューブ)」のご紹介
マイコン向け超軽量カーネルを採用したRTOS「μC3(マイクロ・シー・キューブ)/Compact」
μC3(マイクロ・シー・キューブ)/Compactは、マイコン内蔵の小さなメモリだけで動作するように最適化された、コンパクトなμITRON4.0仕様のRTOSです。
μC3/Compactは、ソースコードに直接コンフィグレーションを行うのではなく、付属のコンフィグレータによりGUIベースでRTOS、TCP/IP、デバイスのコンフィグレーションからベースコードの自動生成まで行います。
- 小さいフットプリント
- マイコンの小さなROM/RAMのみで動作するように最適化された最小2.4Kbyteのコンパクトなカーネル。メモリ容量が小さい安価なデバイスを使用する事ができます。
- μC3/Configurator付属
- 選択・設定するだけでベースコードが生成できるコンフィギュレーションツール。開発時間の大幅な短縮やコーディングミスの減少が可能。RTOSの初心者でも簡単に開発をスタートできます。
- 豊富なCPUサポート
- 業界随一のCPUサポート実績があり、技術サポートも充実しています。CPUの選択肢を広げ、機会費用を抑える事ができます。業界随一のCPUサポート実績があり、技術サポートも充実。使用予定のデバイスで直ぐに開発着手が可能で、ご質問に対して24時間以内の1次回答を徹底しています。
- 省電力対応
- デフォルトで省電力機能がついているため、システム全体の省電力に貢献します。
詳しい資料をご希望の方は、下記より製品ガイドをダウンロードしてください。
μC3のライセンスの種類・詳細
ライセンスの種類
ライセンスの種類は3つあります。
- 開発量産用プロジェクトライセンス
- プラットフォームライセンス
- 研究開発用プロジェクトライセンス
開発量産用プロジェクトライセンス
開発量産用プロジェクトライセンスは、研究開発から量産販売までが可能な標準的なライセンスとなります。開発量産用プロジェクトライセンスの対象製品の範囲には、1種類の製品型番だけでなく、その製品ファミリ(派生機種)が含まれます。
有償の保守契約に加入中の場合、プラットフォームライセンスのライセンス費用との差額でアップグレードが可能です。
プラットフォームライセンス
プラットフォームライセンスは、プロジェクトライセンスの対象範囲を広げたライセンスです。プラットフォームライセンスの対象製品は、1種類の製品ファミリだけでなく、複数の製品ファミリが範囲となります。サイトライセンスではございません。
研究開発用プロジェクトライセンス
研究開発用プロジェクトライセンスは、研究開発のみ可能なライセンスです。ライセンス購入時の段階で、製品化まで見えていない場合や、フィジビリティスタディの場合にお勧めです。
ライセンス費用は、開発量産用プロジェクトライセンスの60%の価格です。
有償の保守契約に加入中の場合、開発量産用プロジェクトライセンスのライセンス費用の40%オフの価格でアップグレードが可能です。
ポイント
- 開発量産用プロジェクトライセンス:研究開発から量産販売までが可能な標準的なライセンス
- プラットフォームライセンス :1種類の製品ファミリだけでなく、複数の製品ファミリを範囲とするライセンス
- 研究開発用プロジェクトライセンス:製品化まで見えていない場合や、フィジビリティスタディの場合にお勧めなライセンス
※弊社のライセンスはプロジェクトライセンスの形式を採っております。ご購入時に該当プロジェクトの名称をご登録いただく必要があり、その際、「計測機器」などの抽象的な名称ではなく、具体的な名称を頂戴しております。
お客様のご要望にあわせて適切な範囲で設定させていただきますので、まずは、担当営業にご相談下さい。
ライセンスの詳細
-
- ライセンス費用の金額・計算方法:ライセンス購入時の固定の一括払いのみでご使用いただけます
- 開発人数制限 :無(ただし同プロジェクト内)
- 提供形態 :ソースコード
- 使用範囲 :定義されたプロジェクト内
- 使用CPU :型番固定ではなくCPUシリーズ(例:STM32F4シリーズ)
- μC3/ConfiguratorはCPUシリーズ毎に用意されています
ライセンスの価格などの詳細については、下記より製品ガイドをダウンロードしてご覧ください。
保守について
製品定価には契約日の翌月1日から6ヶ月分の無償保守が含まれています。
無償保守サービス終了後は有償での保守サービスとなります。そのまま継続でのご利用の場合、製品価格(研究開発用プロジェクトライセンスはプロジェクトライセンス価格)の20%、非継続の後に再加入をされたい場合は研究開発用プロジェクトライセンスはプロジェクトライセンス価格)の40%となります。
プロジェクトライセンスと1年間の保守サービスを同時にご購入いただいた場合は、初回に限り15%とさせていただきます。
保守サービスには以下が含まれています。
- 製品の無償バージョンアップ対応
- コンパイラのバージョンアップ対応
- メールによる技術サポートサービス(1営業日以内に1次回答)