问题
I'm trying to read the data already stored by me in the Arduino kit, I'm using the physicaloid library to achieve this. I tested the kit (reading data) by connecting it to my PC using the Type B USB cable provided by Arduino itself and using Tera Term. The data begins to transfer after I press '@' on the keyboard (specific to our implementation).
But when I connect it my Android tablet and use the test project by physicaloid to open a device and start communicating, every time I click 'open' it shows a Toast saying it cannot open. I give permission to access the USB device every time it prompts me. Here is the sample program which I had created to read the data:
if(mPhysicaloid.open()){
Toast.makeText(getBaseContext(), "communicating", Toast.LENGTH_SHORT).show();
String signalToStart = new String("@");
byte[] bufToWrite = signalToStart.getBytes();
mPhysicaloid.write(bufToWrite, bufToWrite.length);
byte[] buf = new byte[255];
mPhysicaloid.read(buf);
String data = new String(buf);
tvResult.setText(data);
mPhysicaloid.close();
}
else
Toast.makeText(getBaseContext(), "no communication with device", Toast.LENGTH_LONG).show();
Now here's what I want to know about the data coming from the Arduino USB cable: is it in the RS232 format where the Android device is not able to understand (I don't know, I may be making a blunder here by asking this data format) or is it in the USB data format that is suitable for the Android device to understand? Please help, I have searched over this the whole day. What can I do to open the device and communicate?
回答1:
I finally got the idea of reading the data from serial USB device. So I thought I'd share it:
First, get all the USB devices attached (if more than one) and get a suitable interface and search for endpoints to communicate with. While initializing the USB device make sure you consider the USB device which you really want to communicate with. You can do that by considering product id and Vendor id. The code for doing the above described..
private boolean searchEndPoint() {
usbInterface = null;//class level variables, declare these.
endpointOut = null;
endpointIn = null;
Log.d("USB","Searching device and endpoints...");
if (device == null) {
usbDevices = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = usbDevices.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice tempDevice = deviceIterator.next();
/**Search device for targetVendorID(class level variables[vendorId = SOME_NUMBER and productId=SOME_NUMBER] which u can find) and targetProductID.*/
if (tempDevice .getVendorId() == vendorId) {
if (tempDevice .getProductId() == productId) {
device = tempDevice ;
}
}
}
}
if (device == null){
Log.d("USB","The device with specified VendorId and ProductId not found");
return false;
}
else
Log.d("USB","device found");
/**Search for UsbInterface with Endpoint of USB_ENDPOINT_XFER_BULK,
*and direction USB_DIR_OUT and USB_DIR_IN
*/
try{
for (int i = 0; i < device.getInterfaceCount(); i++) {
UsbInterface usbif = device.getInterface(i);
UsbEndpoint tOut = null;
UsbEndpoint tIn = null;
int tEndpointCnt = usbif.getEndpointCount();
if (tEndpointCnt >= 2) {
for (int j = 0; j < tEndpointCnt; j++) {
if (usbif.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT) {
tOut = usbif.getEndpoint(j);
} else if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN) {
tIn = usbif.getEndpoint(j);
}
}
}
if (tOut != null && tIn != null) {
/** This interface have both USB_DIR_OUT
* And USB_DIR_IN of USB_ENDPOINT_XFER_BULK
*/
usbInterface = usbif;
endpointOut = tOut;
endpointIn = tIn;
}
}
}
if (usbInterface == null) {
Log.d("USB","No suitable interface found!");
return false;
} else {
Log.d("USB","Suitable interface found!");
return true;
}
}catch(Exception ex){
ex.printStackTrace();
return false;
}
}
Now you have a device, USB interface, and endpoints ready for communication. Now it's time to establish a connection between your Android device and USB device. Below is the code for this (and checking whether the connection is up and communicating):
private boolean checkUsbCOMM() {
/**Value for setting request, on the USB connection.*/
final int RQSID_SET_CONTROL_LINE_STATE = 0x22;
boolean success = false;
Log.d("USB","Checking USB Device for communication: ");
try{
Boolean permitToRead = SUSBS_usbManager.hasPermission(SUSBS_device);
if (permitToRead) {
//class level variable(connection, usbManager : declare it)
connection = usbManager.openDevice(device);
if (connection != null) {
connection.claimInterface(usbInterface, true);
int usbResult;
usbResult = connection.controlTransfer(0x21, //requestType
RQSID_SET_CONTROL_LINE_STATE, //SET_CONTROL_LINE_STATE(request)
0, //value
0, //index
null, //buffer
0, //length
500); //timeout = 500ms
Log.i("USB","controlTransfer(SET_CONTROL_LINE_STATE)[must be 0 or greater than 0]: "+usbResult);
if(usbResult >= 0)
success = true;
else
success = false;
}
}
else {
/**If permission is not there then ask for permission*/
usbManager.requestPermission(device, mPermissionIntent);
Log.d("USB","Requesting Permission to access USB Device: ");
}
return success;
}catch(Exception ex){
ex.printStackTrace();
return false;
}
}
Voila, the USB device is now able to communicate. So let's read using a separate thread:
if(device!=null){
Thread readerThread = new Thread(){
public void run(){
int usbResult = -1000;
int totalBytes = 0;
StringBuffer sb = new StringBuffer();
String usbReadResult=null;
byte[] bytesIn ;
try {
while(true){
/**Reading data until there is no more data to receive from USB device.*/
bytesIn = new byte[endpointIn.getMaxPacketSize()];
usbResult = connection.bulkTransfer(endpointIn,
bytesIn, bytesIn.length, 500);
/**The data read during each bulk transfer is logged*/
Log.i("USB","data-length/read: "+usbResult);
/**The USB result is negative when there is failure in reading or
* when there is no more data to be read[That is :
* The USB device stops transmitting data]*/
if(usbResult < 0){
Log.d("USB","Breaking out from while, usb result is -1");
break;
}
/**Total bytes read from the USB device*/
totalBytes = totalBytes+usbResult;
Log.i("USB","TotalBytes read: "+totalBytes);
for(byte b: bytesIn){
if(b == 0 )
break;
else{
sb.append((char) b);
}
}
}
/**Converting byte data into characters*/
usbReadResult = new String(sb);
Log.d("USB","The result: "+usbReadResult);
//usbResult holds the data read.
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
/**Starting thread to read data from USB.*/
SUSBS_readerThread.start();
SUSBS_readerThread.join();
}
For permission, make sure you add a PendingIntent
as well add the permission to your manifest.
AndroidManifest : <uses-feature android:name="android.hardware.usb.host" />
PendingIntent:
private PendingIntent mPermissionIntent;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
mPermissionIntent = PendingIntent.getBroadcast(MainActivity.this,
0, new Intent(ACTION_USB_PERMISSION), 0);
/**Setting up the Broadcast receiver to request a permission to allow the APP to access the USB device*/
IntentFilter filterPermission = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filterPermission);
来源:https://stackoverflow.com/questions/29679318/reading-data-from-arduino-uno-r3-kit