🧪 새 튜토리얼이 계속 업데이트 중 — 로봇 팔부터 센서까지
본문으로 건너뛰기

03-PWM 서보 버전-사용 매뉴얼 ​

목차 ​

  1. 개요

  2. 하드웨어 배선

  3. 펌웨어 컴파일 및 플래싱

  4. 시리얼 통신 프로토콜

  5. 명령 레퍼런스

  6. 호스트 PC 사용 튜토리얼

  7. 제스처 추적

  8. 제스처 파라미터 미세 조정

  9. 자주 묻는 질문


1. 개요 ​

본 펌웨어는 ESP32-S3 개발 보드에서 실행되며, PWM 신호를 통해 8채널 서보를 제어하여 로봇 손이 제스처를 수행하도록 구동합니다. 호스트 PC(PC/라즈베리파이/기타 MCU)는 USB 시리얼로 바이너리 프레임 명령을 전송하고, ESP32가 해석한 후 해당 제스처를 실행하고 응답을 반환합니다.

프로젝트는 두 세트의 펌웨어 구현을 제공합니다:

펌웨어디렉터리특징
ESP-IDF 버전(권장)esp-idf/AmazingHand_Serial/컴포넌트화된 프로젝트 구조, FreeRTOS 듀얼 태스크, 프로덕션 준비 완료

두 펌웨어는 동일한 시리얼 프로토콜과 동일한 명령 집합을 공유하며, 제스처 파라미터는 서로 참고할 수 있습니다.

지원 제스처(제스처 명령 11개) ​

제스처명령설명
바위0x01가위바위보: 모든 손가락 주먹
가위0x02가위바위보: 검지+중지를 펼쳐 V자
보0x03가위바위보: 모든 손가락 펼침
엄지 척0x04엄지를 세우고 나머지는 주먹
도발10x05검지 흔들기("아니아니아니")
도발20x06약지를 펼쳐 흔들기(새끼손가락 대체)
펼치기0x07모든 손가락 펼침
주먹0x08모든 손가락 닫기
OK0x09OK 제스처
핀치0x0A핀치 제스처
가리키기0x0C검지를 펼쳐 "가리키기" 동작
직접 구동0xF08채널 서보 각도를 직접 제어
좌우손 설정0xF1왼손/오른손 모드 전환
반복0xFE마지막 제스처를 반복 실행
정지0xFF현재 제스처를 즉시 종료
NOP0x00링크 테스트

참고: 명령 0x0B는 사용 중지되었습니다(기존 "엄지 아래로"가 "엄지 척" 동작과 중복되어 제거됨).


2. 하드웨어 배선 ​

적용 하드웨어 ​

항목모델
메인 컨트롤러ESP32-S3 개발 보드(Youxin YX-ESP32-S3 또는 동급)
서보8채널 PWM 아날로그 서보 (SG90 또는 동급)
어댑터 보드PWM 서보 어댑터 보드

ESP32-S3 개발 보드에는 두 개의 Type-C 인터페이스가 있습니다:

  • 내장 USB Serial/JTAG: ESP32-S3 칩 내장 USB 컨트롤러에 직접 연결

  • 외장 FT232: FT232 USB-시리얼 변환 칩을 통해 통신

두 인터페이스 모두 시리얼 통신에 사용할 수 있으며, 어느 하나를 선택하면 됩니다. 호스트 PC에서 해당 시리얼 장치 이름을 선택하세요.

서보 → 어댑터 보드 ​

8개 서보의 3P 플러그를 ID 번호에 따라 어댑터 보드의 서보 1-8 핀 헤더에 꽂습니다.

어댑터 보드 → ESP32-S3 ​

어댑터 보드ESP32-S3 GPIO설명
PWM14검지 관절1
PWM25검지 관절2
PWM36중지 관절1
PWM47중지 관절2
PWM515약지 관절1
PWM616약지 관절2
PWM717엄지 관절1
PWM818엄지 관절2
5V5V전원 공급(어댑터 보드에서 인출)
GNDGND반드시 공통 접지, 최소 한 가닥 연결

좌우손은 동일한 GPIO 매핑을 공유합니다. "왼손" 모드로 전환하면 펌웨어가 제스처 내에서 엄지 운동 방향을 미러링하며, 핀은 변경되지 않습니다.

전원 공급 ​

어댑터 보드에는 두 세트의 5V/GND 전원 포트가 있습니다:

  • 한 세트는 Type-C 케이블로 인출되어 5V 3A 전원 어댑터에 연결

  • 다른 한 세트는 ESP32-S3의 5V 핀에 전원을 공급하기 위해 인출(개발 보드는 더 이상 Type-C로 전원을 공급할 필요 없음)


3. 펌웨어 컴파일 및 플래싱 ​

3.1 ESP-IDF 버전(권장) ​

경고: 경로 요구 사항: ESP-IDF 컴파일은 중국어 경로를 지원하지 않습니다. 프로젝트가 위치한 경로가 완전히 영문인지 확인하세요(사용자 폴더, 상위 디렉터리 포함).

프로젝트 구조 ​

Plaintext
esp-idf/AmazingHand_Serial/
├── CMakeLists.txt              # 최상위 프로젝트 구성
├── sdkconfig.defaults          # 기본 Kconfig 구성
├── main/
│   ├── CMakeLists.txt
│   └── main.c                  # FreeRTOS 이중 태스크 + 초기화(글루 레이어)
└── components/
    ├── hand_servo/             # 서보 구동(LEDC PWM + 캘리브레이션 데이터)
    ├── hand_gestures/          # 제스처 파라미터 매크로 + 제스처 함수 + 좌우손 제어
    └── hand_protocol/          # 시리얼 프레임 파싱 + 명령 분배

빌드 환경 ​

  • ESP-IDF v6.0.1

  • 대상 칩: ESP32-S3

  • idf.py 환경 변수 설정 완료

컴파일 및 플래싱 ​

Bash
cd esp-idf/AmazingHand_Serial

# 1. 대상 칩 설정 (최초 또는 칩 교체 시)
idf.py set-target esp32s3

# 2. 컴파일
idf.py build

# 3. 플래시 (Windows: COM 포트 사용, 예: COM3)
idf.py -p COM3 flash

# 4. 시리얼 모니터 (선택 사항, 보드레이트 115200)
idf.py -p COM3 monitor

components/ 또는 main/ 아래의 소스를 수정한 후에는 idf.py build && idf.py -p COM3 flash를 다시 실행하면 됩니다.

3.3 캘리브레이션(선택 사항, 최초 사용 시 권장) ​

서보 중심 위치와 펄스 폭은 실제 기구에 맞게 캘리브레이션해야 합니다. 두 가지 방법이 있습니다:

  • ESP-IDF 버전: components/hand_servo/hand_servo.c의 middle_pos[8](40번째 줄)와 min_pw/mid_pw/max_pw[8](45-47번째 줄)를 편집

캘리브레이션 후 다시 컴파일 및 플래싱해야 합니다.


4. 시리얼 통신 프로토콜 ​

4.1 물리 계층 ​

파라미터값
인터페이스USB Serial (UART0)
보드레이트115200
데이터 비트8
패리티 비트없음 (None)
정지 비트1
흐름 제어없음

4.2 프레임 형식 ​

호스트 → ESP32(명령 프레임) ​

Plaintext
┌────────┬────────┬──────────┬────────────────┬──────────┐
│  0xAA  │ CMD_ID │ DATA_LEN │ DATA[0 .. N-1] │ CHECKSUM │
│ 1 Byte │ 1 Byte │  1 Byte  │    N Bytes     │  1 Byte  │
└────────┴────────┴──────────┴────────────────┴──────────┘
 帧头      命令ID    数据长度      数据负载         校验和
  • 프레임 헤더: 고정 0xAA, 한 프레임의 시작을 식별

  • 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 → 호스트(응답 프레임) ​

Plaintext
┌────────┬────────┬────────┬──────────┐
│  0xBB  │ CMD_ID │ STATUS │ CHECKSUM │
│ 1 Byte │ 1 Byte │ 1 Byte │  1 Byte  │
└────────┴────────┴────────┴──────────┘
 帧头      命令ID    状态码    校验和
  • 프레임 헤더: 고정 0xBB

  • CMD_ID: 원래 명령 번호

  • STATUS: 상태 코드(아래 표 참조)

  • CHECKSUM: CMD_ID ^ STATUS

상태 코드 ​

STATUS의미설명
0x00OK명령이 수락되어 실행 시작
0x01유효하지 않은 명령CMD_ID가 명령 테이블에 없음
0x02파라미터 오류데이터 길이 또는 내용이 올바르지 않음
0x03바쁨제스처 실행 중, 새 명령을 일시적으로 받지 않음
0x10완료제스처 실행 완료

4.3 통신 타이밍 ​

Plaintext
主机                          ESP32
 │                              │
 │──── [AA 01 00 01] ────────→│  发送"石头"命令
 │                              │
 │←─── [BB 01 00 01] ─────────│  ACK: 命令已接受
 │                              │
 │                      (执行手势中)
 │                              │
 │←─── [BB 01 10 11] ─────────│  完成: 手势执行完毕
 │                              │
 │──── [AA 02 00 02] ────────→│  发送"剪刀"命令
 │                              │
 │←─── [BB 02 00 02] ─────────│  ACK
 │                              │

4.4 제스처 정지 & 프레임 타임아웃 ​

  • [AA FF 00 FF]를 전송하면 실행 중인 제스처를 언제든 중단할 수 있음

  • ESP32는 200ms 내에 한 프레임을 다 받지 못하면 자동으로 폐기(바이트 손실로 인한 영구적 동기 상실 방지)

  • 체크섬이 일치하지 않는 프레임은 조용히 폐기되며, 호스트 PC는 타임아웃 재전송을 구현해야 함

4.5 좌우손 모드 ​

기본은 오른손 모드입니다. [AA F1 01 02 F2]를 전송하면 왼손으로 전환, [AA F1 01 01 F1]을 전송하면 오른손으로 복귀합니다. 좌우손은 엄지의 운동 방향에 영향을 줍니다(바위/가위/엄지 척/OK/핀치 등 엄지가 포함된 제스처).


5. 명령 레퍼런스 ​

5.1 제스처 명령 (0x01-0x0A, 0x0C) ​

이 명령들은 데이터 페이로드가 필요 없으며 (DATA_LEN=0), ESP32는 수신 후 즉시 해당 제스처를 실행합니다.

명령HEX 프레임응답설명
바위AA 01 00 01BB 01 00 01 → BB 01 10 11모든 손가락 주먹
가위AA 02 00 02BB 02 00 02 → BB 02 10 12검지+중지 펼침
보AA 03 00 03BB 03 00 03 → BB 03 10 13모든 손가락 펼침
엄지 척AA 04 00 04BB 04 00 04 → BB 04 10 14엄지 세우기
도발1AA 05 00 05BB 05 00 05 → BB 05 10 15검지 흔들기(약 2.5s)
도발2AA 06 00 06BB 06 00 06 → BB 06 10 16약지 흔들기(약 2.5s)
펼치기AA 07 00 07BB 07 00 07 → BB 07 10 17모든 손가락 펼침
주먹AA 08 00 08BB 08 00 08 → BB 08 10 18모든 손가락 닫기
OKAA 09 00 09BB 09 00 09 → BB 09 10 19OK 제스처
핀치AA 0A 00 0ABB 0A 00 0A → BB 0A 10 1A핀치 제스처
가리키기AA 0C 00 0CBB 0C 00 0C → BB 0C 10 1C검지를 펼쳐 "가리키기" 동작

5.2 직접 구동 명령 (0xF0) ​

8채널 서보 각도를 직접 제어하며, 8바이트 데이터가 각각 서보 1-8에 대응하고 각 바이트의 값 범위는 0-180입니다.

예시: 모든 서보를 중립 위치(90°)로

Plaintext
发送: AA F0 08 5A 5A 5A 5A 5A 5A 5A 5A F8
       │  │  │  └── 8 个 0x5A (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°)

Plaintext
发送: AA F0 08 AA 0A 5A 5A 5A 5A 5A 5A 58
               └─170°  └─10°

5.3 좌우손 설정 (0xF1) ​

1바이트 데이터: 0x01 = 오른손, 0x02 = 왼손.

Plaintext
设右手: AA F1 01 01 F1
设左手: AA F1 01 02 F2

5.4 제어 명령 ​

명령HEX 프레임설명
NOPAA 00 00 00링크 테스트, 즉시 BB 00 00 00 반환
반복AA FE 00 FE마지막 제스처를 반복 실행
정지AA FF 00 FF현재 제스처를 즉시 종료

5.5 응답 빠른 조회 ​

유효하지 않은 명령을 수신했을 때(존재하지 않는 명령 0xFC를 예로):

Plaintext
发送: AA FC 00 FC
响应: BB FC 01 FD    (STATUS=0x01 无效命令)

체크섬 검증: FC ^ 00 = FC, 응답 FC ^ 01 = FD


6. 호스트 PC 사용 튜토리얼 ​

프로젝트 루트 디렉터리는 두 개의 호스트 PC 도구를 제공합니다:

도구파일유형용도
그래픽 인터페이스hand_gui.py / 패키지 exe시각화버튼 클릭으로 제스처, 슬라이더 직접 구동, 로그
명령줄 테스트serial_test.py명령 방식제스처/단일 서보/스윕 전송, 자동화 테스트

둘 다 pyserial에만 의존합니다. 설치: pip install -r requirements.txt

6.1 시각화 GUI(권장) ​

방식 A: 패키지된 exe 실행(고객용) ​

  1. AmazingHand控制台.exe를 받습니다(또는 압축 해제된 디렉터리)

  2. exe를 두 번 클릭하여 바로 실행, Python 설치 불필요

  3. 아래 단계에 따라 연결하고 사용합니다

방식 B: 소스에서 실행 ​

Bash
# 1. 의존성 설치
pip install -r requirements.txt

# 2. 실행
python hand_gui.py

GUI 사용 단계 ​

  1. 시리얼 포트 선택: 상단 드롭다운에서 ESP32에 해당하는 COM 포트를 선택(Windows 장치 관리자에서 확인)

  2. "연결" 클릭: 상태등이 녹색으로 변하고 로그 영역에 "연결됨"이 표시되며, 자동으로 NOP 링크 테스트를 전송

  3. 제스처 명령: 「바위」「가위」「보」「엄지 척」「OK」… 등의 버튼을 클릭하면 로봇 손이 해당 제스처를 실행

  4. 좌우손: 「오른손」/「왼손」을 체크하여 엄지 미러 방향 전환

  5. 서보 직접 구동: 슬라이더 8개를 드래그하여 개별 서보 각도를 실시간 제어(0-180°)

  6. 손가락 차동 제어(권장): 손가락마다 두 개의 진행 막대——굴곡/신전은 해당 손가락의 두 서보를 역방향 차동(굴곡 신전)으로 제어하고, 오른쪽/왼쪽은 동일 방향 흔들기를 제어합니다. 두 자유도는 독립적이며 동기 구동됩니다

  7. 반복 / 정지: 마지막 제스처 반복 / 현재 제스처 즉시 중단

  8. 통신 로그: 하단에 송수신 프레임과 응답 상태를 실시간 표시

손가락 차동 제어 설명 ​

각 손가락은 두 개의 서보가 차동 구동하며, 두 자유도는 직교합니다:

진행 막대역할기계적 효과
굴곡◀▶신전두 서보 역방향 회전(차동)손가락 굴곡 또는 신전
오른쪽◀▶왼쪽두 서보 동일 방향 회전손가락 좌우 흔들기
  • 굴곡/신전 슬라이더 범위 -70 ~ +70(0 = 중립, +70 = 완전 신전, -70 = 완전 굴곡)

  • 좌우 흔들기 슬라이더 범위 60 ~ 120(90 = 중립, 60 = 오른쪽으로, 120 = 왼쪽으로)

  • 서보 각도 = 흔들기 ± 굴곡, 두 서보를 동기 갱신하고 직접 구동 명령을 전송

예(검지 GPIO4/5): 굴곡 슬라이더를 +70으로 드래그, 흔들기를 90 유지 → 서보4=160°, 서보5=20°(완전 신전); 굴곡을 -70으로 드래그 → 서보4=20°, 서보5=160°(완전 굴곡).

6.2 명령 방식 테스트(serial_test.py) ​

명령줄 사용법 ​

Bash
# 도움말 보기
python serial_test.py

# 링크 테스트
python serial_test.py COM3 nop

# 제스처 전송
python serial_test.py COM3 rock        # 바위
python serial_test.py COM3 thumbs_up    # 엄지 척
python serial_test.py COM3 index        # 가리키기
python serial_test.py COM3 open         # 펼치기
python serial_test.py COM3 close        # 주먹

# 단일 서보 직접 구동
python serial_test.py COM3 servo 1 90   # 서보1 → 90°

# 모두 중앙으로 복귀
python serial_test.py COM3 mid

# 좌우 손 설정
python serial_test.py COM3 hand L       # 왼손
python serial_test.py COM3 hand R       # 오른손

# 스윕 / 자가 진단
python serial_test.py COM3 sweep 1      # 서보1 스윕
python serial_test.py COM3 test         # 모든 서보 순차 테스트

대화형 모드 ​

Bash
python serial_test.py COM3

REPL에 진입하여 축약 명령을 직접 입력합니다(예: servo 3 180, rock, mid, quit).

6.3 시리얼 도구 수동 테스트(선택 사항) ​

CoolTerm (macOS/Windows/Linux):

  1. CoolTerm을 열고, Options → 보드레이트 115200, 8N1 설정

  2. Connection → Send String → Hex 선택

  3. AA 01 00 01을 입력 → 전송 → 로봇 손이 "바위" 실행

  4. 응답 영역에 BB 01 00 01 ... BB 01 10 11이 표시되는지 확인

SerialTool (macOS):

Bash
brew install serialtool
echo -ne '\xAA\x01\x00\x01' > /dev/cu.usbserial-0001

6.4 Python 제어 스크립트(사용자 정의 개발) ​

Python
#!/usr/bin/env python3
"""灵巧手串口控制 - Python 上位机示例"""
import serial
import time

SERIAL_PORT = "/dev/cu.usbserial-0001"  # 실제 포트로 수정
BAUD_RATE   = 115200

# 명령 정의 (펌웨어 명령 세트와 일치)
CMD = {
    "nop":       0x00,
    "rock":      0x01,
    "scissors":  0x02,
    "paper":     0x03,
    "thumbs_up": 0x04,
    "taunt1":    0x05,
    "taunt2":    0x06,
    "open":      0x07,
    "close":     0x08,
    "ok":        0x09,
    "pinch":     0x0A,
    "index":     0x0C,
    "direct":    0xF0,
    "set_side":  0xF1,
    "repeat":    0xFE,
    "stop":      0xFF,
}

def calc_checksum(cmd_id, data=b""):
    """计算 XOR 校验和 (CMD ^ LEN ^ DATA[0..N])"""
    result = cmd_id ^ len(data)
    for b in data:
        result ^= b
    return result & 0xFF

def send_command(ser, cmd_id, data=b""):
    """发送命令帧,返回 (ack_status, completion_status)"""
    data_len = len(data)
    checksum = calc_checksum(cmd_id, data)
    frame = bytes([0xAA, cmd_id, data_len]) + data + bytes([checksum])
    ser.write(frame)
    print(f"发送: {frame.hex(' ').upper()}")

def read_response(ser, timeout=1.0):
    """读取一个响应帧 [0xBB CMD STATUS CKSUM]"""
    ser.timeout = timeout
    while True:
        b = ser.read(1)
        if not b:
            return None
        if b[0] == 0xBB:
            buf = ser.read(3)
            if len(buf) == 3:
                expected = buf[0] ^ buf[1]
                if expected == buf[2]:
                    return bytes([0xBB]) + buf
    return None

def set_side(ser, side):
    """设置左右手: side='R' 右手, side='L' 左手"""
    val = 0x01 if side.upper() == 'R' else 0x02
    send_command(ser, CMD["set_side"], bytes([val]))

def direct_drive(ser, angles):
    """直驱 8 路舵机: angles 为 8 个 0-180 的角度列表"""
    data = bytes([min(180, max(0, a)) for a in angles[:8]])
    send_command(ser, CMD["direct"], data)

# ===== 사용 예시 =====
if __name__ == "__main__":
    ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
    time.sleep(1)  # ESP32 리셋 완료 대기

# 1. 링크 테스트
    print("=== NOP 链路测试 ===")
    send_command(ser, CMD["nop"])

# 2. 가위바위보 게임
    print("\n=== 猜拳: 石头 → 剪刀 → 布 ===")
    for name in ["rock", "scissors", "paper"]:
        send_command(ser, CMD[name])
        time.sleep(0.5)

# 3. 좋아요 제스처
    print("\n=== 真棒 ===")
    send_command(ser, CMD["thumbs_up"])

# 4. 테스트 중지
    print("\n=== 停止测试 ===")
    send_command(ser, CMD["taunt1"])  # 검지 흔들기 시작
    time.sleep(0.3)
    send_command(ser, CMD["stop"])    # 즉시 정지

# 5. 직접 구동 모드: 모두 중앙으로 복귀
    print("\n=== 直驱: 归中 ===")
    direct_drive(ser, [90] * 8)

    ser.close()

7. 제스처 추적 ​

카메라로 손바닥을 실시간 인식하여 로봇 손의 손가락 굴곡/신전 및 좌우 흔들기를 구동합니다. 공식 AmazingHand의 손 추적 알고리즘 기반(MediaPipe 21개 키포인트 + 3D 월드 좌표 회전).

7.1 원리 ​

  • 카메라를 손바닥에 향함 → MediaPipe가 21개 손 키포인트 인식

  • 손의 로컬 좌표계를 구성하고 4개 손가락 끝의 3D 벡터를 계산

  • 손가락 끝 벡터 → 각 손가락의 (flex, base) 차동 파라미터 → 직접 구동 프로토콜을 재사용하여 서보로 전송

7.2 환경 요구 사항 ​

제스처 추적은 64비트 Python + mediapipe 0.10.14에 의존합니다(구버전 solutions API, 이것만이 3D 월드 좌표를 처리할 수 있음):

의존성버전
Python64비트 3.12
mediapipe0.10.14
numpy<2.0
scipy>=1.9
opencv-python>=4.10
Pillow>=10.0

주의: 현재 기본 환경은 32비트 Python이라 mediapipe를 설치할 수 없습니다. 64비트 Python 3.12를 별도로 설치해야 합니다(D 드라이브, 예: D:\Python312-64에 설치, 기존 32비트와 완전히 공존하며 충돌 없음).

7.3 원클릭 배포 ​

  1. 64비트 Python 3.12 설치(python.org에서 64비트 installer 다운로드, D:\Python312-64에 설치)

  2. 프로젝트 루트 디렉터리의 **setup_tracking.bat**을 두 번 클릭하여 실행

    • 64비트 Python 자동 검색

    • tracking_env 가상환경 생성

    • mediapipe 0.10.14 등 의존성 설치

    • 설치 검증

7.4 사용 단계 ​

  1. 추적 환경으로 GUI 시작:
Plaintext
tracking_env\Scripts\python hand_gui.py
  1. 시리얼 포트 연결(ESP32에 해당하는 COM 포트 선택)

  2. "제스처 추적" 패널에서 카메라 번호 선택(기본 0)

  3. "추적 시작" 클릭 → 카메라 화면이 패널에 표시됨

  4. 손바닥을 카메라에 향함:

    • 손가락 굴곡/신전 → 로봇 손의 해당 손가락이 굴곡/신전

    • 손바닥 좌우 회전 → 로봇 손 손가락이 좌우로 흔들림

  5. "추적 정지" 클릭하여 종료

손이 감지되지 않으면 패널에 "손이 감지되지 않음"이 표시되고, 감지되면 "손 감지됨: Right/Left"가 표시됩니다.

7.5 파라미터 캘리브레이션 ​

매핑 계수는 hand_tracking.py 하단(FLEX_SCALE / BASE_SCALE)에 있습니다:

Python
FLEX_SCALE = 80.0    # 손끝 z 성분 → 굽힘/폄 (flex)
BASE_SCALE = 30.0    # 손끝 x 성분 → 좌우 회전 (base)

굴곡/신전 폭이 부족하거나 방향이 반대이면 FLEX_SCALE을 조정하고; 좌우 흔들기 폭이 부족하거나 반대이면 BASE_SCALE을 조정합니다(부호로 방향 조정).


8. 제스처 파라미터 미세 조정 ​

8.1 파라미터 위치 ​

각 제스처의 각도 오프셋은 #define 매크로로 정의되며, 로직 코드를 수정할 필요 없이 값만 조정합니다.

  • ESP-IDF 버전: components/hand_gestures/hand_gestures.c 상단 "제스처 파라미터(사용자 조정 가능)" 영역

8.2 파라미터 의미 ​

C
// 예: 바위 제스처
#define ROCK_IDX_OFF1    70    // 검지 관절1 오프셋
#define ROCK_IDX_OFF2   -70    // 검지 관절2 오프셋
  • 양수 = 굴곡하여 쥠, 음수 = 펴서 염

  • 각 손가락 2개의 오프셋, middle_pos 기준(기본 90°)

  • 차동 구조: 두 서보 오프셋의 차이 = 신전/수축, 동일 방향 성분 = 좌우 편향

8.3 파라미터 조정 단계 ​

  1. 해당 제스처의 #define 매크로를 찾습니다

  2. 값을 수정합니다(증가 → 폭이 커짐; 감소 → 폭이 작아짐)

  3. 다시 컴파일 및 플래싱하고 호스트 PC로 효과를 테스트

  4. 동작이 자연스러울 때까지 반복적으로 미세 조정


9. 자주 묻는 질문 ​

Q1: 호스트 PC가 시리얼 포트에 연결되지 않음? ​

  1. ESP32가 Type-C로 컴퓨터에 연결되었는지 확인

  2. 장치 관리자의 COM 포트 번호가 GUI 선택과 일치하는지 확인

  3. 보드레이트 115200 확인

  4. 시리얼 포트를 점유하는 다른 소프트웨어 연결 해제

Q2: 명령을 보내도 반응이 없음? ​

  1. 먼저 AA 00 00 00(NOP)을 전송하면 BB 00 00 00을 수신해야 함

  2. 펌웨어가 플래싱되었고 대상 칩이 ESP32-S3인지 확인

  3. 배선 확인(GND 공통 접지 여부)

Q3: 제스처 동작 폭이 맞지 않거나 방향이 반대? ​

제스처 파라미터 미세 조정(7장 참조)으로 해당 매크로를 조정합니다.

Q4: 좌우손 모드가 어떤 제스처에 영향을 주나요? ​

바위/가위/엄지 척/OK/핀치 등 엄지가 포함된 제스처는 좌우손 전환 후 엄지 미러 방향이 바뀝니다.

Q5: 손가락이 걸려서 펴지지 않음? ​

모든 수축 계열 제스처는 실행 전에 자동으로 "먼저 손 전체를 펼친 후 오므림"하여 손가락이 이전 제스처에 막히는 것을 방지합니다. 그래도 걸리면 기계 조립을 점검하거나 수축 폭을 줄이세요.