PWM サーボのプロトコル、コマンド、キャリブレーション
本ページでは PWM ファームウェアのシリアルプロトコル、コマンド、キャリブレーション、パラメータの微調整を扱います。配線は PWM 配線、書き込みは PWM クイックスタート、デスクトップ/ウェブコントロールは PWM デスクトップツール / PWM ウェブコントロール を参照してください。
以下のコマンドはリポジトリの
AmazingHand-PWM/ディレクトリで実行します。ファームウェアのソース:firmware/AmazingHand_Serial/。
1. コマンドとジェスチャーの一覧
先頭 11 行がジェスチャーコマンドで、残りは直接駆動、左右の選択、繰り返し、停止、リンクテストのコマンドです。
| ジェスチャー/コマンド | コマンド | 説明 |
|---|---|---|
| グー | 0x01 | じゃんけん:全指を握る |
| チョキ | 0x02 | じゃんけん:人差し指+中指を伸ばして V 字 |
| パー | 0x03 | じゃんけん:全指を開く |
| サムズアップ | 0x04 | 親指を立て、他は握る |
| 挑発 1 | 0x05 | 人差し指を振る(「ダメダメ」) |
| 挑発 2 | 0x06 | 薬指を伸ばして揺らす(小指の代わり) |
| 開く | 0x07 | 全指を開く |
| 握り拳 | 0x08 | 全指を閉じる |
| OK | 0x09 | OK ジェスチャー |
| ピンチ | 0x0A | ピンチジェスチャー |
| 指差し | 0x0C | 人差し指を伸ばして「指差し」の動作 |
| 直接駆動 | 0xF0 | PWM サーボ 8 系統の角度を直接制御 |
| 左右手の設定 | 0xF1 | 左手/右手モードを切り替え |
| 繰り返し | 0xFE | 前回のジェスチャーを繰り返す |
| 停止 | 0xFF | 現在のジェスチャーを即座に終了 |
| NOP | 0x00 | リンクテスト |
注:コマンド 0x0B は無効化されています(旧「サムズダウン」は「サムズアップ」と動作が重複するため削除されました)。
2. ファームウェアのキャリブレーション(任意、初回推奨)
サーボの中心位置とパルス幅は実際の機構に合わせてキャリブレーションする必要があり、ファームウェアのソースを直接編集できます:
components/hand_servo/hand_servo.c冒頭のmiddle_pos[8]とmin_pw/mid_pw/max_pw[8]を編集します。
キャリブレーション後は再ビルドして書き込む必要があります。
3. シリアル通信プロトコル
3.1 物理層
| パラメータ | 値 |
|---|---|
| インターフェース | USB Serial (UART0) |
| ボーレート | 115200 |
| データビット | 8 |
| パリティ | なし (None) |
| ストップビット | 1 |
| フロー制御 | なし |
3.2 フレーム形式
ホスト → ESP32(コマンドフレーム)
┌────────┬────────┬──────────┬────────────────┬──────────┐
│ 0xAA │ CMD_ID │ DATA_LEN │ DATA[0 .. N-1] │ CHECKSUM │
│ 1 Byte │ 1 Byte │ 1 Byte │ N Bytes │ 1 Byte │
└────────┴────────┴──────────┴────────────────┴──────────┘
フレームヘッダ コマンドID データ長 データペイロード チェックサム- フレームヘッダ:固定
0xAA。1 フレームの開始を示します - CMD_ID:コマンド番号(コマンドリファレンス を参照)
- DATA_LEN:データペイロードのバイト数(0-8。8 を超えるフレームは無効)
- DATA:データペイロード。長さは DATA_LEN で決まります
- CHECKSUM:
CMD_ID ^ DATA_LEN ^ DATA[0] ^ ... ^ DATA[N-1](XOR チェックサム)
DATA_LEN = 0 の場合、CHECKSUM = CMD_ID になります。
ESP32 → ホスト(応答フレーム)
┌────────┬────────┬────────┬──────────┐
│ 0xBB │ CMD_ID │ STATUS │ CHECKSUM │
│ 1 Byte │ 1 Byte │ 1 Byte │ 1 Byte │
└────────┴────────┴────────┴──────────┘
フレームヘッダ コマンドID ステータスコード チェックサム- フレームヘッダ:固定
0xBB - CMD_ID:元のコマンド番号
- STATUS:ステータスコード(下表を参照)
- CHECKSUM:
CMD_ID ^ STATUS
ステータスコード
| STATUS | 意味 | 説明 |
|---|---|---|
| 0x00 | OK | コマンドを受け付け、実行を開始 |
| 0x01 | 無効なコマンド | CMD_ID がコマンド表にない |
| 0x02 | パラメータエラー | データ長または内容が正しくない |
| 0x03 | ビジー | ジェスチャー実行中で、新しいコマンドをまだ受け付けない |
| 0x10 | 完了 | ジェスチャーが終了 |
3.3 通信シーケンス
ホスト ESP32
│ │
│──── [AA 01 00 01] ────────→│ 「グー」コマンドを送信
│ │
│←─── [BB 01 00 01] ─────────│ ACK: コマンドを受け付け
│ │
│ (ジェスチャー実行中)
│ │
│←─── [BB 01 10 11] ─────────│ 完了: ジェスチャー終了
│ │
│──── [AA 02 00 02] ────────→│ 「チョキ」コマンドを送信
│ │
│←─── [BB 02 00 02] ─────────│ ACK
│ │3.4 ジェスチャーの停止とフレームタイムアウト
[AA FF 00 FF]を送信すると、実行中のジェスチャーをいつでも中断できます- ESP32 は 200ms 以内に 1 フレームを受信し終えないと自動的に破棄します(バイト欠落による恒久的な同期ずれを防ぐため)
- チェックサムが一致しないフレームは黙って破棄されるため、ホスト側はタイムアウト再送を実装してください
3.5 左右手モード
デフォルトは右手モードです。[AA F1 01 02 F2] で左手へ、[AA F1 01 01 F1] で右手へ切り替えます。左右手は親指の運動方向に影響します(グー/チョキ/サムズアップ/OK/ピンチなど、親指を含むジェスチャー)。
4. コマンドリファレンス
4.1 ジェスチャーコマンド(0x01–0x0A、0x0C)
これらのコマンドはデータペイロードが不要(DATA_LEN=0)で、ESP32 は受信するとすぐに対応するジェスチャーを実行します。
| コマンド | HEX フレーム | 応答 | 説明 |
|---|---|---|---|
| グー | AA 01 00 01 | BB 01 00 01 → BB 01 10 11 | 全指を握る |
| チョキ | AA 02 00 02 | BB 02 00 02 → BB 02 10 12 | 人差し指+中指を伸ばす |
| パー | AA 03 00 03 | BB 03 00 03 → BB 03 10 13 | 全指を開く |
| サムズアップ | AA 04 00 04 | BB 04 00 04 → BB 04 10 14 | 親指を立てる |
| 挑発 1 | AA 05 00 05 | BB 05 00 05 → BB 05 10 15 | 人差し指を振る(約 2.5s) |
| 挑発 2 | AA 06 00 06 | BB 06 00 06 → BB 06 10 16 | 薬指を揺らす(約 2.5s) |
| 開く | AA 07 00 07 | BB 07 00 07 → BB 07 10 17 | 全指を開く |
| 握り拳 | AA 08 00 08 | BB 08 00 08 → BB 08 10 18 | 全指を閉じる |
| OK | AA 09 00 09 | BB 09 00 09 → BB 09 10 19 | OK ジェスチャー |
| ピンチ | AA 0A 00 0A | BB 0A 00 0A → BB 0A 10 1A | ピンチジェスチャー |
| 指差し | AA 0C 00 0C | BB 0C 00 0C → BB 0C 10 1C | 人差し指を伸ばして「指差し」の動作 |
4.2 直接駆動コマンド(0xF0)
PWM サーボ 8 系統の角度を直接制御します。8 バイトのデータがそれぞれサーボ 1-8 に対応し、各バイトの値の範囲は 0-180 です。
例:すべてのサーボを中間位置(90°)へ
送信: AA F0 08 5A 5A 5A 5A 5A 5A 5A 5A F8
│ │ │ └── 0x5A ×8 (90°) ──┘ │
│ │ │ └── CHECKSUM
│ │ └── DATA_LEN = 8
│ └── CMD_DIRECT_DRIVE
└── フレームヘッダチェックサム = F0 ^ 08 ^ 5A ^ 5A ^ 5A ^ 5A ^ 5A ^ 5A ^ 5A ^ 5A = F8
同じ 0x5A を 8 個 XOR すると 0x00 になり、最終的に
0xF0 ^ 0x08 ^ 0x00 = 0xF8になります
例:人差し指を開く(サーボ1=170°、サーボ2=10°)、他は中間位置(90°)
送信: AA F0 08 AA 0A 5A 5A 5A 5A 5A 5A 58
└─170° └─10°4.3 左右手の設定(0xF1)
1 バイトのデータ:0x01 = 右手、0x02 = 左手。
右手に設定: AA F1 01 01 F1
左手に設定: AA F1 01 02 F24.4 制御コマンド
| コマンド | HEX フレーム | 説明 |
|---|---|---|
| NOP | AA 00 00 00 | リンクテスト。すぐに BB 00 00 00 を返す |
| 繰り返し | AA FE 00 FE | 前回のジェスチャーを繰り返す |
| 停止 | AA FF 00 FF | 現在のジェスチャーを即座に終了する |
4.5 応答早見表
無効なコマンドを受信した場合(存在しないコマンド 0xFC を例に):
送信: AA FC 00 FC
応答: BB FC 01 FD (STATUS=0x01 無効なコマンド)チェックサムの検証:
FC ^ 00 = FC、応答はFC ^ 01 = FD
5. ジェスチャーパラメータの微調整
5.1 パラメータの場所
各ジェスチャーの角度オフセットは #define マクロで定義されており、ロジックコードを変更せず数値だけを調整します。
- ESP-IDF 版:
components/hand_gestures/hand_gestures.c冒頭の「ジェスチャーパラメータ(ユーザー調整可)」領域
5.2 パラメータの意味
// 例:グーのジェスチャー
#define ROCK_IDX_OFF1 70 // 人差し指関節1のオフセット
#define ROCK_IDX_OFF2 -70 // 人差し指関節2のオフセット- 正の値 = 曲げて握る、負の値 = 伸ばして開く
- 各指に 2 つのオフセットがあり、
middle_pos(デフォルト 90°)からの相対値です - 差動構造:2 つのサーボは並んで軸心が一直線にあり、同方向の回転で左右の開き、逆方向の回転で屈伸を生みます。2 つのオフセット角の和が開きに、差が屈伸に対応します。
5.3 調整手順
- 対応するジェスチャーの
#defineマクロを探す - 数値を変更する(大きく → 振幅が大きくなる、小さく → 振幅が小さくなる)
- 再ビルドして書き込み、デスクトップツールで効果をテストする
- 動作が自然になるまで繰り返し微調整する
6. よくある問題
Q1: デスクトップツールがシリアルポートへ接続できない
- ESP32 が Type-C で PC へ接続されていることを確認
- デバイスマネージャーの COM 番号が GUI の選択と一致するか確認
- ボーレートが 115200 であることを確認
- シリアルポートを占有している他のソフトウェアを切断
Q2: コマンドを送っても反応がない
- まず
AA 00 00 00(NOP)を送り、BB 00 00 00を受信できることを確認 - ファームウェアが書き込み済みで、ターゲットチップが ESP32-S3 であることを確認
- 配線を確認(GND が共通グラウンドか)
Q3: ジェスチャーの振幅が違う、または向きが逆
ジェスチャーパラメータの微調整(第 5 節 を参照)へ進み、対応するマクロを調整します。
Q4: 左右手モードはどのジェスチャーに影響するか
グー/チョキ/サムズアップ/OK/ピンチなど親指を含むジェスチャーです。左右手を切り替えると親指のミラー方向が変わります。
Q5: 指が引っかかって伸びない
すべての収縮系ジェスチャーは実行前に自動的に「まず全手を展開してから収縮」するため、前のジェスチャーに指が引っかかるのを防ぎます。それでも引っかかる場合は、機械的な組み立てを確認するか、収縮の振幅を小さくしてください。

