felHR85 / UsbSerial

Usb serial controller for Android
MIT License
1.78k stars 581 forks source link

Losing Bytes? #348

Closed untaman closed 2 years ago

untaman commented 2 years ago

Hi! So i have a app that takes data from a teensy arduino via to usb and add it to a text field and then parses it. The issue i am having is that if i try to run another function in "onReceivedData" (a la get my location) I apparently seem to lose bytes in normally the 3rd buffer and fail the parse. But if i leave the function out it works fine. The buffers are 4x 2048 Bytes ( which i am loath to change size of ) appended to some text.

  UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
        //Defining a Callback which triggers whenever data is read.
        @Override
        public void onReceivedData(byte[] arg0) {
            String data = null;

            try {

                data = new String(arg0, "UTF-8");

                data.concat("/n");
                sb.append(data);
                tvAppend(textView, sb);  //appending to textview but it fails on function pass too

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();

            }

//copied from https://github.com/felHR85/UsbSerial/issues/37 the 1 with the thumbs up in the bottom
//the if statement caused problems as well...probably        
     if (data.endsWith("#") || data.endsWith("\n#")||data.endsWith("/n#")) { 
                //Do what ever you want
                sb.setLength(0);
                String location = GetLocandandBearing(); //if i add anything like this it fails parsing 
//and i have place it in the try block as well
                array.add(location);
            }

        }
    };

........ .end of that function

//not really part of the problem just added for completeness
 private final  BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection.
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
                boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
                if (granted) {
                    connection = usbManager.openDevice(device);
                    serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
                    if (serialPort != null) {
                        if (serialPort.open()) { //Set Serial Connection Parameters.
                            setUiEnabled(true);
                            serialPort.setBaudRate(9600);
                            serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
                            serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
                            serialPort.setParity(UsbSerialInterface.PARITY_NONE);
                            serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
                            serialPort.read(mCallback);
                            tvAppend(textView,"Serial Connection Opened!\n");

                        } else {
                            Log.d("SERIAL", "PORT NOT OPEN");
                        }
                    } else {
                        Log.d("SERIAL", "PORT IS NULL");
                    }
                } else {
                    Log.d("SERIAL", "PERM NOT GRANTED");
                }
            } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
                onClickStart(startButton);
            } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
                onClickStop(stopButton);

            }
        }

    };
..................................... end of that function

 @SuppressLint("MissingPermission")
    public void onClickValid(View view) {

        sb.setLength(0);

        data = textView.getText().toString();
        if (data != null || data != " ") {
            int duration = Toast.LENGTH_SHORT;
            Toast.makeText(context, "You got data:", duration).show();

            String[] divide = new String[0];

            //Splitting off the temperature data
            divide = data.split(":");

............................ same  function

 String mic = divide[2];  //buffer #1
                //String mic = fields[5];
                fields = mic.split(" ");
                System.out.println("Read " + fields.length);
                readData(fields, data1, nSamples - dsize);
                Toast.makeText(context, "mic1", duration).show();
                //mic = micloc.serialIn.readLine();

                mic = divide[3];  //buffer #2
                fields = mic.split(" ");
                System.out.println("Read " + fields.length);
                readData(fields, data2, nSamples - dsize);
                Toast.makeText(context, "mic2", duration).show();
                //mic = micloc.serialIn.readLine();

                mic = divide[4]; //buffer #3
                fields = mic.split(" ");
                System.out.println("Read " + fields.length);
                readData(fields, data3, nSamples - dsize);
                Toast.makeText(context, "mic3", duration).show();    //normally this is the last toast i see
                //mic = micloc.serialIn.readLine();

                mic = divide[5];  //buffer #4 with a # at the end

                //removeing the #
                String[]  str = mic.split("#");
                Toast.makeText(context, "cut #", duration).show(); //this is new but it fails w/o it too 
//and i didn't see this toast either
                String micss = str[0];  //buffer #4 alone
                fields  = micss.split(" ");
                System.out.println("Read " + fields.length);
                readData(fields, data4, nSamples - dsize);
                Toast.makeText(context, "mic4", duration).show();   //i've never get to this
                System.out.flush();

............................ more code

As stated before if i leave out the "GetLocandandBearing();" function this works if a good sample is provided. I am guessing the function cause the program to miss a byte or two and mangles the buffer thus making me fail at the parsing. But that is just a guess. I have tested the output from the teensy via hard coding it and it works fine. So what do? Else, is there a work around where i can trigger the function on the receiving of data for a event from the teensy?

bill-chadwick commented 2 years ago

I experienced this too. Losing pairs of bytes. It looks like newer FTDI devices use 512 byte packets rather than 64. The FTDI Class currently assumes packets that have repeats of 2 bytes of status and 62 bytes of data. The newer FTDI devices go 2 bytes of status followed by 510 bytes of data. There is a 1 bit difference in the first status byte that might be indicating 64/512 byte packets size but I have not been able to find information that confirms that.

untaman commented 2 years ago

Ah that makes sense. I did a work around. I triggered on textView onChange(). Which worked.