Skip to content

Instantly share code, notes, and snippets.

@GOROman
Created March 8, 2026 00:41
Show Gist options
  • Select an option

  • Save GOROman/2053af377d082856f667cd9b909d1ced to your computer and use it in GitHub Desktop.

Select an option

Save GOROman/2053af377d082856f667cd9b909d1ced to your computer and use it in GitHub Desktop.
ELRS S.BUS

ExpressLRS S.BUS 調査メモ

概要

実際の構造は次の通りです。

  • RX は ExpressLRS リンクから RC データを受信する
  • そのデータを内部で共通のチャンネルデータとして保持する
  • UART 出力時に、CRSFSBUSSUMD などのどのプロトコルで出すかを選ぶ

そのため、SBUS を選んだ場合は、UART には CRSF ではなく SBUS フレームが出ます。

結論

  • S.BUS は RX の UART 出力プロトコルとして実装済み
  • SBUSInverted SBUS の両方を選択可能
  • ESP32 では第 2 UART にも SBUS を出力可能
  • 実装は事実上の出力専用
  • いくつか注意点と未完了部分が残っている

どこで公開されているか

README

README では SBUS が対応 receiver protocol の 1 つとして明記されています。

  • README.md:50

プロトコル定義

RX の serial protocol enum には以下があります。

  • PROTOCOL_SBUS
  • PROTOCOL_INVERTED_SBUS

ESP32 の第 2 UART 側には以下があります。

  • PROTOCOL_SERIAL1_SBUS
  • PROTOCOL_SERIAL1_INVERTED_SBUS

参照:

  • src/include/common.h:229
  • src/include/common.h:244

Lua / Receiver Parameters

RX パラメータでは以下が公開されています。

  • ProtocolSBUS / Inverted SBUS
  • ESP32 の Protocol2SBUS / Inverted SBUS
  • SBUS failsafe

参照:

  • src/lib/rx-crsf/RXParameters.cpp:34
  • src/lib/rx-crsf/RXParameters.cpp:42
  • src/lib/rx-crsf/RXParameters.cpp:50

Web UI

Web UI の serial panel にも以下があります。

  • Serial 1 Protocol
  • Serial 2 Protocol
  • SBUS Failsafe

参照:

  • src/html/src/utils/globals.js:1
  • src/html/src/pages/serial-panel.js:34
  • src/html/src/pages/serial-panel.js:63

実装の中身

Serial ドライバ

SBUS 出力の実体は SerialSBUS です。

参照:

  • src/src/rx-serial/SerialSBUS.cpp:14
  • src/src/rx-serial/SerialSBUS.h:5

どのように選ばれるか

rx_main.cpp では、選択された serial protocol が以下のいずれかの場合に:

  • PROTOCOL_SBUS
  • PROTOCOL_INVERTED_SBUS
  • PROTOCOL_DJI_RS_PRO

UART を SBUS 系設定で初期化し、SerialSBUS を生成します。

参照:

  • src/src/rx_main.cpp:1269
  • src/src/rx_main.cpp:1341

ESP32 では Serial1 側でも同様です。

参照:

  • src/src/rx_main.cpp:1420

UART 設定

SBUS 出力時の UART 設定は以下です。

  • baud rate: 100000
  • serial format: 8E2
  • 出力周期: 約 9 ms

参照:

  • src/src/rx_main.cpp:1271
  • src/src/rx_main.cpp:1316
  • src/src/rx-serial/SerialSBUS.cpp:11

正しい理解

正しい理解は次の流れです。

  1. ExpressLRS RX が無線リンクから RC データを受信する
  2. ファームウェアがそれを共通のチャンネルデータとして保持する
  3. UART 出力時に、選択されたプロトコルでシリアライズする
  4. SBUS を選べば UART 出力は SBUS になる
  5. CRSF を選べば UART 出力は CRSF になる

したがって、正確には

RX が UART に SBUS を出力できる

であって、

CRSF 出力を SBUS に変換している

ではありません。

対応しているもの

  • RX の UART 出力としての SBUS
  • RX の UART 出力としての Inverted SBUS
  • ESP32 第 2 UART での SBUS
  • SBUS failsafe の以下 2 モード
    • No Pulses
    • Last Position

参照:

  • src/lib/rx-crsf/RXParameters.cpp:50
  • src/lib/WIFI/devWIFI.cpp:382
  • src/lib/WIFI/devWIFI.cpp:573

対応が見えないもの

SBUS 入力

SerialSBUS::processBytes() は空実装なので、このクラスには SBUS 入力処理は見えていません。

参照:

  • src/src/rx-serial/SerialSBUS.h:13

TX 側の SBUS

今回の調査では、RX 側の SerialSBUS に相当するような TX 側の SBUS 出力経路は見つかっていません。

同一 UART での CRSF + SBUS 同時出力

設計は「UART ごとに 1 つの出力プロトコルを選ぶ」形です。
ESP32 では UART ごとに別プロトコルを選べますが、それでも 1 UART = 1 プロトコルです。

ハードウェア / target 条件

SBUS を実際に使えるかどうかは receiver target の構成次第です。

  • target が専用 serial pin を持っている場合がある
  • PWM 可能な target では pin を serial 用に再割当できる場合がある

使える serial pin も PWM 再割当経路もない target では、serial output 自体が使えません。

参照:

  • src/include/targets.h:38
  • src/include/target/Unified_ESP_RX.h:2
  • src/include/target/Unified_ESP_RX.h:4
  • src/src/rx_main.cpp:1990

注意点

1. Web UI の SBUS failsafe は未完成に見える

backend と Lua では sbus-failsafe を扱っていますが、Web UI のコードでは SBUS failsafe の <select>this.sbusFailsafe に変更を反映していないように見えます。

そのため、UI には表示されても、その画面から正しく保存できない可能性があります。

参照:

  • src/html/src/pages/serial-panel.js:76
  • src/html/src/pages/serial-panel.js:163
  • src/html/src/pages/serial-panel.js:178

2. FAILSAFE_SET_POSITION は SBUS では未実装

enum には FAILSAFE_SET_POSITION がありますが、SerialSBUS.cpp にはこのケースの TODO が残っています。

参照:

  • src/include/common.h:261
  • src/src/rx-serial/SerialSBUS.cpp:29

3. 出力周期と frame-availability の整合に TODO がある

devSerialIO.cpp には、SBUS writer が固定 9 ms 周期で動くため、通常の confirmFrameAvailable() による制御と完全には一致しない、という TODO コメントがあります。

コメントでは model-match や team-race 周辺の挙動も複雑さが残っている点として触れられています。

参照:

  • src/src/rx-serial/devSerialIO.cpp:208

履歴メモ

git 履歴を見る限り、SBUS は一度入れて放置された機能ではなく、継続的に手が入っています。

  • 2023-03-13 e5e57fb0 CRSF/SBUS の選択式 serial protocol を導入
  • 2023-05-07 c37b7aae SBUS failsafe modes
  • 2024-05-18 499697ca SBUS last-position failsafe の修正
  • 2024-06-02 e401cbbd ESP32 receiver の第 2 serial 対応
  • 2024-07-15 3a617074 Lua 上の 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 を出力できる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment