<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>IoT Dice on Deadline-Driven Developers</title><link>https://dddev.group/tags/iot-dice/</link><description>Recent content in IoT Dice on Deadline-Driven Developers</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Sat, 01 Aug 2026 02:20:00 +0900</lastBuildDate><atom:link href="https://dddev.group/tags/iot-dice/index.xml" rel="self" type="application/rss+xml"/><item><title>BNO085による投擲計測と出目予測に向けたIoT Diceの試作</title><link>https://dddev.group/posts/iot-dice-development/</link><pubDate>Sat, 01 Aug 2026 02:20:00 +0900</pubDate><guid>https://dddev.group/posts/iot-dice-development/</guid><description>&lt;p>サイコロが完全に止まれば、上面を調べるだけで出目は分かります。
では、最初に机へ触れた時点で、その後の跳ね方や転がり方まで計算して出目を予測できるでしょうか。&lt;/p>
&lt;p>この試行のために製作しているのが、&lt;strong>IoT Dice&lt;/strong>です。
BNO085で姿勢、角速度、線形加速度を測り、nRF5340からBluetooth Low EnergyでWebブラウザへ送ります。
本作は開発中で、現時点で動作するのは姿勢共有と3D表示までです。&lt;/p>
&lt;div class="img-center-wrapper">&lt;a href="https://dddev.group/iot-dice/architecture.png">
 &lt;img src="https://dddev.group/iot-dice/architecture_hu_346a975b21da4660.png"
 alt="BNO085の計測値をnRF5340からWebブラウザへ送り、Rapierで出目を予測するIoT Diceの構成"
 loading="lazy" decoding="async" class="img-center">
 &lt;/a>&lt;/div>
&lt;h2 id="姿勢共有と出目予測の2モード">姿勢共有と出目予測の2モード&lt;/h2>
&lt;p>IoT Diceには、送信するデータとブラウザ側の処理が異なる二つのモードがあります。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>モード&lt;/th>
 &lt;th>サイコロから送るデータ&lt;/th>
 &lt;th>Webブラウザで行う処理&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>姿勢共有&lt;/td>
 &lt;td>姿勢を表すクォータニオン&lt;/td>
 &lt;td>Three.jsで3Dサイコロの向きを更新&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>シミュレーション（実装中）&lt;/td>
 &lt;td>姿勢、角速度、線形加速度、並進速度、投擲状態、衝撃、確定した出目&lt;/td>
 &lt;td>Rapierによる出目予測、的中判定、投擲データの保存&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>現在のコードでは、Webアプリで「シミュレーション」を有効にすると、ファームウェアが投擲状態の判定を開始し、ストリームへ角速度、線形加速度、並進速度を加えます。
衝撃と出目確定は、姿勢ストリームとは別のイベントとして直ちに送信します。&lt;/p>
&lt;h2 id="13-mm角の基板にnrf5340とbno085を収める">13 mm角の基板にnRF5340とBNO085を収める&lt;/h2>
&lt;p>基板外形は13 mm × 13 mmです。
2層基板の中央にnRF5340を搭載したISP2053-AX-RSモジュールとBNO085を配置し、書き込み用の6ピンコネクターと状態表示用LEDを載せました。&lt;/p>
&lt;p>ファームウェアはnRF Connect SDK 3.4.0とZephyrを使い、nRF5340のアプリケーションコアで動作します。
BNO085とはSPIモード3、最大3 MHzで接続し、データ準備完了割り込みを待ってセンサーレポートを読み出します。&lt;/p>
&lt;p>物理シミュレーション内のサイコロは一辺16 mmとしているため、13 mm角はシミュレーションモデルの寸法ではなく、内蔵基板の寸法です。&lt;/p>
&lt;h2 id="磁気センサーを使わない6軸姿勢推定">磁気センサーを使わない6軸姿勢推定&lt;/h2>
&lt;p>BNO085には磁気センサーを含む回転ベクトルもありますが、IoT DiceではGame Rotation Vectorを使います。
実装予定の内蔵電池や受電コイルが磁場を乱す可能性があり、投擲中の方位補正が姿勢へ不連続な変化を加えるためです。
出目の判定には重力方向に対する各面の向きが分かればよく、絶対方位は必要ありません。&lt;/p>
&lt;p>ファームウェアは、次の三つのレポートを2.5 ms間隔で要求します。&lt;/p>
&lt;ul>
&lt;li>Game Rotation Vector：磁気センサーを使わない姿勢クォータニオン&lt;/li>
&lt;li>Calibrated Gyroscope：角速度&lt;/li>
&lt;li>Linear Acceleration：重力成分を除いた線形加速度&lt;/li>
&lt;/ul>
&lt;p>2.5 msは400 Hzに相当しますが、実際の出力速度はBNO085が提供できる範囲に制限されます。
BLE通知はセンサーのサンプル数ではなく経過時間でペーシングし、姿勢表示と記録の更新頻度を平均約60 Hzにしています。&lt;/p>
&lt;h2 id="静止から出目確定までを4状態で追跡する">静止から出目確定までを4状態で追跡する&lt;/h2>
&lt;p>姿勢の表示だけなら、受信したクォータニオンを3Dモデルへ反映すれば足ります。
出目を予測するには、手の中で動き始めた時点、自由落下、机との最初の衝突、静止を区別しなければなりません。&lt;/p>
&lt;p>ファームウェアは投擲を次の4状態で追跡します。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>状態&lt;/th>
 &lt;th>判定に使う量&lt;/th>
 &lt;th>役割&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>REST&lt;/td>
 &lt;td>角速度と線形加速度が300 ms継続して小さい&lt;/td>
 &lt;td>速度積分の基準を0へ戻す&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MOVING&lt;/td>
 &lt;td>静止条件から外れた&lt;/td>
 &lt;td>手から与えられた移動と回転を追う&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>FREEFALL&lt;/td>
 &lt;td>線形加速度の大きさが重力加速度付近に3サンプル続けて入った&lt;/td>
 &lt;td>落下時間を測る&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>TUMBLING&lt;/td>
 &lt;td>20 m/s²を超える衝撃を検出した&lt;/td>
 &lt;td>最初の着地から静止までを追う&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>並進速度は、線形加速度をクォータニオンで機体座標系からワールド座標系へ回転し、最後のRESTから数値積分して求めます。
これにより、自由落下だけでなく、手を離すまでに加えた速度も衝突時の初期条件へ含められます。&lt;/p></description></item></channel></rss>