Android USB 主机通信
我正在开发一个利用 Android 3.2 中 USB 主机功能的项目。我非常缺乏有关 USB/串行通信的知识和人才。我也无法找到任何适合我需要做的事情的好的示例代码。
我需要从 USB 通信设备读取数据。
例如:当我通过 Putty(在我的 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
我可以从 Android 设备发送初始“GO”命令,此时我会收到“GO”的回显。
然后在任何后续读取中都没有其他内容。
我怎样才能: 1) 发送“开始”命令。 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);
}
I'm working on a project that utilizes the USB Host capabilities in Android 3.2. I'm suffering from a deplorable lack of knowledge and talent regarding USB/Serial communication in general. I'm also unable to find any good example code for what I need to do.
I need to read from a USB Communication Device.
Ex: When I connect via Putty (on my PC) I enter:
>GO
And the device starts spewing out data for me. Pitch/Roll/Temp/Checksum.
Ex:
$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
I can send the initial 'GO' command from the Android device at which time I receive an echo of 'GO'.
Then nothing else on any subsequent reads.
How can I:
1) Send the 'go' command.
2) Read in the stream of data that results.
The USB device I'm working with has the following interfaces (endpoints).
Device Class: Communication Device (0x2)
Interfaces:
Interface #0
Class: Communication Device (0x2)
Endpoint #0
Direction: Inbound (0x80)
Type: Intrrupt (0x3)
Poll Interval: 255
Max Packet Size: 32
Attributes: 000000011
Interface #1
Class: Communication Device Class (CDC) (0xa)
Endpoint #0
Address: 129
Number: 1
Direction: Inbound (0x80)
Type: Bulk (0x2)
Poll Interval (0)
Max Packet Size: 32
Attributes: 000000010
Endpoint #1
Address: 2
Number: 2
Direction: Outbound (0x0)
Type: Bulk (0x2)
Poll Interval (0)
Max Packet Size: 32
Attributes: 000000010
I'm able to deal with permission, connect to the device, find the correct interface and assign the endpoints. I'm just having trouble figuring out which technique to use to send the initial command read the ensuing data. I'm tried different combinations of bulkTransfer and controlTransfer with no luck.
Thanks.
I'm using interface#1 as seen below:
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我讨厌回答我自己的问题,但是......我已经弄清楚了。我只是混淆了我的阅读和写作。此外,该设备不喜欢我在命令末尾使用的“\n”。它似乎与 '\r' 相处得更好。
我最终使用android的bulkTransfer进行读取和写入。我写的东西看起来像这样。
我为 BufferedWriter 重写的写入方法:
@Override
读取内容类似:
并且:
这一切都是在一个线程中开始的,如下所示:
显然这只是通信内容,我现在需要用它做一些事情(把它位于一个服务中,可以使用处理程序向顶级 UI 活动报告)。但这部分已经弄清楚了。
非常感谢从事 rosjava 工作的人们 (http://code.google.com/p /rosjava/)...他们整合了很多很棒的项目,他们的代码非常有帮助。
添加我的设备类以帮助澄清问题。
添加BKReader代码:
I hate to answer my own question but... I got it figured out. I was just mixing up my reads and writes. Additionally the device didn't like the '\n' I was using at the end of my commands. It appears to get along with '\r' much better.
I ended up using android's bulkTransfer for reads and writes. My writes looked like this.
And my overridden write method for my BufferedWriter:
@Override
The reads were similar:
And:
This was all just kicked off in a thread like so:
Obviously this is just the comm stuff and I'll need to now do something with it (put it in a Service that can report back to a top level UI Activity using a handler). But this part of it is figured out.
A huge thank you to the folks who are working on rosjava (http://code.google.com/p/rosjava/)... They have put together a lot of great projects and their code was very helpful.
Adding my device class to help clarify things.
Adding BKReader code: