# UartClient Read AllState

**What you’ll do**
- 좌/우 모터에 대해 AllState 요청(**보조 명령**)을 보내고, `poll()`로 응답을 받아 출력합니다.

**Prerequisites**
- {doc}`UartClient Read Speed </page/SDK/tutorials/uart_client_read_speed>`

**Next**
- {doc}`UartClient Teleop and Speed </page/SDK/tutorials/uart_client_teleop_and_speed>`
- {doc}`UART Protocol Reference </page/Protocol/uart_protocol>`

---

이 튜토리얼은 `UartClient Read Speed`에서 다룬 포트 open/flush, 루프 뼈대를 재사용합니다.
여기서는 AllState 요청(**보조 명령**) 처리만 정리합니다.

---

## 1. 목표

- 좌/우 모터에 대해 AllState 요청(**보조 명령**) 전송
- `poll()`로 `AllState`를 받아 출력

---

## 2. 단계별 구현 가이드

### 단계 1) 포트 open/flush (이미 설명한 부분)

`UartClient Read Speed`와 동일합니다. 핵심 API만 재사용합니다.

```cpp
KMC_HARDWARE::UartClient client;
client.open(port, 115200);
client.flushInput();
```

### 단계 2) 두 모터 연속 요청

```cpp
client.requestAllState(0); // Left
client.requestAllState(1); // Right
```

### 단계 3) 수신 루프에서 AllState 출력

```cpp
const auto deadline =
    std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
bool printed = false;
while (std::chrono::steady_clock::now() < deadline) {
  auto msg = client.poll(20);
  if (!msg) continue;
  if (auto* st = std::get_if<KMC_HARDWARE::AllState>(&*msg)) {
    std::printf(
        "AllState: id=%u pos=%.2f deg rpm=%.1f current=%.2f A temp=%.1f C "
        "err=0x%08X\n",
        st->id,
        st->position_deg,
        st->speed_rpm,
        st->current_A,
        st->temperature_C,
        st->error_code);
    printed = true;
  }
}
```

```{admonition} 참고
:class: note

`AllState.error_code`의 비트 정의는 {doc}`UART Protocol Reference </page/Protocol/uart_protocol>`의 AllState 섹션을 기준으로 해석합니다.
```

---

## 3. Result

아래 코드는 SDK 리포지토리의 `examples/UartClient_Advanced/read_allstate.cpp`와 동일한 내용입니다.

```cpp
#include "KMC_uart_client.hpp"

#include <chrono>
#include <cstdio>
#include <string>
#include <thread>
#include <variant>

int main(int argc, char **argv) {
  const std::string port = (argc > 1) ? argv[1] : "/dev/ttyKMC";

  KMC_HARDWARE::UartClient client;
  if (!client.open(port, 115200)) {
    std::fprintf(stderr, "Failed to open port: %s\n", port.c_str());
    return 1;
  }
  client.flushInput();

  while (true) {
    client.requestAllState(0); // Left
    client.requestAllState(1); // Right

    const auto deadline =
        std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
    bool printed = false;
    while (std::chrono::steady_clock::now() < deadline) {
      auto msg = client.poll(20);
      if (!msg) {
        continue;
      }
      if (auto* st = std::get_if<KMC_HARDWARE::AllState>(&*msg)) {
        std::printf(
            "AllState: id=%u pos=%.2f deg rpm=%.1f current=%.2f A temp=%.1f C "
            "err=0x%08X\n",
            st->id,
            st->position_deg,
            st->speed_rpm,
            st->current_A,
            st->temperature_C,
            st->error_code);
        printed = true;
      }
    }
    if (!printed) {
      std::printf("AllState: (no response)\n");
    }
  }

  return 0;
}
```
