Android bluetooth nie odniera wszystkich danych

Android bluetooth nie odniera wszystkich danych
PP
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 7 lat
  • Postów:39
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?

Kopiuj
 
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
                }
            }
        }
    }

edytowany 2x, ostatnio: ŁF
PP
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 7 lat
  • Postów:39
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)

PP
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 7 lat
  • Postów:39
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).

edytowany 1x, ostatnio: pPlaczek
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

PP
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 7 lat
  • Postów:39
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...

PP
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 7 lat
  • Postów:39
0

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

Kopiuj
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);
    }

PP
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 7 lat
  • Postów:39
0

w onCreate jest handler

Kopiuj
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

Kopiuj
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");

edytowany 1x, ostatnio: pPlaczek
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)