nRF51822の概要:クイックスタート

1.はじめに



こんにちは



膨大な数のプログラミングレッスンが、さまざまな単純な(そしてそうではない)プラットフォームのネットワーク上を歩いています。 毎年、同じマイクロコントローラ上でさまざまな深さの同じタイプのチュートリアルが数十個スタンプされています。 また、これは素晴らしいことです。豊富な記事がトピックを入力するためのしきい値を減らし、成熟したプログラマーが、上下に読み取られたデータシートを検索する時間を無駄にせずに、既に動作している周辺機器初期化コードを使用して、問題についてより深刻になります。



ただし、ニュアンスがあります-STM32 / 8、AVRなどの標準選択の右側へのステップ、左側へのステップ、または同じSTM32 / 8のより複雑なインターフェースへの深化、および無音。 遠く、遠く離れたフォーラムでたまにしか、誰かが最終的に未回答のままの質問をします...



私は実際に何につながっていますか。 少し前まで、 Nordic Semiconductor社のnRF51822チップを、現在人気のあるBluetooth Low Energy(以降、BLEと呼びます)を搭載して使用する必要がありました。



画像



チップは情報コンポーネントで非常に人気があり、Googleは半分の悲しみで、BLEスタック自体の説明とNordicおよびTexas Instruments(CC2640)チップのスタック実装に関する2、3の抽象的な記事を含む2〜3のリンクを発行しました。 経験の浅いプログラマーは、「北欧から例を挙げてください(ちなみに、そこにはたくさんあります)」と理解します。 そして、これは、プログラマーを始めて、すぐに結果を取得したいということに関する大部分の問題ではないにしても、正しいアプローチです:豊富な構造、マルチレベルライブラリ-これらはすべて美しく論理的ですが、クイックスタートまたは小規模プロジェクトには冗長です。 これはすべて、入場のしきい値を不当な高さに増やします。



上記のすべてを踏まえて、 NRF51822チップを使用した交換アプリケーションの実装の簡単なバージョンを検討することを提案します。これにより、このようなシステムの開発の基本的な側面を一般的に理解できます。 そしてそれは...当然、LEDです。 リモートスマートフォンの実行。



2.必要なソフトウェアとハ​​ードウェア





スマートフォンの代わりにUSBドングルを使用できますが、その価格(77ドル)は、 NRF51 DKデバッグボードの価格(49ドル に比べて少し反発的です。 この例では、その存在はオプションですが、その重要性を過小評価しないでください。



画像



3.テンプレートを作成する



最優先事項は、Keilでテンプレートを作成し、BLEスタックを使用するために必要なすべてのライブラリファイルを接続することです。 プロセス自体は最初から時間がかかるため、KeilがPack Installerで親切に隠している多くの例の中にある標準テンプレートを使用します。







この例で実装されている機能は、ほとんどの場合、接続を作成し、発生するイベント(接続、切断など)に対するBLEスタックの反応を整理するために必要です。 現時点では、情報であふれないようにそれらを止める理由はありません。また、それらに触れる必要はありません。スタックの使用プロセスに関する一般的な理解はありません(記事に添付されているプロジェクトでは、すべての機能がロシア語でコメント解除されています)。 スタック自体の詳細については、 こちらをご覧ください 。 将来的には、接続イベントやスタックイベントを試すことができますが、このトピックはこの記事には当てはまりません。



4.スタックおよびアプリケーションファームウェア



さまざまなデバイスでのBLEスタックの実装に関する他の記事で既に2回以上言及されているように、BLEスタックはフラッシュメモリの下部に縫い付けられ、その後ユーザーアプリケーションがロードされます。 幸いなことに、この面で未経験の人は、使用するテンプレートでアドレス指定が既に設定されているので、必要なことは、 [ターゲット選択 ]セクションでSoftDevice S130選択し 、[ダウンロード]をクリックするだけです。







次に、同じ方法で、コンパイルされたユーザーアプリケーションをロードします。



5.予備テスト



現時点では、ダウンロードしたアプリケーションは便利な機能を実行していませんが、デバイスに接続する機能を備えた広告パッケージを送信できます。 詳細な情報は、前述の記事で完全に入手できます。

受信したデバイスに接続するには、 nRF Connect for MobileプログラムをAndroidを実行しているスマートフォンにダウンロードする必要があります。 開始し、エーテルをスキャンし、デバイス-Nordic_Templateを見つけます。 接続して、すべてが正しいかどうかを確認できます。 将来的には、このプログラムの助けを借りて、デバイスの特性を読み書きできるようになり、それによってデバイスと対話できるようになります。







前述したように、現時点では、デバイスはサービスパラメータを除いて有用なデータを一切持ちません。 BLEのデバイスとの相互作用は、読み取り/書き込み特性によって提供されます。 特性はサービスに結合され、プロファイルに結合されますが、一般的にこれは別の記事ではかなり深刻なトピックです。 ただし、どの関数が一次近似で特性を持っているかを簡単な言葉で説明することはまだ価値があります。 正式には、これは、相互作用を決定する特定のパラメーター(サイズ、タイプ、アクセスタイプ)を持つスタック変数です。 すべての特性について、読み取り、書き込み、通知などを有効にできます。 書き込み許可を持つ特性を介して、デバイスに任意のデータを転送でき、読み取り許可を持つ特性を介して、データを取得できます。



そのため、たとえば、 要求/応答システムを実装できます 。 パラメーター(温度、湿度、加速度)の時間があるデバイスを想像してください。 3つの異なる特性を作成し、その意味を読み取ることができます。 ここで、特定の期間(たとえば先月)のデータを受信する必要があると想像してください。 この場合、記録許可を持つ特性を作成し、その中に月番号を書き込み、デバイスは要求されたデータを特性に設定します。



画像



しかし、タスクに戻ります。 LEDを制御するには、適切なサービスを作成する必要があります。 サービスには2つの特性が含まれます。





最初のサービスの作成を開始する前に、各サービスとそれに含まれる各特性に固有のアドレス(UUID)が必要であることを理解する必要があります。 このアドレスのおかげで、デバイス(たとえば、スマートフォン)は特定のデータで何をする必要があるかを判断できます。 多くのプロファイル、サービス、機能がBLEの標準であり、Bluetooth SIGに登録された独自の16ビットアドレスと事前定義された機能セットを持っていることに注意してください。 これらのプロファイルのいずれかが実装されているデバイスからデータを受信するスマートフォンは、パッケージの構成を正確に把握しており、受信した情報をさらに実装するために必要なすべての機能を備えています。



128ビットのアドレスのみが利用可能です。 3つのUUIDアドレスを設定します。1つはサービス用で、2つは特性用です。 これを行うには、ランダムなUUIDを生成するように設計された特別なジェネレーターを使用します。 生成時に時間ベースを選択することをお勧めします。3つのアドレスすべてに対して同じメイン部分を使用してUUIDが順番に生成されます。



/*  UUID (  UUID    ) */ #define LED_BASE_UUID {0x66, 0x9A, 0x0C, 0x20, 0x00, 0x08, 0x1A, 0x8F, 0xE7, 0x11, 0x61, 0xBE, 0x00, 0x00, 0x00, 0x00} /*  UUID (  UUID    ) */ #define LED_SERVICE_UUID 0x1523 #define CONTROL_CHAR_UUID 0x1524 #define READ_CHAR_UUID 0x1525 /*   UUID     */ static ble_uuid_t m_adv_uuids[] = {{LED_SERVICE_UUID, BLE_UUID_TYPE_BLE}};
      
      





それでは、サービスの作成に移りましょう。 テンプレートで、 services_init関数に入力します。



services_init
 uint16_t led_handles; //    (  ) void services_init(void){ ble_uuid_t ble_uuid; /*  128 -  UUID */ ble_uuid128_t base_uuid = LED_BASE_UUID; uint8_t uuid_type; ble_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; ble_uuid.uuid = LED_SERVICE_UUID; sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type); sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &led_handles); }
      
      







次のステップは、特性を作成するための汎用機能を実装することです。



char_add
 /*     * UUID -   * handles -    (  ) * n_bytes -    * iswrite, isnotf, isread -   , ,  */ uint32_t char_add(uint16_t UUID, ble_gatts_char_handles_t * handles, uint8_t n_bytes, bool iswrite, bool isnotf, bool isread){ ble_gatts_char_md_t char_md; ble_gatts_attr_md_t cccd_md; ble_gatts_attr_t attr_char_value; ble_uuid_t char_uuid; ble_gatts_attr_md_t attr_md; memset(&cccd_md, 0, sizeof(cccd_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); cccd_md.vloc = BLE_GATTS_VLOC_STACK; memset(&char_md, 0, sizeof(char_md)); char_md.char_props.notify = isnotf; //   ; char_md.char_props.write = iswrite; //   ; char_md.char_props.read = isread; //   ; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = &cccd_md; char_md.p_sccd_md = NULL; /*  UUID - 128 -  */ char_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; char_uuid.uuid = UUID; memset(&attr_md, 0, sizeof(attr_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); attr_md.vloc = BLE_GATTS_VLOC_STACK; attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; attr_char_value.p_uuid = &char_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = n_bytes; attr_char_value.init_offs = 0; attr_char_value.max_len = n_bytes; //  ; attr_char_value.p_value = NULL; //   ; /*     */ sd_ble_gatts_characteristic_add(led_handles, &char_md, &attr_char_value, handles); return 0; }
      
      







サービスと機能を作成するための機能が用意されています。 ここで、まだ必要なものを見つけましょう。 そして、2つのことが必要です。





書き込み処理機能から始めましょう。 スタックには1つのble_evt_dispatch割り込みハンドラーがあり 、スタックイベントが発生したときに呼び出されます。 このハンドラーから、他のすべてのユーザー定義の割り込みハンドラーが呼び出され、それらに反応が定義されている場合にイベントに応答します。 この場合、個別のハンドラーは作成せず、受信したデータに応じてアクションを実行する関数のみを作成し、標準ハンドラーの1つで対象のイベントをチェックします。



on_ble_evt
 static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; /*         */ ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; break; /*       */ case BLE_GATTS_EVT_WRITE: /*     (  ) */ write_handler(p_evt_write->data); break; default: break; } }
      
      







LEDのステータスを設定する機能は提供しませんが、非常に簡単です。さらに、添付のプロジェクトではそうです。



次に、機能のデータ更新機能に進みましょう。 スマートフォンだけでは、LEDの状態が変化したことを認識しません。 また、デバイスのLEDのステータスを担当する変数が変更された場合でも、特性の読み取りには変更されていない値が表示されます。 変更するには、この変更をBLEスタックに登録する必要があります。 もう1つの機能を追加します(汎用ではなく、特定の特性用に作成されていますが、直感的で、あらゆるニーズに合わせて簡単に書き換えることができます)。



data_update
 uint32_t data_update(uint8_t *data, uint16_t value_handle) { uint32_t err_code; ble_gatts_value_t gatts_value; uint8_t update_buffer[1]; /*   (    ) */ memcpy(update_buffer,data,(sizeof(update_buffer)/sizeof(uint8_t))); memset(&gatts_value, 0, sizeof(gatts_value)); /*    */ gatts_value.len = sizeof(update_buffer)/sizeof(uint8_t); gatts_value.offset = 0; /*     */ gatts_value.p_value = update_buffer; /*     */ err_code = sd_ble_gatts_value_set(m_conn_handle, read_handles.value_handle, &gatts_value); return err_code; }
      
      







残っているのは、サービスを初期化し、メイン関数で特性を作成することだけです。



メイン
 /*    (  ) */ ble_gatts_char_handles_t control_handles,read_handles; int main(void) { uint32_t err_code; bool erase_bonds; timers_init(); buttons_leds_init(&erase_bonds); ble_stack_init(); device_manager_init(erase_bonds); gap_params_init(); advertising_init(); /*   */ services_init(); /*        */ char_add(READ_CHAR_UUID,&read_handles,1,0,0,1); /*        */ char_add(CONTROL_CHAR_UUID,&control_handles,1,1,0,0); conn_params_init(); /*       */ err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); for (;;) { power_manage(); } }
      
      







7.最終テスト



nRF Connect for Mobileを再度コンパイル、 アップロード 、起動します 。 サービスと2つの特性があることがわかります。 データベースにはそのようなUUIDがなく、彼はそれをどう処理するのか理解していないため、スマートフォンには不明です。 ただし、特性「1」または「0」に書き込むことでLEDを安全に制御し、現在の値を読み取ることもできます。 この例は、センサーからパラメーターを削除するなど、ほとんどすべてのタスクに適用できます。 将来的には、目的に合わせてサービスを簡単に使用できるAndroid用のアプリケーションを作成できます。





8.結論



この記事は、データ交換プロセスの理解を簡素化し、初心者が既成のケーススタディを活用して、Nordic SemiconductorのBLEスタックのすべての機能を実際にさらに理解できるようにすることを目的としています。 簡単にするために、実装の一部の機能とニュアンスは省略されており、同様のデバイスがたくさんあります。 ただし、試行錯誤を繰り返してトピックに入らない限り、記事を理解するのに役立つ記事はありません。 上記のすべてでは、できるだけ早くミスを開始することができます。 頑張って)



PSプレゼンテーションの主題と方法が暖かく歓迎されている場合、現在の傾向を喜ばせて記事の選択を拡大し、近い将来、BLEスタックのニュアンスのいくつかを検討し、ライブラリとレジスタ、およびAndroid用のBLEアプリケーションでサイクルを完了します。



X.有用な資料






All Articles