Bluetoothモジュール は単なる無線ではない。シールドの下にはGPIO、I2C、SPI、UART、ADC、PWM、タイマを持つ本物のMCUがいる。センサや周辺をそのMCUにどう配線し、ドライバソフトをどう構成するかが、製品の信頼性・低消費・保守性を決める。本稿は実践的な現場ガイドだ。
バス比較
| バス | 信号線 | 速度 | トポロジ | アドレス | 向く用途 |
|---|---|---|---|---|---|
| GPIO | 1-2 | なし | 点 | なし | ボタン、LED、enable |
| I2C | 2 (SDA/SCL) | 100 k-1 MHz | マルチドロップ | 7/10bit | 多数センサ、設定レジスタ |
| SPI | 4 (MOSI/MISO/SCK/CS) | 1-32 MHz | 点(デバイス每CS) | CSピン | 高速、表示、フラッシュ |
| UART | 2 (TX/RX) | 数Mbpsまで | 点 | なし | GNSS、デバッグ、レガシー |
目安:少ないピンで多数の低速センサにはI2C、スループットか遅延が効くならSPI、別チップのシリアルコンソール会話にはUART。
I2Cの罠
- プルアップ:100 kHz・中程度バス容量の定番は4.7 kOhm。R_minは最大シンク電流から、R_maxは立上り時間から:R_max <= t_r / (0.847 * C_bus)。200 pF・立上り1 usの長バスならR <= 約5.9 kOhm。
- クロックストレッチ:スレーブがSCLを低く保持する場合がある。マスタが対応せねば遅いセンサがバスを固める。
- バスロック復帰:転送中にスレーブがリセットされるとSCLが低止まりする。復帰はSCLを9パルストグルし、スタック解除後STOPを送る。ドライバに組み込め。
- アドレス衝突:同じ固定アドレスのセンサ2個はMUX(TCA9548A等)かピンストラップ版が必要。
SPIの罠
- CSタイミング:CSアサート、クロック前セットアップ、最終ビット後ホールドを守る。多くのフラッシュはコマンド間にCSハイを要する。
- モード(CPOL/CPHA):間違えると全バイトがズレる。デバイス毎に明記。
- DMA:SPI 8 MHzは1 MB/s。CPUポキ代入だと両コアを焼く。ストリーミング(センサフュージョン、音声)はリングバッファでDMAを。
- MISO競合:選択デバイスのみMISOを駆動。CS配線ミスで2デバイスが競う。
UARTの罠
- ボーレート誤差:許容は通常2%。RC発振3%のモジュールは115200で壊れる。水晶を使うか低ボーレートに。
- フロー制御:高スループットを信じる前にRTS/CTSを有効に。さもなくば負荷で落字。
- オーバーラン:ISRがFIFOを十分早く払えねば、FIFOトリガを大きくするかDMAへ。
割込待ち時間の予算
ピン変化からISに至るまで:
- 低消費からのSoC起動:1-10 us(リテンション状態依存)
- ISR入り+プロローグ:1 us未満
- クリティカルセクション:殺し屋。長い disable_irq() ブロックは他全割込を遅らせる。クリティカルは数マイクロ秒に。仕事はタスクへ回せ。
64 MHzのnRF52840で清潔なISRは数マイクロ秒で発火。ログ関数内5 msのクリティカルセクションは1 kHzサンプリングの締切を破る。
クロックゲーティングと周辺電力
未使用周辺はアイドルでもuAを食う。有効のままのUART 3 uA、ADC基準10 uA、予備タイマ2 uA – 5 uAを吸うべきタグで純粋に15 uAの無駄。使わぬ周辺は無効に、無線アイドル時はHFクロックをゲート。
ドライバ設計
階層的・非ブロッキングを好め:
<h1>擬似:DMA+タイムアウト付非ブロッキングI2C読</h1>
def read_sensor(dev, reg, buf):
i2c.start_write(dev, [reg])
i2c.start_read_dma(dev, buf, done_cb)
return # ブロックするな
def done_cb(buf):
queue.put(("sensor", buf)) # RTOSタスクが後で処理
- HAL層:レジスタ上の薄ラッパ、チップ間同一API。
- ドライバ層:センサ固有の初期化・較正・単位変換。
- サービス層:バスを所有しアクセスを直列化しキューを公開するRTOSタスク。
- 割込内でブロックするな。合図のみ。
これでハードリアルタイムを要する無線スタックが遅いセンサ読みに飢えるのを防ぐ。
レベルシフト
1.8 Vモジュールが3.3 Vセンサと話すには全線にレベルシフタ(または1.8 V耐性センサ)が要る。ここを忘れるとロジアナでは消える間欠破損が出る。
よくある罠表
| 症状 | 推定原因 |
|---|---|
| バスが無作為に止まる | I2Cスレーブ低止まり、復帰なし |
| SPI読みがズレる | 誤ったCPOL/CPHA |
| UART落字 | フロー制御無し/小FIFO |
| 高アイドル電流 | 周辺がゲートオフされず |
| 締切逸失 | 長いクリティカルセクション |
| 間欠データ | レベルシフタ欠落 |
まとめ
Bluetoothモジュール の成否は無線の周りの部分で決まる。バスは速度とピン数で選び、I2Cプルアップを計算し、SPIのCSタイミングを守り、スループットはDMA、クリティカルセクションは極小に、未使用周辺は全ゲート。HAL・ドライバ・サービスタスク・キューの清潔な階層で無線スタックをリアルタイムに、ファームをデバッグ可能に保て。