我正在开发一个利用Android 3.2中的USB Host功能的项目。一般来说,我在USB /串行通信方面缺乏令人遗憾的缺乏知识和才能。我也无法找到任何我需要做的好示例代码。
我需要从USB通讯设备上读取 例如:当我通过Putty(在我的电脑上)连接时,我输入:
>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'命令,此时我收到'GO'的回音。
然后在任何后续读取上没有别的。
我怎样才能: 1)发送'go'命令。 2)读入产生的数据流。
我正在使用的USB设备具有以下接口(端点)。
设备类:通信设备(0x2)
接口:
接口#0 类别:通讯设备(0x2) 端点#0 方向:入站(0x80) 类型:中断(0x3) 民意调查间隔:255 最大包大小:32 属性:000000011
接口#1 类别:通信设备类(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 :(得分: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();
显然这只是comm的东西,我现在需要用它做一些事情(把它放在一个可以使用处理程序报告回顶层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 {
}
}