RN-42 を使用して Bluetooth 2.1 経由でデバイスからデータを読み取ろうとしています。デバイスは iPhone または iPad Mini にペアリングされ、データは短時間ストリーミングされますが、iOS & BT モジュールは数秒 (10 未満) 以内に切断 (ペアリング解除) されます。デバイスは 5 ~ 10kB/s のデータを出力しており、Bluetooth の仕様に十分収まっています。また、関数 NSInputStream [NSInputStream read: maxLength:] を実行すると、返されるバイト数が常に 158 以下になることにも気付きました。アプリとハードウェアはクラッシュしませんが、Bluetooth のペアリングが解除されるだけです。
デバイスは切断後も RN42 にデータを送信し続けているため、電子機器側の問題の可能性が低くなります。このセットアップは、Android デバイスでも問題なく機能します。切断やクラッシュなしでデータをストリーミングできます。
私が試したこと...
- Apple が提供する外部アクセサリの例、EADemo に従いました。
- ポーリングの代わりに実行ループを純粋に使用します。
- この投稿で提案されているように、ストリームをバックグラウンド スレッドに配置します。
- パフォーマンスを向上させるためにすべての NSLog を削除します。
- デバッグおよびリリース モードでコンパイルされます。
iOS と BT モジュールが接続されたままになり、切断する前にデータを転送できるようになるため、データ転送が遅くなります (つまり、5kB/s 未満)。
#define EAD_INPUT_BUFFER_SIZE 1024
/**
* Stream delegate
*/
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
[... other cases ...]
case NSStreamEventHasBytesAvailable:
{
uint8_t buf[EAD_INPUT_BUFFER_SIZE];
unsigned int len = 0;
len = [(NSInputStream *)aStream read:buf maxLength:EAD_INPUT_BUFFER_SIZE];
if(len) {
// Read successful, process data
} else {
// Fail
}
break;
}
default:
break;
}
}
/**
* Stream delegate with polling (for better or worse)
*/
[...]
case NSStreamEventHasBytesAvailable:
{
while ([[_session inputStream] hasBytesAvailable])
{
// Read the data
NSInteger bytesRead = [[_session inputStream] read:_buf maxLength:EAD_INPUT_BUFFER_SIZE];
if (bytesRead > 0) {
// Read successful, process data
} else if (bytesRead == 0) {
// End of buffer reached
return;
} else if (bytesRead == -1) {
// Failed to read
return;
}
}
break;
[...]