ユーザ用ツール

サイト用ツール


ハイハイスクールアドベンチャー_m5stack_m5cardputer版

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
ハイハイスクールアドベンチャー_m5stack_m5cardputer版 [2024/11/06 03:31] – [BTキーボードをつなごう] arakiハイハイスクールアドベンチャー_m5stack_m5cardputer版 [2024/12/09 02:30] (現在) – [BTキーボードをつなごう] araki
行 321: 行 321:
             {             {
                 uint8_t c = input[i];                 uint8_t c = input[i];
-                if (c == 0) break;+                if (c == 0) continue;
                 if (memchr(buf, c, buflen) == NULL) keybuf.push(((uint16_t)mod << 8)|c);                 if (memchr(buf, c, buflen) == NULL) keybuf.push(((uint16_t)mod << 8)|c);
             }             }
行 393: 行 393:
 NimBLEDevice::setSecurityAuth()は全部trueにしてやります。 NimBLEDevice::setSecurityAuth()は全部trueにしてやります。
 これで無事につながらなかったキーボードがつながるようになりました。 これで無事につながらなかったキーボードがつながるようになりました。
 +
 +== キーボードが再接続できない ==
 +
 +BLEキーボードを接続した状態でしばらく何もしないで放置していると、キーボード側がパワーセーブモードに入って接続が切れます。
 +クライアント側には onDisconnect() の通知が送られて、接続が切れたことが認識されます。
 +
 +ここで、デバイスの再検索を始めて、打鍵するなどして復帰したキーボードから Advertiseがやってくればめでたく再接続になります。
 +
 +NimBLE のサンプルやそれを参考にした多くのコードが、次のような実装をしていたので私もそうしていました。
 +
 +<code>
 +void
 +ClientCallbacks::onDisconnect(NimBLEClient* pClient)
 +{
 +    Serial.print(pClient->getPeerAddress().toString().c_str());
 +    Serial.println(" disconnected - Starting scan");
 +    NimBLEDevice::getScan()->start(BTKeyBoard::scanTime);
 +}
 +</code>
 +
 +一見すると何の問題もありません。
 +実際、シリアルコンソールにも  disconnected - Starting scan と表示されて、いかにも動いているように見えますが実は全然動いていません。
 +一向にデバイスが再接続されないのです。
 +困った。
 +これでは、一気通貫にハイハイスクールアドベンチャーを最後までプレイするのでなければ、ゲームの途中でにっちもさっちもいかなくなってしまいます。
 +
 +さて、原因はなんでしょう?
 +もしかすると、一度接続したデバイスからの Advertiseを無視しているのかもしれません。
 +ならば <code>NimBLEDevice::getScan()->setDuplicateFilter(true);</code>とかすればいいのかもしれないと思って試してみました。
 +再接続はうまくいかないし、そもそも、最初の接続が完了するまで何度も Advertiseのコールバックがかかってきてしまいました。
 +筋違いのようです。
 +
 +じゃあ、なんなんだろう?
 +
 +ふと、callbackの中から NimBLEDevice::getScan()->start(0); とか呼んじゃダメなんじゃないか?ということに気づきました。
 +これ、つまりコールバック処理が完了しなくなって、おかしなことになっている可能性があるんじゃないかと。
 +
 +で、次のようにしました。
 +
 +<code>
 +static volatile bool connected = false;
 +
 +void
 +ClientCallbacks::onDisconnect(NimBLEClient* pClient)
 +{
 +    Serial.print(pClient->getPeerAddress().toString().c_str());
 +    Serial.println(" disconnected");
 +    connected = false;
 +}
 +</code>
 +
 +で、メイン処理の中で、
 +
 +<code>
 +    if (!connected)
 +    {
 +        Serial.println("Start scan.");
 +        NimBLEDevice::getScan()->start(scanTime);
 +    }
 +</code>
 +
 +という処理を足してやりました。
 +
 +結論。
 +
 +あっさり再接続しました_ノ乙(、ン、)_
 +
 +<code>
 +Connect to BLE Keybord.
 +Advertised HID Device found: Name: Notepad8, Address: XX:XX:XX:XX:XX:XX, appearance: 961, manufacturer data: YYYYYYYYYYYYYYYYYYYYYY, serviceUUID: 0x1812
 +Start connecting to server...
 +A new client created.
 +BLE Device connected.
 +Connected to XX:XX:XX:XX:XX:XX
 +RSSI: -60
 +Done.
 +XX:XX:XX:XX:XX:XX disconnected
 +Start scan.
 +Advertised HID Device found: Name: Notepad8, Address: XX:XX:XX:XX:XX:XX, appearance: 961, manufacturer data: YYYYYYYYYYYYYYYYYYYYYY, serviceUUID: 0x1812
 +Start connecting to server...
 +BLE Device connected.
 +Reconnected.
 +Connected to XX:XX:XX:XX:XX:XX
 +RSSI: -62
 +Done.
 +</code>
 +
 +== キーバッファ ==
 +
 +キーバッファの仕様は何種類か存在しているようである。
 +
 +最も多い実装は8bytesで、modifiers + padding + key buffer (6bytes) という構成で、手元ではバッファローのBSKBB335だけが11bytes で modifiers + key buffer (10bytes)というものである。
 +
 +キーバッファのサイズだとか、多分アラインメントを考慮したであろうパディングの有無や全体長などの差異はあれど、渡ってくる情報(modifiersやキーコード)に違いはない。
 +
 +が、キーバッファーの部分の扱いには、解釈違いのものがあるようである。
 +
 +当初、試したキーボード((BSKBB335/NimBLE版 Cardputer BT キーボード))では、キーが押されたときには先頭からキーコードが入って送られてきた。
 +なので、常にキーが押されればキーバッファの先頭にはキーコードがあるという想定だった。
 +
 +他のキーボードでもそれで問題は特にはなかった。
 +
 +が、ちょっと色気(?)を出して、シフトキーを押したりコントロールキーを押したりしたときにそれは起きた。
 +
 +文字が入力されない。
 +
 +仕方がないので、デバッグです。
 +調べてみたら、キーは渡ってきてます。
 +但し、なぜか二文字目で先頭は0です。
 +どうやら、キーボードによっては、modifiers が押されたのもキーバッファを消費する((ただしよりにもよってキーコードは0))ようです。
 +なので、0ならそこで打ち切りとしていた処理を、0なら飛ばすように変更しました。
 +
 +
 +
 +
 ==== 画面のスケーリング ==== ==== 画面のスケーリング ====
  
ハイハイスクールアドベンチャー_m5stack_m5cardputer版.1730863905.txt.gz · 最終更新: 2024/11/06 03:31 by araki