Android bluetooth nie odniera wszystkich danych

0

Witam,
mam taki problem, że moja aplikacja nie odbiera niektórych "ramek"
wysyłam z terminala przez rs do btm222 ramkę danych hex
68 1A 1A 68 00 01 04 1A 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 16
i jest ok, ale jak już wyślę ramkę
68 1A 1A 68 00 05 00 1A 00 1E 00 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 10 16
to niestety jej nie odbiera. Poniżej metody połączenia bt i obsługi bufora.
metoda msg wyswietla toasty, które są dla mnie "checkpointami"

czy ktoś może mi powiedzieć o co chodzi?

 
private class ConnectBT extends AsyncTask<Void, Void, Void>{
        private boolean ConnectSuccess = true; //if it's here, it's almost connected

        @Override
        protected void onPreExecute()
        {
            progress = ProgressDialog.show(DeviceActivity.this, "Łączenie...", "Proszę czekać!!!");  //show a progress dialog
        }

        @Override
        protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
        {
            try
            {
                if (btSocket == null || !isBtConnected)
                {
                    myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
                    BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
                    btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
                    BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                    btSocket.connect();//start connection
                }
            }
            catch (IOException e)
            {
                ConnectSuccess = false;//if the try failed, you can check the exception here
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
        {
            super.onPostExecute(result);

            if (!ConnectSuccess)
            {
                msg("Nie udało się nawiązać połączenia z wybranym urządzeniem.");
                finish();
            }
            else
            {
                msg("Połączono.");
                isBtConnected = true;
                mConnectedThread = new ConnectedThread(btSocket);
                mConnectedThread.start();
                doItAferFullConnect();
            }
            progress.dismiss();
        }
    }

    public class ConnectedThread extends Thread {
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        //creation of the connect thread
        public ConnectedThread(BluetoothSocket socket) {
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                //Create I/O streams for connection
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[256];
            int bytes;

            // Keep looping to listen for received messages
            while (true) {
                try {
                    bytes = mmInStream.read(buffer);            //read bytes from input buffer
                    String readMessage = new String(buffer, 0, bytes);
                    // Send the obtained bytes to the UI Activity via handler
                    bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
                } catch (IOException e) {
                    break;
                }
            }
        }
        //write method
        public void write(byte[] input) {
            byte[] msgBuffer = input;
            try {
                mmOutStream.write(msgBuffer);                //write bytes over BT connection via outstream
            } catch (IOException e) {
                //if you cannot write, close the application
                Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }

   private void addToBuffer(byte[] receivedBytes){

        byte[] temp_0 = buffer_0;
        byte[] temp_1 = receivedBytes;
        byte[] buff_1 = new byte[temp_0.length + temp_1.length];

        for(int i=0; i<buff_1.length; ++i){
            if(i<temp_0.length) buff_1[i] = temp_0[i];
            else buff_1[i] = temp_1[i - temp_0.length];
        }

        buffer_0 = buff_1;
        bufferControl();
    }

    private void bufferControl(){
        if(buffer_0.length>3){ //dlugosc na glowka = 4bajty
            while(true){
                if(buffer_0[0] == 0x68 && buffer_0[1] == 0x1A && buffer_0[2] == 0x1A && buffer_0[3] == 0x68){
                    if(buffer_0.length>31){
                        if(buffer_0[31] == 0x16){
                            byte[] frame;// = new byte[32];
                            frame = getFrameFromBuffer();
                            buffer_0 = moveBufferLeft(32);
                            msg("dobra ramka");
                            commandCenter.received(frame);
                        }
                    }
                    break;
                }
                else{
                    buffer_0 = moveBufferLeft(1);//przesuniecie bufora
                    if (buffer_0.length<4) break;//jesli naglowek nie miesci sie w buforze
                }
            }
        }
    }

0

OK. problem zaczyna się w momencie wysłania bajtu większego niż 7F. jak to zrobić żeby odbierać od 0 do FF

0
pPlaczek napisał(a):

OK. problem zaczyna się w momencie wysłania bajtu większego niż 7F. jak to zrobić żeby odbierać od 0 do FF

w ogóle nie odbiera, nie wchodzi Ci do jakiegoś ifa czy wywala wyjątek? Wydaje mi się że to nie jest kompletny kod - gdzie jest getFrameFromBuffer?
Nie wnikając w kod - znaki powyżej 7F są to liczby ujemne, prawdopodobnie błąd masz związany z tym (złe porównanie, lub odwołanie się do ujemnego indeksu tablicy)

0

getFrameFromBuffer nie ma tutaj znaczenia - pobiera tylko z buforu pierwsze 32 bajty.
znaki powyżej 7F (do FF) to liczby całkowite od 128 do 255. właśnie w tym jest chyba problem, żę w javie byte odpowiada char z C++ czyli zakres jest od -127 do 127. jednym słowem liczba jest znakowana. bo binarnie na 8 bitach można ustawić 0d 0 do 255, czyli dokładnie tak jak wymaga się tego od zmiennej bajtowej. a tutaj byte jest na 7 bitach robione a 8 określa parzystość :/ dopiero zaczynam jako tako naukę androida (wcześniej nie pisałem w javie) i moim zdaniem parzystość byte jest wyjątkowo niekorzystną sytuacją ...

@editjak wstawiam do jakiejś zmiennej byte wartość na E1 i ją wysyłam przez BT to nie ma problemu żadnego normalnie leci i jest interpretowana przez terminal jako 225. ale jak już mam odebrać E1 to właśnie nie wiem co się dzieje ale jedyna reakcja jest taka, że w ogóle moja aplikacja przestaje odbierać dane po BT (wysyłać nadal się da).

0

Nie ma to żadnego znaczenia
Na zakresie -127 do 127 pomieścisz tyle samo co na 0 do 255
Trzeba tylko o tym pamiętać

1

8 bit nie oznacza parzystości tylko znak

pPlaczek napisał(a):

jak już mam odebrać E1 to właśnie nie wiem co się dzieje ale jedyna reakcja jest taka, że w ogóle moja aplikacja przestaje odbierać dane po BT (wysyłać nadal się da).

pokaż wszystkie swoje funkcje związane z odbiorem

0

też mi się tak wydawało ale jednak jak do stringa wsadzam coś poniżej 0 to nie wiem co się dzieje i odzyskanie tej danej sprawia jakiś kłopot...

0

napisałem też coś takiego do przerobienia stringa na byte[]

private byte[] stringToBytes(String string){
        byte[] temp1 = string.getBytes();
        byte[] temp = new byte[temp1.length];

        for(int i=0; i<temp1.length; ++i){
            if(temp1[i]<0) temp[i] = (byte) (128 + 128 - toUnsignedBytes((int)temp1[i]));
            else temp[i] = temp1[i];
        }

        return temp;
    }

public static byte toUnsignedBytes(int b){
        return (byte)(b & 0xFF);
    }

0

w onCreate jest handler

bluetoothIn = new Handler() {
            public void handleMessage(android.os.Message msg) {
                if (msg.what == handlerState) {                                     //if message is what we want
                    String readMessage = (String) msg.obj;                                                                // msg.arg1 = bytes from connect thread
                    //byte[] readMessage = (byte[]) msg.obj;
                    //addToBuffer(readMessage);
                    //recDataString.append(readMessage);                                      //keep appending to string until ~
                    //addToBuffer(recDataString.substring(0, recDataString.length()));
                    //recDataString.delete(0,recDataString.length());
                    addToBuffer(stringToBytes(readMessage));
                }
            }
        }; 

kontrola buforu poniewaz pakiety przychodzace przez BT dzielą mi dane na mniejsze czesci

private void bufferControl(){
        if(buffer_0.length>3){ //dlugosc na glownka = 4bajty
            while(true){
                if(buffer_0[0] == 0x68 && buffer_0[1] == 0x1A && buffer_0[2] == 0x1A && buffer_0[3] == 0x68){
                    if(buffer_0.length>31){
                        if(buffer_0[31] == 0x16){
                            byte[] frame;// = new byte[32];
                            frame = getFrameFromBuffer();
                            buffer_0 = moveBufferLeft(32);
                            msg("dobra ramka");
                            commandCenter.received(frame);
                        }
                    }
                    break;
                }
                else{
                    buffer_0 = moveBufferLeft(1);//przesuniecie bufora
                    if (buffer_0.length<4) break;//jesli naglowek nie miesci sie w buforze
                }
            }
        }
    } 

private byte[] moveBufferLeft(int count){
        byte[]temp = new byte[buffer_0.length-count];
        for(int i = 0; i<temp.length; ++i) temp[i] = buffer_0[i+count];

        return temp;
    }

    private byte[] getFrameFromBuffer(){
        byte[] temp = new byte[32];
        for(int i=0; i<32; ++i) temp[i] = buffer_0[i];

        return temp;
    }

commandCenter.received(frame);
to juz jest analiza danych jakie przyszly w ramce
ale przy wartosciach ujemnych nie zostaje nawet wykonane msg("dobra ramka");

1 użytkowników online, w tym zalogowanych: 0, gości: 1