• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[JAVA ANDROID] wysyłanie tablicy bajtów przez USB po wypełnieniu jej elementami

Object Storage Arubacloud
+2 głosów
275 wizyt
pytanie zadane 1 lipca 2021 w Java przez matej1410 Nowicjusz (180 p.)

Witam serdecznie szanownych Kolegów.

 

Piszę kod w Android Studio w którym to wysyłam bajty po USB do mikrokontrolera.

Używam do tego metody przyjmującej takie argumenty:

public int write(final byte[] src, final int timeout) throws IOException;

Samo wysyłanie odbywa się tak:

port.write(tablica_czas,1000);

Gdy deklaruję i wypełniam tablicę w taki sposób:

static byte[] tablica_czas = {1,2,3,4,5,6,7,8,9};

i wysyłam ją poprzez metodę port.write to odbiera się bardzo dobrze w mikrokontrolerze pod drugiej stronie USB, natomiast kiedy wypełnie tablicę poprzez metodę klasy którą sam sobie wymyśliłem to:

tablica_czas=MojaKlasa.wypełnijTablice();

po tej operacji gdy sprawdzę tablice to co prawda znajdę tam wartości poprawne (poprawne, wpisane przez klasę), ale gdy robię:

port.write(tablica_czas,1000);

to w mikrokontrolerze dostaje tablice z samymi zerami.

Dlaczego tak się dzieje, czy ktoś podpowie? :-)

 

1
komentarz 1 lipca 2021 przez Oscar Nałogowiec (29,290 p.)

Obawiam się, że jeśli nie pokażesz tej funkcji/metody MojaKlasa.wypełnijTablice() wiele nie da się pomóc. Jeśli jest to duża funkcja lub nie chcesz ujawniać szczegółów to spróbuj stworzyć najprostszy program, w którym występuje taki sam błąd. Najprościej poprzez usuwanie kolejnych fragmentów oryginalnego programu.

Na razie dziwnie wygląda nazwa - wypełnijTablicę a nie przekazujesz tablicy do wypełnienia, natomiast podmieniasz oryginalną referencję.

2 odpowiedzi

+2 głosów
odpowiedź 1 lipca 2021 przez Wiciorny Ekspert (269,710 p.)
Bez wglądu do implementacji nie da się powiedzieć. Pamiętaj jedno o ile tego nie wiesz java - przyjmuje jedynie PARAMETRY PRZEZ WARTOŚĆ, nigdy nie jest to referencja, jeśli przyjmuje typ obiektowy jest to WARTOŚĆ REFERENCJI, A NIE CZYSTO REFERENCJA, stąd jest to kopia :)
0 głosów
odpowiedź 1 lipca 2021 przez matej1410 Nowicjusz (180 p.)

public class UstawCzas {

    public byte[] getTablicaCzasow() {
        return tablicaCzasow;
    }

    public byte[] tablicaCzasow = new byte[9];

    public UstawCzas() {}

    public void PrzypiszCzasy()
    {
        DateTime czasTerazniejszy = new DateTime();

        tablicaCzasow[0]= 0; //
        tablicaCzasow[1]= 0; // 001 to kod zapisu godziny
        tablicaCzasow[2]= 1; //

        byte rok = (byte) (czasTerazniejszy.getYear()-2000);
        byte jednostka = (byte) (rok%10);
        byte dziesiatka = (byte) ((byte) ((rok-(rok%10)))/10);
        byte heks=0;
        heks = (byte) (dziesiatka << 4);
        heks = (byte) (heks | jednostka);
        tablicaCzasow[3]= heks;

        byte miesiac = (byte) czasTerazniejszy.getMonthOfYear();
        jednostka = (byte) (miesiac%10);
        dziesiatka = (byte) ((byte) ((miesiac-(miesiac%10)))/10);
        heks=0;
        heks = (byte) (dziesiatka << 4);
        heks = (byte) (heks | jednostka);
        tablicaCzasow[4]= heks;

        byte dzien = (byte) czasTerazniejszy.getDayOfMonth();
        jednostka = (byte) (dzien%10);
        dziesiatka = (byte) ((byte) ((dzien-(dzien%10)))/10);
        heks=0;
        heks = (byte) (dziesiatka << 4);
        heks = (byte) (heks | jednostka);
        tablicaCzasow[5]= heks;

        byte godzina = (byte) czasTerazniejszy.getHourOfDay();
        jednostka = (byte) (godzina%10);
        dziesiatka = (byte) ((byte) ((godzina-(godzina%10)))/10);
        heks=0;
        heks = (byte) (dziesiatka << 4);
        heks = (byte) (heks | jednostka);
        tablicaCzasow[6]= heks;

        byte minuta = (byte) czasTerazniejszy.getMinuteOfHour();
        jednostka = (byte) (minuta%10);
        dziesiatka = (byte) ((byte) ((minuta-(minuta%10)))/10);
        heks=0;
        heks = (byte) (dziesiatka << 4);
        heks = (byte) (heks | jednostka);
        tablicaCzasow[7]= heks;

        byte sekunda = (byte) czasTerazniejszy.getSecondOfMinute();
        jednostka = (byte) (sekunda%10);
        dziesiatka = (byte) ((byte) ((sekunda-(sekunda%10)))/10);
        heks=0;
        heks = (byte) (dziesiatka << 4);
        heks = (byte) (heks | jednostka);
        tablicaCzasow[8]= heks;
    }


}

 

tu jest wypełnianie tablicy:

UstawCzas ustawCzas = new UstawCzas();
ustawCzas.PrzypiszCzasy();
tablica_czas=ustawCzas.getTablicaCzasow();

w tym miejscu gdy podglądam tablice to mam w niej wartości sensowne, natomiast w mikrokontrolerze przy wysyłaniu dostaję już zera.

i jeszcze na koniec to:

try {
       port.write(tablica_czas,1000);

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

Dziękuję Wam za zainteresowanie tematem.

 

1
komentarz 3 lipca 2021 przez Wiciorny Ekspert (269,710 p.)
https://stackoverflow.com/questions/28154369/why-dropping-leading-all-zeros-byte-in-a-java-byte-array-before-hashing
Dlatego, żę jeśli pierwsze idzie 0, traktowane jest to jako unasigned - > wiodące zero , traktowane jest pewnie jako "bajt znaku "
komentarz 3 lipca 2021 przez matej1410 Nowicjusz (180 p.)
czy to oznacza, że nie można zer przesyłać ponieważ to ucina część danych?

Jedyne co mi przychodzi do głowy to to, żeby sprawdzać tablice przed wysłaniem i w miejsce zer wpisywać ściśle określoną liczbę którą w odbiorniku traktować jako zero no i podmieniać ją po odebraniu na zero.
1
komentarz 3 lipca 2021 przez Oscar Nałogowiec (29,290 p.)
edycja 3 lipca 2021 przez Oscar

@matej1410,
 ciekawe spostrzeżenie z tymi zerami. W sumie to ten najpierwszy przykład, który podałeś na początku jako działający, nie wysyłał żadnych zer, więc nie wiadomo czy to dlatego działał, czy z powodu braku zabawy zmiennymi. Stawiam na to pierwsze. Trzeba sprawdzić w dokumentacji libUSB czy ten bulk transfer nie ma jakiś ograniczeń, choć w to wątpię, to podstawowy transfer po USB.

Czy jesteś pewny, że do tego urządzenia USB nie ma drivera od razu w kernelu i ten driver tam nie grzebie? Oglądałem przykłady użycia libUSB na komputerach destopowych i używają tam takiej konstrukcji (C).

    if(libusb_kernel_driver_active(handle, 0) == 1)    

Nie ma podobnej funkcji/metody w tej bibliotece androidowej?

 

Mam jeszcze jeden pomysł - czy możesz przedebuggować wykonanie tej funkcji write() - czy ona wysyła całość w jednym wywołaniu bulkTransfer, czy wysyła to kawałkami, jakie są wyniki poszczególnych bulkTransferów itp?

1
komentarz 3 lipca 2021 przez Wiciorny Ekspert (269,710 p.)
ja podejrzewam, że traktuje 0, jako znak zmiany "pinu" sygnału albo właśnei znak kontrolny i zeruje - robiąc odcięcie pozostałych bitow
komentarz 6 lipca 2021 przez matej1410 Nowicjusz (180 p.)

@Oscar, przepraszam za opóźnienie w odpisaniu. 

Wysyła całość w jednym wywołaniu. 

Kolejna obserwacja jest taka, że gdy wysyłam dane w drugą stronę czyli z STM32 do Smartfona to nie ma problemu z zerami.

Jeśli chodzi o wcześniej poruszany problem to rozwiązałem go tak, że zastępuję zera danym znakiem i następnie w odbiorniku wychwytuję je  i zamieniam na zera z powrotem. Pozwalam sobie na to, ponieważ w tę (problematyczną) stronę wysyłam tylko 8 bajtów natomiast w drugą aż 8kB (można wysyłać zera i odbierać je poprawnie), ale na moje szczęście jak już wspomniałem  tu problemu nie ma.

Bardzo Wam dziękuję za wszystkie cenne uwagi!

Podobne pytania

0 głosów
1 odpowiedź 123 wizyt
0 głosów
0 odpowiedzi 114 wizyt
0 głosów
0 odpowiedzi 19 wizyt

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...