2012-01-22 9 views
16

저는 Android 3.2에서 USB 호스트 기능을 사용하는 프로젝트를 진행하고 있습니다. 나는 일반적으로 USB/시리얼 통신에 관한 지식과 재능이 절망적 인 부족으로 고통 받고있다. 나는 또한 내가해야 할 일에 대한 좋은 예제 코드를 찾을 수 없다.Android USB 호스트 통신

USB 통신 장치에서 읽어야합니다.
예는 : 나는 (내 PC에) 퍼티를 통해 연결하면 내가 입력 :

>GO 

그리고 디바이스 나에 대한 데이터를 밖으로 분출 시작합니다. 피치/롤/온도/체크섬.

예는 :

$R1.217P-0.986T26.3*60 
$R1.217P-0.986T26.3*60 
$R1.217P-0.987T26.3*61 
$R1.217P-0.986T26.3*60 
$R1.217P-0.985T26.3*63 

나는 'GO'의 에코를받는 시간에 안드로이드 장치에서 초기 'GO'명령을 보낼 수 있습니다.

다음에 이어지는 읽기에는 아무 것도 표시되지 않습니다.

어떻게 할 수 있습니까 : 1) 'go'명령을 보내십시오. 2) 결과로 나오는 데이터 스트림을 읽습니다.

내가 사용하고있는 USB 장치에는 다음 인터페이스 (끝점)가 있습니다.

장치 클래스 : 통신 장치 (0x2로)

인터페이스 :

인터페이스 # 0 등급 : 통신 장치 (0x2로) 엔드 포인트 # 0 방향 : 인바운드 (0x80으로) 유형 : Intrrupt (0x3으로) 폴링 간격 : 255 최대 패킷 크기 : 32 속성 : 000000011

인터페이스 # 1 클래스 : 통신 드 그 클래스 (CDC) (0xa는) 엔드 포인트 # 0 주소 : 129 수 : 1 방향 : 인바운드 (0x80으로) 유형 : 벌크 (0x2로) 폴링 간격 (0) 최대 패킷 크기 : 32 속성 : 000,000,010

엔드 포인트 # 1 주소 : 2 수 : 2 방향 : 아웃 바운드 (0x0으로) 유형 : 벌크 (0x2로) 폴링 간격 (0) 최대 패킷 크기 : 32 속성 : 000000010

권한을 처리하고, 장치에 연결하고, 올바른 인터페이스를 찾고 끝점을 할당 할 수 있습니다. 나는 초기 명령을 보내기 위해 사용할 기술을 알아내는 데 어려움을 겪고있다. 행운과 bulkTransfer와 controlTransfer의 다른 조합을 시도했습니다.

감사합니다.

나는 아래와 같이 인터페이스 # 1을 사용하고 있습니다 :

public AcmDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) { 
    Preconditions.checkState(usbDeviceConnection.claimInterface(usbInterface, true)); 
    this.usbDeviceConnection = usbDeviceConnection; 

    UsbEndpoint epOut = null; 
    UsbEndpoint epIn = null; 
    // look for our bulk endpoints 
    for (int i = 0; i < usbInterface.getEndpointCount(); i++) { 
     UsbEndpoint ep = usbInterface.getEndpoint(i); 
    Log.d(TAG, "EP " + i + ": " + ep.getType()); 
     if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { 
     if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { 
      epOut = ep; 

     } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { 
      epIn = ep; 
     } 

     } 
    } 
    if (epOut == null || epIn == null) { 
     throw new IllegalArgumentException("Not all endpoints found."); 
    } 

    AcmReader acmReader = new AcmReader(usbDeviceConnection, epIn); 
    AcmWriter acmWriter = new AcmWriter(usbDeviceConnection, epOut); 
    reader = new BufferedReader(acmReader); 
    writer = new BufferedWriter(acmWriter); 
    } 
+0

, 어떻게, 0 인터페이스 기능 것입니다 무슨 목적으로 인터페이스 1, 인터럽트 인터페이스에 사용되는 선택 했습니까? 감사! – Rachael

답변

12

나는 내 자신의 질문에 대답하기 싫어하지만 ... 나는 그것을 알아 낸 얻었다. 나는 독서와 글을 섞어 가고 있었다.또한 장치는 내 명령 끝에 '\ n'을 사용하지 않았습니다. 그것은 '\ r'과 함께 나아 간다.

필자는 android의 bulkTransfer를 사용하여 읽기 및 쓰기 작업을 마쳤습니다. 내 글은 이렇게 보였다. 유사했다

@Override

public void write(char[] buf, int offset, int count) throws IOException { 
    byte[] buffer = new String(buf, offset, count).getBytes(Charset.forName("US-ASCII")); 
    int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); 
    } 

읽습니다 :

try { 
      device.getWriter().write(command + "\r"); 
      device.getWriter().flush(); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 

그리고 내 BufferedWriter의 내 오버라이드 (override) 쓰기 방법은

char[] buffer = new char[BUF_SIZE]; 
    try { 
     BufferedReader reader = device.getReader(); 

     int readBytes = reader.read(buffer); 
     Log.d(TAG, "BYTES READ: " + readBytes); 

    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
    String strBuf = new String(buffer).trim(); 
    if (DEBUG) { 
     Log.d(TAG, "Read: " + strBuf); 
    } 

그리고 :

@Override 
    public int read(char[] buf, int offset, int count) throws IOException { 
    byte[] buffer = new byte[count]; 
    int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); 

    if (byteCount < 0) { 
     throw new IOException(); 
    } 
    char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); 
    System.arraycopy(charBuffer, 0, buf, offset, byteCount); 
    return byteCount; 
    } 

이 모든 너무 같은 스레드에서 쫓겨되었다

new Thread() { 
    @Override 
public void run() { 

    String command = "go"; 
    write(command); 

    while (true) { 
     String coords = read(); 
     } 
} 
}.start(); 

은 분명히이 바로 통신의 물건과 내가해야에 지금 (다시보고 할 수있는 서비스에 넣어 뭔가를 할 핸들러를 사용하여 최상위 UI 작업에 연결). 그러나이 부분은 알아 낸 것입니다.

rosjava (http://code.google.com/p/rosjava/)에서 작업하는 사람들에게 큰 감사를드립니다. 그들은 많은 훌륭한 프로젝트를 작성했으며 코드는 매우 유용했습니다.

사물을 명확히하는 데 도움이되는 장치 클래스 추가.

import com.google.common.base.Preconditions; 

import android.hardware.usb.UsbConstants; 
import android.hardware.usb.UsbDeviceConnection; 
import android.hardware.usb.UsbEndpoint; 
import android.hardware.usb.UsbInterface; 
import android.util.Log; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 

/* This class represents a USB device that supports the adb protocol. */ 
public class BKDevice { 

// private static final int TIMEOUT = 3000; 

private final UsbDeviceConnection usbDeviceConnection; 
private final BufferedReader reader; 
private final BufferedWriter writer; 
public static final String TAG = "AcmDevice"; 

public BKDevice(UsbDeviceConnection usbDeviceConnection, 
     UsbInterface usbInterface) { 
    Preconditions.checkState(usbDeviceConnection.claimInterface(
      usbInterface, true)); 
    this.usbDeviceConnection = usbDeviceConnection; 

    UsbEndpoint epOut = null; 
    UsbEndpoint epIn = null; 
    // look for our bulk endpoints 
    for (int i = 0; i < usbInterface.getEndpointCount(); i++) { 
     UsbEndpoint ep = usbInterface.getEndpoint(i); 
     Log.d(TAG, "EP " + i + ": " + ep.getType()); 

     if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { 
      if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { 
       epOut = ep; 

      } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { 
       epIn = ep; 

      } 
     } 
    } 
    if (epOut == null || epIn == null) { 
     throw new IllegalArgumentException("Not all endpoints found."); 
    } 

    BKReader acmReader = new BKReader(usbDeviceConnection, epIn); 
    BKWriter acmWriter = new BKWriter(usbDeviceConnection, epOut); 

    reader = new BufferedReader(acmReader); 
    writer = new BufferedWriter(acmWriter); 
} 

public BufferedReader getReader() { 
    return reader; 
} 

public BufferedWriter getWriter() { 
    return writer; 
} 
} 

추가 BKReader 코드 : 거기에 어려움을 겪고 우리의 사람들을 위해

import android.hardware.usb.UsbDeviceConnection; 
import android.hardware.usb.UsbEndpoint; 
import android.util.Log; 

import java.io.IOException; 
import java.io.Reader; 
import java.nio.charset.Charset; 

public class BKReader extends Reader { 

    private static final int TIMEOUT = 1000; 

    private final UsbDeviceConnection connection; 
    private final UsbEndpoint endpoint; 

    public BKReader(UsbDeviceConnection connection, UsbEndpoint endpoint) { 
     this.connection = connection; 
     this.endpoint = endpoint; 
    } 

    @Override 
    public int read(char[] buf, int offset, int count) throws IOException { 
     byte[] buffer = new byte[count]; 
     int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); 

     if (byteCount < 0) { 
      throw new IOException(); 
     } 
     char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); 
     System.arraycopy(charBuffer, 0, buf, offset, byteCount); 
     return byteCount; 
    } 

    @Override 
    public void close() throws IOException { 
    } 

} 
+0

어떻게 device.getwriter()를 얻을 수 있었습니까? flush() 메서드는 무엇을 할 것인가? – Sathish

+0

내 장치 클래스에 BufferedWriter가 포함되어 있습니다. getWriter가 해당 객체를 반환했습니다. 따라서 flush()는 단순히 스트림을 플러시합니다. 도움을 위해 위의 클래스 코드를 붙여 넣습니다. –

+0

BKReader 란 무엇입니까? 네가 쓴 수업 같아. 그것도 몇 가지 코드를 보여줄 수 있습니까? –

관련 문제