2012-01-22 60 views
16

我正在开发一个利用Android 3.2中的USB主机功能的项目。一般来说,我的USB /串行通信缺乏知识和人才。我也无法找到任何我需要做的很好的示例代码。Android USB主机通信

我需要从USB通信设备读取。
例如:当我通过腻子连接(我的电脑),我输入:

>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 

我可以从在该时间余接收的“走”的回波的Android设备发送初始“GO”指令。

然后没有其他任何后续的读取。

我该怎么做: 1)发送'go'命令。 2)读入结果数据流。

我正在使用的USB设备具有以下接口(端点)。

设备类:通信设备(0X2)

接口:

接口#0 类别:通信设备(0X2) 端点#0 方向:入站(0x80的) 类型:Intrrupt段(0x3 ) 轮询间隔:255 最大分组大小:32个 属性:000000011

接口#1 类别:通信DE副类(CDC)(是0xA) 端点#0 地址:129 数:1 方向:入站(0x80的) 类型:散装(0X2) 轮询间隔(0) 最大分组大小:32 属性:000000010

端点#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

对于我们这些挣扎在那里,你怎么选择接口1,为了什么目的将0接口,中断接口,可以用来做什么?谢谢! – Rachael

回答

12

我不想回答我的问题,但...我想通弄明白了。我只是混淆了我的读写。此外,该设备不喜欢我在命令结束时使用的'\ n'。它似乎与'\ r'相得益彰。

我最终使用android的bulkTransfer读取和写入。我的写作看起来像这样。

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

而对于我的BufferedWriter我重写写方法:

@覆盖

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); 
    } 

的读取是相似的:

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?看起来像你写的一堂课。你能为此展示一些代码吗? –