BLE RSSI 기반 PHY 자동 전환

BLEIoTEmbedded

BLE 5.0은 여러 PHY를 지원한다. 1M PHY는 처리량이 높고, Coded PHY S8은 도달 거리가 길다. 신호 강도에 따라 자동 전환하면 가까울 때는 빠르게, 멀어지면 연결을 유지할 수 있다.

PHY 비교

PHY데이터 레이트도달 거리 (상대)용도
1M1 Mbps1x기본. 처리량 우선
2M2 Mbps0.8x고속 전송. 범위 짧음
Coded S2500 kbps2x중거리
Coded S8125 kbps4x장거리. 처리량 낮음

이 프로젝트에서는 1M과 Coded S8 두 가지만 사용한다.

구현

1초마다 RSSI를 측정하고, 임계값에 따라 PHY를 전환한다.

static void phy_adapt_ev_cb(struct ble_npl_event* ev) {
  uint16_t conn = GetBleConnHandle();
  if (conn == BLE_HS_CONN_HANDLE_NONE) return;

  int8_t rssi;
  if (ble_gap_conn_rssi(conn, &rssi) == 0) {
    if (rssi <= -75) {
      ble_gap_set_prefered_le_phy(conn, BLE_GAP_LE_PHY_CODED_MASK,
                                  BLE_GAP_LE_PHY_CODED_MASK,
                                  BLE_GAP_LE_PHY_CODED_S8);
    } else if (rssi >= -65) {
      ble_gap_set_prefered_le_phy(conn, BLE_GAP_LE_PHY_1M_MASK,
                                  BLE_GAP_LE_PHY_1M_MASK, 0);
    }
  }
  ble_npl_callout_reset(&s_phy_callout, ble_npl_time_ms_to_ticks32(1000));
}

히스테리시스

-75dBm 이하에서 Coded PHY로 전환하고, -65dBm 이상에서 1M PHY로 복귀한다. 10dB 간격을 두어 경계에서 PHY가 반복 전환(flapping)되는 현상을 방지한다.

RSSI: ─────────────────────────────────────────
         Coded S8      |  유지 구간  |   1M PHY
                     -75           -65

-75 ~ -65 사이에서는 현재 PHY를 유지한다.

NimBLE Callout

ble_npl_callout은 NimBLE의 이벤트 큐에 콜백을 등록하는 메커니즘이다.

void BleComsInitPhyAdapt(void) {
  ble_npl_callout_init(&s_phy_callout, nimble_port_get_dflt_eventq(),
                       phy_adapt_ev_cb, NULL);
}

별도 FreeRTOS 태스크를 만들지 않고 NimBLE 호스트 태스크의 이벤트 루프에서 실행된다. BLE API 호출이 동일 컨텍스트에서 이루어지므로 race condition이 없다.

장단점

장점:

  • 별도 태스크/스택 메모리 불필요 (callout 사용)
  • 로봇이 벽면을 따라 이동할 때 거리 변화에 자동 대응
  • PHY 전환은 BLE 스택이 처리하므로 앱 레벨에서 재연결 불필요

단점:

  • Coded PHY를 지원하지 않는 모바일 기기가 있다. iOS 14+, Android 8+에서 지원하지만, 실제 하드웨어 지원 여부는 기기마다 다르다
  • PHY 전환 요청은 negotiation이다. 상대방이 거부할 수 있다. 이 경우 콜백에서 에러가 발생하지만, 현재 구현에서는 별도 처리하지 않는다
  • RSSI 1회 측정값에 의존한다. 순간 노이즈에 반응할 수 있다

대안 검토

고정 PHY 사용:

  • 가장 단순한 방식. 1M PHY로 고정하면 구현이 불필요하다
  • 문제: 이 프로젝트의 디바이스는 천장에 설치된다. 모바일과의 거리가 가변적이고, 벽/가구 등 장애물이 많아 RSSI 변동 폭이 크다
  • Coded PHY 고정도 가능하지만, 가까운 거리에서 불필요하게 낮은 처리량(125kbps)을 사용하게 된다

RSSI 이동 평균:

  • N개 샘플의 이동 평균을 사용하면 순간 노이즈에 덜 민감해진다
  • 구현 복잡도가 올라가고, 실제 운용에서 히스테리시스만으로 충분한 안정성을 확보했기 때문에 채택하지 않았다
  • 급격한 거리 변화(로봇 이동)에 대한 반응이 느려지는 단점도 있다

2M PHY 추가:

  • 근거리에서 2M PHY를 사용하면 처리량이 2배로 올라간다
  • 이 프로젝트에서 BLE로 전송하는 데이터는 10Hz 상태 notification(약 43바이트)과 이벤트 로그(14바이트)뿐이다. 1M PHY로 충분하므로 추가하지 않았다

연결 끊김 후 Coded PHY로 재시도:

  • PHY 전환이 아니라, 연결 실패 시 Coded PHY advertising으로 재시도하는 방식
  • 이 방식은 연결이 끊어진 후에만 동작하므로, 연결 유지가 목적인 현재 구현과 병용할 수 있다. 아직 구현하지 않았다