この文書は、ExpressLRS(ELRS)を 外部 MCU(ESP32 など)から扱う ための実装メモです。
ELRS には大きく 2 つの層があります。
- ELRS の無線 OTA リンク
TX モジュールと RX の間で動く無線プロトコル - CRSF シリアルプロトコル
ELRS TX モジュールや ELRS 受信機と UART で接続するときに使う制御用プロトコル
外部 MCU から ELRS を扱う場合、実装対象として現実的で安定しているのは CRSF over UART です。
ELRS の OTA パケット形式は、ファームウェア世代、RF モード、周波数帯、ハードウェア構成に依存するため、この文書では OTA 層は高レベルの説明に留め、UART 側の CRSF を中心に整理します。
- ELRS は、FPV ドローンやロボットで広く使われる低遅延 RC リンクです。
2.4 GHz、900 MHz、一部デュアルバンドハードウェアをサポートします。- 公式情報では最大
1000 Hzのパケットレートが案内されています。 - ELRS は以下を運びます。
- RC 操作データ
- テレメトリ
- デバイス設定や管理トラフィック
ESP32 -> UART -> ELRS TX モジュール -> OTA 無線 -> ELRS RX
ESP32 から RC 指令を生成したい場合の構成です。
実際には ESP32 から ELRS TX モジュールへ CRSF 0x16 RC_CHANNELS_PACKED フレームを送り、必要に応じてリンク統計などの返答を受け取ります。
注意:
- 汎用 CRSF の仕様では、送信機から TX モジュールへの接続は 単線 half-duplex として説明されています。
- ELRS TX モジュールによっては、モジュールベイ信号ではなく通常の UART に近い形でアクセスできる場合があります。
- もしモジュールがベイ用の half-duplex 信号や反転信号しか出していないなら、レベル変換や極性変換は使用者側で対応が必要です。
ELRS RX -> UART -> ESP32
ESP32 が制御対象そのものになる場合の構成です。最も扱いやすい構成でもあります。
- ELRS 受信機のシリアル出力を
CRSFに設定する - ESP32 側で RC チャンネルを UART から受信する
- 必要なら ESP32 からテレメトリを上流へ返す
カスタムロボット、ローバー、ジンバル、独自制御機器では、この構成が最も実用的です。
ESP32 から見た場合、ELRS の無線リンクは次のような性質を持つブラックボックスとして扱えます。
- 双方向の低遅延パケット通信である
- パケットレート、テレメトリ比率、スイッチモード、モデルマッチ設定によって内部挙動が変わる
- 最大
16チャンネルの制御情報を扱える - ただし RF 側のスイッチ圧縮やフル解像度モードは ELRS 設定に依存する
そのため、外部 MCU から ELRS の RF パケットを直接生成しようとするより、CRSF を話す 方が正しい実装方針です。
| 接続区間 | トポロジ | 標準ボーレート | フォーマット | 信号 |
|---|---|---|---|---|
| 送信機 -> TX モジュール | 単線 half-duplex | 400000 baud |
8N1 |
ハード依存で反転/非反転 |
| RX -> FC / 車載 MCU | 2 線 full-duplex | 416666 baud |
8N1 |
非反転 |
ELRS まわりでは、受信機と下流コントローラの接続に 420000 baud が実用上よく使われます。
このリポジトリのサンプルコードも次の前提にしています。
420000 baud8 data bitsno parity1 stop bit3.3V UART
ESP32 を ELRS 受信機につなぐ場合の基本配線:
- ESP32 の
TX-> ELRS RX のRX - ESP32 の
RX-> ELRS RX のTX GND共通- 非反転 UART
CRSF の UART 通信はフレーム単位です。
+--------+--------+------+---------+------+
| Sync | Length | Type | Payload | CRC8 |
+--------+--------+------+---------+------+
+--------+--------+------+-------------+--------+---------+------+
| Sync | Length | Type | Destination | Origin | Payload | CRC8 |
+--------+--------+------+-------------+--------+---------+------+
Sync- シリアル同期バイト
0xC8 - またはデバイスアドレス
0xEC/0xEEなど
- シリアル同期バイト
Length- 先頭 2 バイト(
Sync,Length)を含まない - 有効範囲は
2..62
- 先頭 2 バイト(
- Sync と CRC を含めた最大フレーム長は
64バイト CRC8- 多項式は
0xD5 - 計算対象は
Type + Payload SyncとLengthは CRC に含めない
- 多項式は
| 意味 | アドレス |
|---|---|
| Broadcast | 0x00 |
| Flight Controller / Serial Sync | 0xC8 |
| Remote Control | 0xEA |
| CRSF Receiver | 0xEC |
| CRSF Transmitter Module | 0xEE |
典型的な使い方:
- ESP32 から ELRS TX モジュールへ RC を送るときは
0xEE - 車載 MCU から ELRS 受信機へテレメトリを返すときは
0xC8
用途:
- コントローラ -> TX モジュール
- 受信機 -> Flight Controller / 車載 MCU
Payload:
16チャンネル- 各チャンネルは
11bit - 全体で
22バイト - パック順は実質 LSB-first / little-endian 的なビット詰め
Flight Controller 側で一般的に使われる CRSF の変換式:
#define TICKS_TO_US(x) (((x) - 992) * 5 / 8 + 1500)
#define US_TO_TICKS(x) (((x) - 1500) * 8 / 5 + 992)代表値:
- 中立
1500 us->992 - おおよそ
988 us->172 - おおよそ
2012 us->1811
ELRS 実運用での慣例:
CH1..CH4がメイン操作軸CH5(AUX1) が arm/disarm に使われることが多い
フェイルセーフ上の注意:
0x16フレームが来なくなったら、安全側へ遷移するべきです- 汎用 CRSF 仕様では、"cut" モード時に FC 側フェイルセーフを発火させるまで最大
1 秒ほど見込む実装が案内されています
Payload 構成:
| Byte(s) | 意味 |
|---|---|
| 0 | uplink RSSI antenna 1 (dBm * -1) |
| 1 | uplink RSSI antenna 2 (dBm * -1) |
| 2 | uplink link quality (%) |
| 3 | uplink SNR(符号付き dB) |
| 4 | 使用中アンテナ |
| 5 | RF プロファイル / モード index |
| 6 | TX 出力 enum/index |
| 7 | downlink RSSI (dBm * -1) |
| 8 | downlink link quality (%) |
| 9 | downlink SNR(符号付き dB) |
リンク健全性を監視したいとき、ESP32 側で最も実用的なフレームです。
受信機寄りの簡易リンク統計:
| Byte(s) | 意味 |
|---|---|
| 0 | RSSI (dBm * -1) |
| 1 | RSSI (%) |
| 2 | link quality (%) |
| 3 | SNR(符号付き dB) |
| 4 | RF power(dBm) |
送信機寄りの簡易リンク統計:
0x1C と同じ内容に加えて:
| Byte(s) | 意味 |
|---|---|
| 5 | frames per second / 10 |
Payload:
- NUL 終端文字列
単純で扱いやすいため、サンプルコードの「上流へ返すテレメトリ」の例として使いやすいフレームです。
- UART を
420000 8N1で初期化する 4 msから10 ms周期で0x16RC フレームを送る- 明示的に安全確認が取れるまで、スロットル低・
CH5低を維持する - 戻りの
0x14/0x1C/0x1Dを読む
- 受信機のシリアル出力を
CRSFに設定する - 入ってくる
0x16フレームをパースする - 必要に応じて ticks を us に変換する
- チャンネル閾値でアプリケーション処理を行う
- 必要なら
0x21 Flight Modeのような単純なテレメトリを返す
ELRSSPEC.mdesp32/crsf.hesp32/crsf.cesp32/elrs_tx_to_module_example.cesp32/elrs_rx_from_receiver_example.ctest/crsf_selftest.c
- ELRS のネイティブ OTA パケット形式そのものは固定仕様として扱っていません
- バインド、周波数ホッピング、RF チップ制御、ネイティブ OTA モデム処理は実装していません
- サンプルコードは UART 側の CRSF に絞っています
これは、単体 ESP32 アプリケーションが ELRS と連携するための正しい実装点だからです
- TBS CRSF protocol specification:
- CRSF working group repository:
- ExpressLRS project:
- ExpressLRS Model Matching:
- ExpressLRS ArduPilot setup note (
420Kbaud): - ExpressLRS packet rate / signal health: