実際の構造は次の通りです。
- RX は ExpressLRS リンクから RC データを受信する
- そのデータを内部で共通のチャンネルデータとして保持する
- UART 出力時に、
CRSF、SBUS、SUMDなどのどのプロトコルで出すかを選ぶ
そのため、SBUS を選んだ場合は、UART には CRSF ではなく SBUS フレームが出ます。
S.BUSは RX の UART 出力プロトコルとして実装済みSBUSとInverted SBUSの両方を選択可能- ESP32 では第 2 UART にも SBUS を出力可能
- 実装は事実上の出力専用
- いくつか注意点と未完了部分が残っている
README では SBUS が対応 receiver protocol の 1 つとして明記されています。
README.md:50
RX の serial protocol enum には以下があります。
PROTOCOL_SBUSPROTOCOL_INVERTED_SBUS
ESP32 の第 2 UART 側には以下があります。
PROTOCOL_SERIAL1_SBUSPROTOCOL_SERIAL1_INVERTED_SBUS
参照:
src/include/common.h:229src/include/common.h:244
RX パラメータでは以下が公開されています。
ProtocolにSBUS/Inverted SBUS- ESP32 の
Protocol2にSBUS/Inverted SBUS SBUS failsafe
参照:
src/lib/rx-crsf/RXParameters.cpp:34src/lib/rx-crsf/RXParameters.cpp:42src/lib/rx-crsf/RXParameters.cpp:50
Web UI の serial panel にも以下があります。
Serial 1 ProtocolSerial 2 ProtocolSBUS Failsafe
参照:
src/html/src/utils/globals.js:1src/html/src/pages/serial-panel.js:34src/html/src/pages/serial-panel.js:63
SBUS 出力の実体は SerialSBUS です。
参照:
src/src/rx-serial/SerialSBUS.cpp:14src/src/rx-serial/SerialSBUS.h:5
rx_main.cpp では、選択された serial protocol が以下のいずれかの場合に:
PROTOCOL_SBUSPROTOCOL_INVERTED_SBUSPROTOCOL_DJI_RS_PRO
UART を SBUS 系設定で初期化し、SerialSBUS を生成します。
参照:
src/src/rx_main.cpp:1269src/src/rx_main.cpp:1341
ESP32 では Serial1 側でも同様です。
参照:
src/src/rx_main.cpp:1420
SBUS 出力時の UART 設定は以下です。
- baud rate:
100000 - serial format:
8E2 - 出力周期: 約
9 ms
参照:
src/src/rx_main.cpp:1271src/src/rx_main.cpp:1316src/src/rx-serial/SerialSBUS.cpp:11
正しい理解は次の流れです。
- ExpressLRS RX が無線リンクから RC データを受信する
- ファームウェアがそれを共通のチャンネルデータとして保持する
- UART 出力時に、選択されたプロトコルでシリアライズする
SBUSを選べば UART 出力は SBUS になるCRSFを選べば UART 出力は CRSF になる
したがって、正確には
RX が UART に SBUS を出力できる
であって、
CRSF 出力を SBUS に変換している
ではありません。
- RX の UART 出力としての
SBUS - RX の UART 出力としての
Inverted SBUS - ESP32 第 2 UART での
SBUS - SBUS failsafe の以下 2 モード
No PulsesLast Position
参照:
src/lib/rx-crsf/RXParameters.cpp:50src/lib/WIFI/devWIFI.cpp:382src/lib/WIFI/devWIFI.cpp:573
SerialSBUS::processBytes() は空実装なので、このクラスには SBUS 入力処理は見えていません。
参照:
src/src/rx-serial/SerialSBUS.h:13
今回の調査では、RX 側の SerialSBUS に相当するような TX 側の SBUS 出力経路は見つかっていません。
設計は「UART ごとに 1 つの出力プロトコルを選ぶ」形です。
ESP32 では UART ごとに別プロトコルを選べますが、それでも 1 UART = 1 プロトコルです。
SBUS を実際に使えるかどうかは receiver target の構成次第です。
- target が専用 serial pin を持っている場合がある
- PWM 可能な target では pin を serial 用に再割当できる場合がある
使える serial pin も PWM 再割当経路もない target では、serial output 自体が使えません。
参照:
src/include/targets.h:38src/include/target/Unified_ESP_RX.h:2src/include/target/Unified_ESP_RX.h:4src/src/rx_main.cpp:1990
backend と Lua では sbus-failsafe を扱っていますが、Web UI のコードでは SBUS failsafe の <select> が this.sbusFailsafe に変更を反映していないように見えます。
そのため、UI には表示されても、その画面から正しく保存できない可能性があります。
参照:
src/html/src/pages/serial-panel.js:76src/html/src/pages/serial-panel.js:163src/html/src/pages/serial-panel.js:178
enum には FAILSAFE_SET_POSITION がありますが、SerialSBUS.cpp にはこのケースの TODO が残っています。
参照:
src/include/common.h:261src/src/rx-serial/SerialSBUS.cpp:29
devSerialIO.cpp には、SBUS writer が固定 9 ms 周期で動くため、通常の confirmFrameAvailable() による制御と完全には一致しない、という TODO コメントがあります。
コメントでは model-match や team-race 周辺の挙動も複雑さが残っている点として触れられています。
参照:
src/src/rx-serial/devSerialIO.cpp:208
git 履歴を見る限り、SBUS は一度入れて放置された機能ではなく、継続的に手が入っています。
2023-03-13e5e57fb0CRSF/SBUS の選択式 serial protocol を導入2023-05-07c37b7aaeSBUS failsafe modes2024-05-18499697caSBUS last-position failsafe の修正2024-06-02e401cbbdESP32 receiver の第 2 serial 対応2024-07-153a617074Lua 上の SBUS failsafe 表示修正
このリポジトリにおける S.BUS 対応状況は次の通りです。
- RX の UART 出力としては実装済み
- Lua と Web UI から選択可能
SBUS/Inverted SBUSの両方に対応- ESP32 では第 2 UART にも出せる
- SBUS 入力経路は見当たらない
- 同一 UART での CRSF + SBUS 同時出力機能ではない
- 既知の caveat と未実装部分が少し残っている
要するに:
ExpressLRS RX は、選択された serial protocol として UART に S.BUS を出力できる。