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);
}
Best Answer
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: