Reading data from Arduino UNO R3 kit

我的梦境 提交于 2019-12-03 21:06:04

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!