================================================================
 PoseLab Core (adv) - Arduino IDE 빌드 안내
================================================================

갱신일  : 2026-08-31

대상 보드   : ESP32-S3-WROOM-1 N16R8 (16MB flash, 8MB OPI PSRAM)
USB-UART    : CH343P (CDC, 드라이버 불필요) - COM 포트로 잡힙니다
전송        : UART0 @ 2,000,000 baud, 50fps, 96바이트 AnalyzedFrame 패킷
              (기존 86바이트 + 온디바이스 추론 10바이트)

----------------------------------------------------------------
 1. 준비물
----------------------------------------------------------------
- Arduino IDE 2.x
- 보드 매니저: "esp32 by Espressif Systems" (arduino-esp32 core 3.3.11에서 확인)
    Tools > Board > Boards Manager 에서 "esp32" 검색 후 설치
- 라이브러리 (라이브러리 매니저에서 설치):
    * Adafruit NeoPixel        (v1.15.x)
    * ArduinoJson              (v7.x)     <- v6 아닌 v7 이어야 합니다
    * Chirale_TensorFLowLite   (v2.0.0)   <- 온디바이스 추론 (TFLite Micro)
    * NimBLE-Arduino           (v2.x)     <- v1 아닌 v2 여야 합니다. BLE 출력용

  TensorFlow 라이브러리 주의: 반드시 Chirale_TensorFLowLite 여야 합니다.
  예전 TensorFlowLite_ESP32 (tanakamasayuki, 2022) 는 arduino-esp32 core 3.x
  에서 컴파일되지 않습니다. 내장된 flatbuffers 가 const 멤버에 대입하는데,
  core 3.x 가 기본으로 쓰는 C++17 에서는 이것이 오류입니다.

----------------------------------------------------------------
 2. 스케치 열기
----------------------------------------------------------------
- PoseLabCore-adv/PoseLabCore-adv.ino 를 IDE 에서 엽니다.
- 소스는 src/ 아래 폴더 구조로 들어 있습니다 (board/ sense/ calib/ proto/
  tinyml/ model/ ...). IDE 탭에는 .ino 만 보이지만 src/ 아래 전체가 함께
  컴파일됩니다.
  (하위 파일을 수정하려면 왼쪽 탐색기에서 열면 됩니다.)

----------------------------------------------------------------
 3. Tools 메뉴 설정 (* 표시는 반드시 일치해야 함)
----------------------------------------------------------------
  Board                : ESP32S3 Dev Module
  Port                 : (보드가 잡힌 COM 포트)
  USB CDC On Boot      : Disabled          <- 중요. Enabled 면 데이터가 안 나옵니다
  CPU Frequency        : 240MHz (WiFi)
  Core Debug Level     : None
  Flash Mode           : QIO 80MHz
  Flash Size           : 16MB (128Mb)      <- 4MB 아닙니다
  PSRAM                : OPI PSRAM         <- Disabled 면 LED/PSRAM 인식 실패
  Partition Scheme     : Custom            <- * Custom 이어야 합니다 (스케치의 partitions.csv 적용)
  Upload Mode          : UART0 / Hardware CDC
  Upload Speed         : 921600
  USB Mode             : Hardware CDC and JTAG
  (나머지 항목은 기본값 그대로)

  참고: Partition Scheme 을 Custom 으로 해야 스케치 폴더의 partitions.csv 가
        적용됩니다. 이 펌웨어가 쓰는 파티션 두 개가 여기 들어 있습니다 —
        "fit"(교정값)과 "models"(업로드한 모델). Custom 이 아니면 스트리밍은
        되지만 교정값이 저장되지 않고 모델도 넣을 수 없습니다.

  참고: PSRAM 은 OPI 여야 합니다. 모델 업로드는 플래시에 쓰기 전에 PSRAM 에
        모아두므로, PSRAM 이 꺼져 있으면 전송이 실패합니다.

----------------------------------------------------------------
 4. 업로드 및 확인
----------------------------------------------------------------
- 업로드 후 Serial Monitor 를 baud 2000000 으로 엽니다.
- 부팅 배너 예시:
    ==== PoseLab Core ====
    Chip       : ESP32-S3 ... Flash 16MB, PSRAM 8189KB   <- PSRAM 인식됨
    [model] SPIFFS 0/1920401 B used, model none          <- 모델 파티션 마운트
    [tinyml] using embedded model (28060 B)
    [tinyml] selftest 5/5                                <- 추론 검증 통과
    [tinyml] invoke 0.337 ms avg over 200 runs
    FIT calib loaded: USER params                        <- 교정값 저장됨
    PUMP- ENTER ...                                      <- 스트리밍 시작
- 부팅 시 WS2812C LED 가 무지개 시퀀스 후 앰버로 유지되면 정상입니다.

  셀프테스트는 PC 에서 미리 계산한 기준 벡터를 모델에 넣어보고 몇 개가
  일치했는지 출력합니다. 5/5 면 추론이 정상입니다. 내장 fallback 모델에
  대해서만 돌고, 업로드한 모델은 비교할 기준 벡터가 없어 건너뜁니다.

----------------------------------------------------------------
 5. 온디바이스 추론
----------------------------------------------------------------
- 96바이트 프레임마다 디바이스가 자체 판단한 결과가 tail 직전 10바이트에
  실립니다. app/model id 와 상위 3개 라벨·신뢰도입니다.
- 라벨은 문자열이 아니라 인덱스로 전달됩니다. 라벨 이름은 모델 파일 안에
  있어 호스트가 조회하면 되고, 같은 문자열을 초당 50번 다시 보내는 것은
  정적 정보를 반복 전송하는 것일 뿐입니다.
- 펌웨어에는 fallback 용 내장 모델이 들어 있습니다. 직접 만든 모델을 넣으려면
  브라우저(MLP 랩 페이지)에서 학습하고 변환한 뒤 같은 페이지에서 디바이스로
  전송하면 됩니다. 변환은 Colab 노트북에서 이루어지며, 랩 페이지에 안내
  링크가 있습니다.
- 새로 올린 모델은 재부팅 후 적용됩니다 — 인터프리터가 부팅 시 한 번
  만들어지기 때문입니다.

----------------------------------------------------------------
 6. 참고
----------------------------------------------------------------
- PlatformIO 로 빌드하려면 PoseLabCore-pio 패키지를 쓰면 됩니다
  (진입점은 src/main.cpp). 두 패키지는 하나의 소스에서 생성되며, src/ include
  접두와 .ino / .cpp 차이뿐입니다. 동작은 동일합니다.
- timer_50fps.cpp 에는 버전 분기가 있어 arduino-esp32 core 2.x 와 3.x 양쪽에서
  빌드됩니다.
- 문의: support@poselab.app
