Bluetooth Low Energy特性の値を短時間で繰り返し書き込みたい(考えられる使用例として、マウスを想像してください)。
IPhone4Sからシーケンス番号を含むパケットを送信してプログラムをテストします。シーケンス番号は、パケットが送信されるたびに1つずつ増加します。
受信側では、 CSR10 BLEチップを組み込んだプログラム可能な開発ボードを使用して、パケットを受信し、受信したシーケンス番号をシリアル接続に出力します。
私の問題は次のとおりです:
しばらくすると、パケットがドロップされ始めます。最初の約100パケットは、50Hzで正常に機能します。それ以降、パケットはドロップされ始めます。
0x00 - 0x46 received
0x47, 0x48 missing
0x49, 0x4a, 0x4b, 0x4c received
0x4d missing
0x4e, 0x4f, 0x50, 0x51 received
0x52 missing
0x53, 0x54, 0x55, 0x56 received
0x57 missing
...
ほとんどの場合、4パケットのパックが正常に送信されます(まれに、2パケットのみ)。次に、1〜7個のパケットが欠落しています。
特性値のサイズを小さくしても、問題は解決しません。
50Hzではなく100Hzで書き込んだ場合、状況は同じです。ドロップは約35パケット後に発生し始め、4パケットの送信が成功するまでに5〜7パケットがドロップされるだけです。
パケットが失われると、書き込みの頻度に関係なく、結果の伝送速度は約5 kbit/sになります。これは、Bluetooth LowEnergyで技術的に可能であるはずの約305kbit/sを明らかに下回っています。
開発ボードからiPhone4Sにパケットを送信しているときに、この問題は反対方向にも発生します。繰り返しますが、5 kbit/sが私が得ている最大値です。このシナリオでは、通知メカニズムが使用されます。この場合も、属性レイヤーでは確認応答は発生しません。
両方向に同時に送信しようとすると、開発ボードとiPhone4Sの両方をリセットしなければならないところまで物事が爆発し始めます。
質問:
これは、開発ボードで使用されているBluetooth Low Energyチップの問題でしょうか?
はいの場合、iPhoneがレシーバーとして機能する反対方向にも問題が発生するのはなぜですか?
特性への高周波アクセスをサポートする開発ボードは市場にありますか?
問題の原因は何でしょうか?
前提条件に加えて、Bluetooth仕様/プレゼンテーションスライド/記事の一部も参照してみてください。
市場にはBluetoothLowEnergyマウスがあります。マウスの通常のポーリングレートは125Hzであり、少なくとも2つの16バイト値とティックごとの追加のHIDオーバーヘッドを送信する必要があります。したがって、私の問題の解決策が利用できるはずです。
更新
LE接続完了イベントは、Bluetooth仕様バージョン4.0 Vol 2パートEセクション7.7.65.1で説明されています。さまざまな接続パラメーターについて、次の値を受け取ります。
Parameter Value Description
--------------------------------------------------
Conn_Interval 0x0054 Time = 105 ms
Conn_Latency 0x0000 Time = 0 ms
Supervision_Timeout 0x00fc Time = 2520 ms
Master_Clock_Accuracy 0x05 50 ppm
接続パラメータの更新を発行すると、問題が解決し、スループットが5 kbit/sから〜33 kbit/sに増加しました。 -)。ただし、これは予想される約305 kbit/sをまだ下回っています。
Conn_Interval = 0x000f = 18.75 ms
Conn_Latency = 0x0000
Supervision_Timeout = 0x00fc
〜305 kbit/sに到達する方法はありますか?
TSIを焼き付けて1か月待つことで、Appleから返信を受け取ることができます。
基本的に、彼らはその振る舞いがiOS5.1で意図されていると言っています。他のアプリがBluetoothとWiFiのどちらを使用しているかによってアプリのパフォーマンスが左右されることを望まないため、どういうわけか理にかなっています。
エンジニアのコメントによると-iOS5.1では、接続間隔中に6ペアの通知が必要です。つまり、6 * packetSize * 1000/intervalです。これは最大55kbpsに変換されます(最小間隔は20ミリ秒、パケットサイズは23バイトです)。 iPhoneとiPadの両方がBTクラシック、BT LE、WiFi間でアンテナを共有しているため、間隔ごとのペア数を制限し、間隔を最小にすることを決定しました。
iOS LEは、低電力トランスポートとして設計されています。より高いスループットの場合、BTクラシックはより優れた転送方法です。
私に戻る-上記のエンジニアのコメントに基づくと、200 kbsのスループットを達成したい場合は、クラシックBluetoothがその答えです。ただし、iPhone上のアプリケーションを操作したい場合は、これは単純な変更ではないことを理解できます。ClassicBTにはMFIライセンスが必要です。
パケットがドロップされたときに表示されるのは、iPhone側(おそらく私が思う)またはホスト側のいずれかのバッファオーバーフローが原因です。 iOS 11.2以降、Appleは、次のパケットを書き込む前にバッファの準備ができているかどうかを確認できるメカニズムを提供します。canSendWriteWithoutResponse:
パケットを書き込む前にcanSendWriteWithoutResponseがtrueになるまで待機すると、配信は受信バッファーに配置されたことが保証されますが、処理された(未確認)ことは保証されません。他に役立つ可能性があるのは、20を超えるMTUサイズをネゴシエートすることです。Appleは185B、最大251(拡張データ長、別名EDL)でMTUをサポートします。MTUでデータパケットをチャンク化する-3サイズ、パケット==(MTU-3)x接続間隔ごとに1。@ 185B MTU、24ミリ秒の接続間隔パケットがドロップされることなく、約48kbpsのスループットがあります。デバイスからiPhoneにデータを送信する場合、SDKはそのためには、「canSendWriteWithoutResponse」と同等のものが必要になります。私の場合、SiLabsハードウェア/ SDKを使用すると、
`` `
do {
result = gecko_cmd_gatt_server_send_characteristic_notification(
0xFF,
evt->data.evt_gatt_server_attribute_value.attribute,
chunk.length,
[chunk bytes])->result;
} while(result == bg_err_out_of_memory);
//retry until buffer is empty and ready for more
//then update the offset
offset += thisChunkSize;
`` `
これは、Appleからのビデオと.pdfで、さまざまなBLEテクニックと予想される速度を説明しています。MTU+接続間隔は、最大スループットを決定するために使用するものです。48kpsは簡単に達成でき、96kbpsで、おそらくもう少し高い可能性があります。
コアBluetoothの新機能
video: https://devstreaming-cdn.Apple.com/videos/wwdc/2017/712jqzhsxoww3zn/712/712_hd_whats_new_in_core_bluetooth.mp4?dl=1
pdf: https://devstreaming-cdn.Apple.com/videos/wwdc/2017/712jqzhsxoww3zn/712/712_whats_new_in_core_bluetooth.pdf
主な問題は、使用しているチップのバッファの問題であるようです。コア仕様、ボリューム3、パートF、3.3.2から:
応答PDUがない通知の場合、フロー制御はなく、通知はいつでも送信できます。
応答を必要としないコマンドには、フロー制御がありません。注:サーバーにはコマンドが殺到する可能性があり、上位層の仕様でこれを防ぐ方法を定義できます。
受信したものの、バッファオーバーフローなどの理由で処理できないコマンドや通知は破棄されます。したがって、これらのPDUは信頼性が低いと見なす必要があります。