USB를 사용한 하드웨어와 안드로이드 기기의 접속
  • 2012-03-06
  • 편집부

USB 인터페이스를 통해 안드로이드 기반 제어 기능을 구현할 수 있다. 안드로이드 호스트 API 사용과 함께 적절한 하드웨어를 조달하고 관련 펌웨어를 개발한다면, 안드로이드 운영체제와 여러 다양한 특징에 대한 지식이 많지 않아도 상상력이 넘치는 애플리케이션을 만들 수 있다.

 
                                                  
  글 |   *마누엘 디 세르보(Manuel Di Cerbo) /  Nexus-Computing
          **데이브 린네스(Dave Riness) / FTDI Chip        

최근의 상황은 모바일/휴대용 시스템과 자동화 또는 기계식 시스템의 인터페이스 시장에 거대한 잠재력이 존재함을 시사하고 있다. 구글(Google)이 2011년 봄에 발표한 Android Open Accessory(안드로이드 오픈 액세서리) 프레임워크는 스마트폰과 태블릿 컴퓨터에 외장 하드웨어를 제어할 수 있는 기능을 부여하는 안드로이드 운영체제 기반 기기를 위한 가능성을 열어준다. 이 오픈 액세서리 프레임워크는 주방 가전 기기, 개별 중장비 등 다양한 장치와 연결되면서 이미 널리 채택된 사용자들에게 익숙한 운영체제를 이용하는 휴대형 기기에 기업, 소비자 및 산업 환경에서 자동화 공정을 개시할 수 있는 수단을 제공한다.
현재 유선을 통해 마이크로컨트롤러와 모바일 기기의 종단간(end-to-end) 통신을 실현하는 가장 인기 있는 방법 중 하나는 USB 인터페이스를 이용하는 것이다. 이 방법은 (특히 소비 가전 및 컴퓨팅 분야에서) 폭넓은 인기로 인해 엔지니어들 사이에서 선호되고 있다. 이 글은 안드로이드 기반 태블릿PC와 USB 컨트롤러를 포함하는 마이크로컨트롤러 사이에서 이 같은 통신을 지원하는 매우 기초적인 솔루션에 대해 설명한다.
USB 호스트의 핵심적인 기능 중 하나는 비교적 대용량의 데이터 전송을 지원하고 매우 기능이 풍부한 통신 프로토콜을 제공함과 동시에, USB 기기(즉, 슬레이브)에 전력을 공급하는 기능이다. 그러나 엔지니어들은 기기 쪽 프로토콜의 복잡성으로 인해 몇 가지 단점을 극복해야 한다.
자신이 직접 제작한 펌웨어를 구현하고자 하는 엔지니어가 극복해야 하는 가장 큰 문제점은 서로 다른 반도체 제조업체들이 판매하는 마이크로컨트롤러의 API(애플리케이션 프로그래밍 인터페이스)가 약간씩 차이가 있다는 점이다. 이 문제를 극복하기 위해 사용할 수 있는 방법은 기본적으로 두 가지다.

1. 첫째는 기기 쪽에서 일종의 ‘하드웨어-스테이트-머신’ 기능을 제공하는 마이크로컨트롤러를 사용하는 방법이다. 그러나 이 방법을 사용하려면 많은 엔지니어링 리소스가 요구되는 경향이 있다.
2. USB-시리얼 컨버터를 사용하면 애플리케이션에 추상화 층을 더 추가함으로써 소프트웨어 구현의 복잡성을 USB 호스트 쪽과 USB 기기 쪽에서 모두 줄일 수 있다. 이 방법은 특히 과거에 안드로이드 운영체제나 안드로이드 USB API를 다뤄 본 경험이 거의 없거나 전혀 없는 엔지니어들이 이용하기가 쉽다.

이 글에서는 USB-to-serial converter를 사용한 두 번째 방식의 예를 살펴본다. 예제에 언급된 코드는 FTDI Vinculum-Ⅱ(VNC2) USB 호스트 컨트롤러 IC와 함께 사용하도록 개발됐지만, 다른 컨트롤러와 함께 동작하도록 활용할 수도 있다.



안드로이드를 통한 제어
안드로이드는 개발자들이 자신의 애플리케이션을 구현하는 데 사용할 수 있는 일련의 광범위한 API는 물론, USB를 통해 통신할 수 있는 기능도 제공한다. 그러나 현재 풀 사이즈 USB 호스트 인터페이스 커넥터를 제공하는 안드로이드 태블릿은 극소수에 불과하다. 이 같은 제약으로 인해, 구글은 USB 기기 포트를 통해 외부 USB 호스트와 통신하는 안드로이드용 API를 개발했다. 이를 안드로이드 오픈 액세서리 개발 키트(ADK)라고 한다. 이 API는 이제 안드로이드(버전 2.3.4 이상)를 구동하는 일부 기기와 통신할 수 있는 방법을 제공하지만, 디자이너들이 유념해야 할 몇 가지 중대한 결점이 여전히 존재한다.

1. 외장 액세서리는 자체 전원을 사용해야 하며, 안드로이드 하드웨어의 USB 호스트 역할을 해야 한다. 예를 들면, 안드로이드 오픈 액세서리 프레임워크의 잠재적인 용도 중 하나는 안드로이드 기반 휴대 기기와 운동 기구의 상호작용을 통해 사용자가 심장박동, 칼로리 소비량 등에 대한 데이터를 휴대 기기에 전송하여 이전 방문 시에 얻어진 통계와 비교해 분석할 수 있도록 하는 것인데, 휴대 기기가 런닝 머신 같은 기계에 전원을 공급하는 것은 당연히 불가능하다. 반면에, (PC가 예를 들면 마우스 같은 주변기기와 연결되었던) 과거의 애플리케이션 시나리오에서는 호스트가 전원도 제공했다.
2. 현재 호스트의 역할을 할 수 있는 기기는 많지 않다. 특히, 대부분의 스마트폰 모델에는 여전히 USB 호스트 연결 기능이 없다. 앞으로는 더 많은 스마트폰이 (새로 출시된 삼성 갤럭시 넥서스처럼) USB OTG를 이용할 것이므로 안드로이드를 기반으로 가정에서 사용되는 다양한 소비가전 제품을 유선으로 제어하는 경우가 급증할 것이다. 예를 들면, 스마트폰을 사용하여 게임 콘솔이나 백색 가전 제품과 상호 통신하는 일이 많아질 것이다.

애플리케이션 예제
안드로이드 오픈 액세서리 프레임워크를 통해 휴대용 기기가 흔히 수행하게 될 것이 거의 확실한 작업 중 하나는 다양한 형태의 전기 모터 제어 작업이다. 이렇게 되면 방향 및 속도 같은 요소를 편리한 방법으로 관리할 수 있게 될 것이다. 이런 원리는 태블릿 컴퓨터를 사용하여 장난감 레이싱카를 조종하는 안드로이드의 기능적인 능력을 보여주는, 간단하면서도 재미있는 예제를 통해 좀 더 자세히 설명할 수 있다.
안드로이드 기반 제어 시스템을 만드는 데 필요한 구성요소는 다음과 같다(그림 1에 관련 배선도가 나와 있다).
각각의 경우에 장난감 레이싱카 예제를 위해 사용된 구체적인 품목에 대한 상세정보가 제시돼 있다(그림 2는 이를 더 자세히 보여주고 있다).

1. 원격 제어 기능을 제공하는 애플리케이션을 포함한 안드로이드 태블릿(이는 모터, 펌프 등과 같은 다른 모든 하드웨어 구성요소를 제어하는 데도 똑같이 적용할 수 있다). 이 예에서는 (안드로이드 3.2를 탑재한) Acer A500 안드로이드 태블릿을 이용한다.
2. USB 케이블을 통해 태블릿에 연결되고 USB 기기의 역할을 하는 마이크로컨트롤러. 펌웨어를 단순화하기 위해, USB-to-serial driver가 기기 쪽에서 사용된다. 이 예에는 FTDI Vinco 개발 보드가 사용됐다. 이 보드에는 듀얼 채널 USB 호스트/기기 컨트롤러 기능이 있다.
3. GPIO, PWM, I2C 또는 SPI 인터페이스에 의해 제어되는 맞춤 하드웨어 구성요소. 이 예에서 이 구성요소는 제어 기능이 GPIO 인터페이스를 통해 수행되는 원격 리모컨이다.

코드 작성
장난감 자동차를 제어하는 유저 인터페이스(UI)는 꽤 간단한 편이다. 태블릿의 터치스크린에 버튼 2개가 표시된다. 하나는 자동차 전진에 사용되고 나머지 하나는 후진에 사용된다. 자동차를 좌우로 조종하려면 태블릿을 좌우로 돌리면 된다. 무선 조종 신호는 바이트 단위의 직렬 전송으로 나눌 수 있다. 예를 들면, 오른쪽으로 조종하는 데는 바이트 값 “0x01”이 사용되고 전진에는 “0x08”이 사용된다. 두 값을 합한 “0x09”는 차가 전진하면서 오른쪽으로 회전하는 결과로 나타난다.
이 애플리케이션을 위한 특정 안드로이드 커널 모듈을 컴파일하거나 제조업체의 기본 권한을 우회하기 위해 액세스 루트가 태블릿을 통과하도록 할 필요는 없다. 대신, 안드로이드 애플리케이션[http://www.nexus-computing.ch/files/Racer.apk]을 설치한 다음, USB 인터페이스를 통해 Vinco 보드를 꽂아 넣기만 하면 된다. 안드로이드 태블릿과 Vinculum Ⅱ 사이의 연결은 최근에 출시된 안드로이드 USB 호스트 API로 유지된다. Java 소프트웨어는 안드로이드 상에서 USB 벌크 및 제어 전송을 사용하여 마이크로컨트롤러와 상호작용하며, 따라서 “소프트” USB-to-serial driver의 역할을 한다. 마이크로컨트롤러의 펌웨어는 USB-to-serial driver를 통해 태블릿과 인터페이스하도록 설정된다. 이는 바이트를 하나씩 수신하고 궁극적으로 장난감차를 조종하는 무선 리모컨에서 해당되는 핀을 아래로 당긴다.

시리얼 통신을 개시하는 데는 다음과 같은 Java 코드가 사용된다.

UsbDeviceConnection conn = usbm.openDevice(dev);
conn.controlTransfer(0x40, 0, 0, 0, null, 0, 0);// reset
conn.controlTransfer(0x40, 0, 1, 0, null, 0, 0);// clear Rx
conn.controlTransfer(0x40, 0, 2, 0, null, 0, 0);// clear Tx
conn.controlTransfer(0x40, 0x03, 0x4138, 0, null, 0, 0);// set baudrate 9600

이 코드는 libftdi 기능과 매우 유사하다.

int ftdi_usb_reset(struct ftdi_context *ftdi)
int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi)
int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi)
int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate)

일단 연결이 초기화되면, 더 많은 벌크 전송이 안드로이드 운영체제의 USB API를 통해 유사한 방법으로 이루어진다.

결론
이 글에서 설명한 애플리케이션 예제는 몇 가지 내재된 문제점에도 불구하고 USB 인터페이스를 통해 안드로이드 기반 제어 기능을 실제로 구현할 수 있음을 보여준다. 안드로이드 호스트 API 사용과 함께 적절한 하드웨어를 조달하고 관련 펌웨어를 개발한다면, 안드로이드 운영체제와 여러 다양한 특징에 대한 지식이 많지 않아도 상상력이 넘치는 애플리케이션을 만들 수 있다. 

<저작권자(c)스마트앤컴퍼니. 무단전재-재배포금지>



  • 100자평 쓰기
  • 로그인

TOP