Babak
Babak

Reputation: 101

reading data from usb serial port in Android

I use prolifit PL23023 chip for send and receive data to my android app. I Handled driver thing about pl2303 and I can write and read data over serial. but the problem is when for example I receive a 15 byte data,its read in a 11byte data and a 4byte data. no data loss,its give me all data but in a 11byte packets. I controlled every thing about buffer size and it seems no problem. This is method that reads data:

    @Override
    public int read(byte[] dest, int timeoutMillis) throws IOException {
      //  synchronized (mReadBufferLock) {
            int readAmt = Math.min(dest.length, mReadBuffer.length);

            int numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer,
                    readAmt, timeoutMillis);
            if (numBytesRead < 0) {
                return 0;
            }
            System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
            return numBytesRead;
        //}
    }

and bulkTransfer() method finally executed in native methods and we do not know about what is going in bulkTransfer().

and interesting thing about this functionality is that when I put a break point in first of this line.

   int numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer,
                    readAmt, timeoutMillis);

and run the program in Debug mode, the value of numBytesRead in 15 byte example sets to 15 and every thing is ok! I dont know what is happening. in debug mode I can get more than 11 byte packets but in normal mode I can get only 11 byte packets.

Upvotes: 0

Views: 3914

Answers (1)

Chris Stratton
Chris Stratton

Reputation: 40407

Nothing is wrong with the system, only with the expectations. This is the nature of serial ports - data arrives at the timing with which the source sends it, which could be timing that keeps the line fully busy, or potentially years between characters.

Independently of that, your USB implementation queries the USB converter chip for any data it has received, and it will give you whatever it has up to that time. It cannot know if more is on the way from the source, so it merely gives you what it has up to that time.

If you want to reliably obtain complete "messages" you will need to keep reading and concatenating the results until you reach whatever condition defines the end of a "message" for you - for example, a newline character. (It is possible this will mean that one read contains the end of one message and the start of a next.) As you have seen, slowing your program down can increase the chances that a full "message" has been received at the converter by the time you do the first read, but that isn't reliable (also keep in mind that the maximum data size for one USB read in this mode is fairly small).

Normally you could do this reading in a loop, but beware on Android that you must not execute blocking operations on the UI thread, so you will probably need to do this collection in a background thread.

Upvotes: 4

Related Questions