콘텐츠로 이동

GPIO 도구

연결된 보드, Uno Q 브리지, 시리얼 전송 계층, 하드웨어 컨텍스트 파일을 통한 GPIO 쓰기/읽기.

GPIO 도구를 사용하면 에이전트가 일반 함수 호출만으로 연결된 보드의 핀을 구동하고 상태를 감지할 수 있습니다. 두 가지 핵심 도구인 **gpio_write**와 **gpio_read**는 지원되는 모든 연결 보드(Raspberry Pi Pico, Arduino Uno, ESP32, STM32 Nucleo)에서 동일하게 동작합니다. 이 보드들은 모두 동일한 Revka 시리얼 JSON 프로토콜을 사용하기 때문입니다. 이 페이지에서는 두 도구, 이를 운반하는 시리얼 전송 계층, 핀 정보를 탐색하는 hardware_capabilities 도구, TCP 소켓을 통해 동작하는 Arduino Uno Q 브리지 변형, 그리고 에이전트에게 특정 보드 정보를 알려주는 하드웨어 컨텍스트 파일을 다룹니다.

LED를 켜거나 끄고, 버튼 상태를 읽거나, 보드가 노출하는 핀을 확인하고 싶다면 이 페이지를 참고하세요. Revka가 USB로 연결된 것이 아니라 Raspberry Pi에서 직접 실행 중이라면 네이티브 gpio_rpi_* 도구를 사용하세요 — Raspberry Pi (셀프 호스팅)을 참고하세요. 보드 연결 및 펌웨어 플래싱에 대해서는 하드웨어 퀵스타트펌웨어 플래싱을 참고하세요.

gpio_write는 등록된 장치의 GPIO 핀을 HIGH 또는 LOW로 설정합니다. 에이전트가 함수로 호출하며, 일반적으로 자연어(“25번 핀 켜줘”)로 트리거합니다.

파라미터타입필수 여부설명
pininteger필수GPIO 핀 번호
valueinteger필수1 = HIGH(켜짐), 0 = LOW(꺼짐)
devicestring선택장치 별칭(예: pico0, arduino0). GPIO 가능 장치가 하나만 등록된 경우 자동 선택됩니다. 여러 보드가 연결된 경우 필수입니다.

에이전트 호출 예시:

User: Turn on pin 25
Agent: gpio_write(pin=25, value=1)
# With more than one board connected:
Agent: gpio_write(device="pico0", pin=25, value=1)

내부적으로 도구는 장치 전송 계층을 통해 개행 구분 JSON 한 줄을 전송하고 응답 한 줄을 수신합니다:

// Host → Device
{"cmd":"gpio_write","params":{"pin":25,"value":1}}
// Device → Host
{"ok":true,"data":{"pin":25,"value":1,"state":"HIGH"}}

성공 시 도구는 GPIO 25 set HIGH on pico0와 같은 메시지를 반환합니다. 0 또는 1 이외의 값은 I/O 발생 전에 거부되며, pin이나 value가 누락되면 파라미터 오류를 반환합니다.

gpio_read는 핀의 현재 HIGH/LOW 상태를 읽습니다. gpio_write와 동일한 전송 계층과 자동 선택 규칙을 사용합니다.

파라미터타입필수 여부설명
pininteger필수읽을 GPIO 핀 번호
devicestring선택장치 별칭. GPIO 장치가 하나만 등록된 경우 자동 선택됩니다.
Agent: gpio_read(pin=25)
# or, with multiple boards:
Agent: gpio_read(device="pico0", pin=25)

와이어 교환:

// Host → Device
{"cmd":"gpio_read","params":{"pin":25}}
// Device → Host
{"ok":true,"data":{"pin":25,"value":1,"state":"HIGH"}}

도구 출력에는 숫자 값과 텍스트 상태가 모두 포함됩니다. 예를 들면:

GPIO 25 is HIGH (1) on pico0

gpio_writegpio_read는 매우 다른 전송 계층에서도 동일한 도구 이름을 사용합니다. Revka는 보드가 등록된 방식에 따라 적절한 구현체를 자동으로 선택하므로, 에이전트가 직접 선택할 필요가 없습니다.

설정도구전송 방식
USB로 연결된 Pico / Arduino / ESP32 / Nucleogpio_write, gpio_read시리얼 JSON 프로토콜 (이 페이지)
Raspberry Pi에서 Revka 네이티브 실행gpio_rpi_write, gpio_rpi_read, gpio_rpi_blinkrppal을 통한 직접 /dev/gpiomem 접근 — Raspberry Pi (셀프 호스팅) 참고
transport = "bridge" 설정의 Arduino Uno Qgpio_write, gpio_read127.0.0.1:9999의 브리지 TCP 소켓 (아래 참고)
Total Phase Aardvark 어댑터gpio_aardvarkUSB를 통한 8핀 비트마스크 — Aardvark I2C/SPI/GPIO 및 데이터시트 참고

모든 연결 보드는 시리얼 전송 계층을 통해 GPIO에 접근하며, 이 계층은 시리얼 포트를 통해 Revka 시리얼 JSON 프로토콜을 전달합니다. 보드 항목에 transport = "serial"을 설정하면 암묵적으로 구성됩니다.

[peripherals]
enabled = true
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
필드타입기본값설명
pathstring시리얼 포트 경로(예: /dev/ttyACM0, /dev/cu.usbmodem101)
baudinteger115200시리얼 보드레이트

두 가지 동작 방식을 알아두세요:

  • 지연 열기. 포트는 데몬 시작 시가 아니라 첫 번째 명령 시점에 열립니다. 부팅 시 보드가 연결되어 있지 않아도 데몬은 정상적으로 시작되며, 보드를 연결하면 첫 번째 gpio_write 호출 시 연결이 열립니다.
  • 펌웨어 핑 핸드셰이크. 첫 연결 시 전송 계층은 ping을 전송하고 300 ms 이내에 Revka 펌웨어 응답을 기대합니다. Revka 펌웨어로 응답하지 않는 보드는 GPIO 장치로 처리되지 않습니다.

와이어 계약은 이 페이지 전체에서 사용되는 개행 구분 ZcCommand / ZcResponse 쌍입니다: 각 요청에 대한 호스트 명령(cmd + params)과 장치 응답(ok + data, ok가 false일 때는 추가로 error). 펌웨어와 호스트 모두 이 형식에 동의해야 하므로, Pico, Arduino, ESP32, Nucleo 모두 동일하게 구현합니다.

사용 가능한 핀 탐색 (hardware_capabilities)

섹션 제목: “사용 가능한 핀 탐색 (hardware_capabilities)”

핀에 쓰기 전에, 에이전트는 각 시리얼 보드가 노출하는 핀과 온보드 LED를 구동하는 핀을 쿼리할 수 있습니다. hardware_capabilities 도구는 펌웨어의 capabilities 명령을 쿼리하고 결과를 반환합니다.

파라미터타입필수 여부설명
boardstring선택단일 보드 이름으로 필터링합니다. 생략하면 구성된 모든 시리얼 보드를 쿼리합니다.
Agent: hardware_capabilities()
Output: arduino0: gpio [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], led_pin 13

이 도구는 hardware 피처가 빌드되고 시리얼 보드가 구성된 경우에만 등록됩니다. 펌웨어는 시리얼 JSON 핸들러에 capabilities 명령을 구현해야 하며, Revka Arduino 펌웨어는 gpio_readgpio_write와 함께 이를 활성화합니다. 필터와 일치하는 보드가 없으면 도구는 기능이 지원되지 않음을 보고합니다.

Arduino Uno Q는 동반 MCU가 있는 Linux 보드입니다. 시리얼 포트 대신 GPIO는 TCP 포트 9999에서 수신 대기하며 MCU의 핀을 Linux 쪽에 노출하는 소형 브리지 앱(Python + MCU 소켓 서버)을 통해 전달됩니다. transport = "bridge"로 보드를 구성하면 Revka가 표준 gpio_read / gpio_write 도구를 소켓 기반 구현체로 투명하게 교체합니다. 에이전트는 동일한 도구 이름을 사용합니다.

[[peripherals.boards]]
board = "arduino-uno-q"
transport = "bridge"

도구 호출 방식은 시리얼 방식과 동일합니다:

User: Turn on pin 13 on the Arduino
Agent: gpio_write(pin=13, value=1)

내부적으로 브리지 도구는 127.0.0.1:9999에 TCP 연결을 열고 공백 구분, 개행 종료 한 줄을 전송합니다. 쓰기의 경우 gpio_write 13 1\n, 읽기의 경우 gpio_read 13\n 형식이며, 이후 응답을 읽습니다.

타임아웃
연결5초
응답3초

GPIO 도구는 원시 핀 번호로 동작하지만, 에이전트는 각 핀이 보드에서 어떤 역할을 하는지 알 때 더 잘 추론할 수 있습니다. Revka는 부팅 시 ~/.revka/hardware/에서 마크다운을 로드하여 LLM 시스템 프롬프트에 주입하므로, 코드를 수정하지 않고도 에이전트에게 하드웨어에 대해 가르칠 수 있습니다. 세 가지 유형의 파일이 지원됩니다:

경로용도
~/.revka/hardware/HARDWARE.md모든 장치에 공유되는 전역 하드웨어 메모
~/.revka/hardware/devices/<alias>.md세션 별칭을 이름으로 하는 장치별 프로필(예: pico0.md)
~/.revka/hardware/skills/*.md파일명 알파벳 순으로 로드되는 하드웨어 스킬
  1. 전역 메모 작성. 보드에 무관한 규칙과 핀 관례를 기록합니다.

    Terminal window
    cat > ~/.revka/hardware/HARDWARE.md << 'EOF'
    # Hardware Notes
    - Pin 25 is the onboard LED on Pico
    - Use device_exec for blink loops
    EOF
  2. 장치 프로필 추가. 파일 이름을 장치 별칭으로 지정하면 해당 보드가 존재할 때만 로드됩니다.

    Terminal window
    mkdir -p ~/.revka/hardware/devices
    cat > ~/.revka/hardware/devices/pico0.md << 'EOF'
    # pico0 — Raspberry Pi Pico
    Port: /dev/cu.usbmodem1101
    Use pin 25 for the onboard LED.
    EOF
  3. 데몬을 재시작하여 부팅 서브시스템이 디렉터리를 다시 읽고 새 컨텍스트를 주입하도록 합니다.

로딩 방식:

  • 파일은 일반 마크다운입니다. 스키마나 프론트매터가 필요하지 않습니다.
  • 시스템 프롬프트에 주입할 때 섹션은 이중 개행으로 연결됩니다. 파일이 없으면 조용히 건너뛰고, 빈 파일은 무시됩니다.
  • 장치 프로필은 세션에 실제로 등록된 별칭에 대해서만 로드됩니다.