Toon posts:

[J2ME] DataInputStream komt te snel?

Pagina: 1
Acties:
  • 193 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Hallo,

Ik ben bezig aan een j2me programma, en daarbij komt er seriele data binnen.
Nu is deze data een constante stream die aan een gsmmodule zit ( in j2me dus )

Dus het programma start op, de stream is al aan het sturen, en dan wordt alles in een inputstreambuffer gestoken. Dit doe ik zo:

Java:
1
2
3
4
5
6
7
8
9
10
11
    while (rcv.length() < 100){  
    try {
        int chr;
        chr = in.read();               
       rcv.append(chr+",");
    }          
    
    catch (Exception e){
        e.printStackTrace();}
        
           }


Dus er worden 100 karakter opgeslaan ..
Maar dit lukt enkel als het programma al runt, en wacht op data. En daarna pas de datastream aansteken ( starten )

Maar als de datastream al aanwezig is, en het programma start op, dan krijg ik in de buffer allemaal verkeerde karakters ( 255 dec etc ..)

Wat kan ik eraan doen dat ie de juiste dingen opslaat?
Wat zou er fout gaan ? :?

alvast bedankt

  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Je append een int. Als je de char waarde wilt hebben moet je die casten in je append. Dus:

code:
1
2
rvc.append((char)chr);
rvc.append(",");


Je houdt hierbij geen rekening met mogelijke character encodings, maar zo lang de bron ascii is moet het wel goed gaan :)

edit: in je topic van gisteren (http://gathering.tweakers.net/forum/list_messages/1112077/ ) had je het al wel goed 8)7

[ Voor 22% gewijzigd door grhmpf op 16-02-2006 10:51 ]


Verwijderd

Topicstarter
grhmpf schreef op donderdag 16 februari 2006 @ 10:48:
Je append een int. Als je de char waarde wilt hebben moet je die casten in je append. Dus:

code:
1
2
rvc.append((char)chr);
rvc.append(",");


Je houdt hierbij geen rekening met mogelijke character encodings, maar zo lang de bron ascii is moet het wel goed gaan :)

edit: in je topic van gisteren (http://gathering.tweakers.net/forum/list_messages/1112077/ ) had je het al wel goed 8)7
ik append idd een int, dat is ook de bedoeling, als output wil ik gewoon de decimale waarde .. dat is geen probleem ( ben al wat wijzer dan gisteren ;) )

maar het feit is gewoon dat hij niet overweg kan met het feit dat de datastream al aan het sturen is, vooraleer het programma opgestart is ..

als ik de datastream start als het programma al runt, dan is er geen probleem ..

waaraan kan dit liggen?
bedankt!

Verwijderd

Topicstarter
Mss had ik m'n beginpost wat verkeerd geformuleerd ..

eventjes herproberen ;)

Het probleem gaat hem dus om een apparaat die iedere 2ms een string van 9 karakters doorstuurt naar een GSM Module die in j2me geprogrammeerd wordt. De string wordt voorafgegaan door een identifier die een soort ' case ' aanduid.
dus de module krijgt zoiets binnen '1abcdefghi2abcdefghi3abcdefghi4abcdefghi ( totaan 18 ) ' .. en dan wordt die ganse rij herhaald.
In de module wordt dit dan omgezet in HEX, en dan doorgestuurd naar een webpagina ( dit werkt al reeds )
een mogelijke output ( die opgeslagen wordt in de StringBuffer ) kan dit zijn '31616263646566768' ( waarbij dit dus allemaal hex waarden zijn = de eerste 31hex wil zeggen case 1 )
Nu zou dit moeten werken, enkel is er een probleem.

Als het javaprogramma nog niet gestart is, ligt die stream al aan de module .. dus er is al een datastream zonder dat er een java programma werkt.
Als ik het programma start, dan doorloopt ie z'n opstart procedure, en dan komt ie aan z'n Stringbuffer, maar daar steekt hij ipv de correcte hex-waarden allemaal verkeerde hex-waarden
in. bv 'FCE0E000E0E0E0E0E0FC1' .. ( allemaal rare waarden dus )

Doe ik hetzelfde, maar start ik eerst het programma op, en dan pas de stream aansteken, dan lukt dit wel.
( in de praktijk zal er dus constant data gestuurd worden, dus het zou moeten verholpen worden )

Java:
1
2
3
4
5
// een functie voor het omzetten naar hex
char ascii(char val){
   if(val<  9) return(char) (val | 0x30);
   else return (char)((val-9) | 0x40);
 }


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public void run () {
          System.out.println("runnen");
    try {
               
                System.out.println("connectie open");
                System.out.println(running);
                CommConnection connection = (CommConnection)Connector.open(CONNECTION, Connector.READ);
                in = new InputStreamReader (connection.openDataInputStream());
                StringBuffer rcv = new StringBuffer ();
                
    while (rcv.length() < 1000){ 
    try {

        int chr;
        char chl,chm;
        chr = in.read();
        chl = ascii((char) (chr & 0xf));
                     //   System.out.println(chl);
        chm = ascii((char) ((chr >> 4) & 0xf));
                        //        System.out.println(chm);
       
       
       rcv.append(chm).append(chl);
  
    }      
   
    catch (Exception e){
        e.printStackTrace();}
      
           }

           System.out.println(rcv);
           karakters = rcv.toString();
           System.out.println("omgezet in string");

           //upload(karakters);

    }
     
    catch (Exception e){
  e.printStackTrace();
    }
          System.out.println("Klaar");
  }

Bedankt!
Alexander

  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Het probleem lijkt dus dat je niet het begin van de stream kan vinden? Dan zal je daar een algo voor moeten maken om dat te vinden. Je zou bijvoorbeeld een paar keer die 18 bytes kunnen ontvangen, opslaan in een buffer en dan door steeds de offset te veranderen kijken of het een begin van de stream is. Als je goed aan het begin staat dan weet je ook waar het volgende bericht begint. Door de 'cases' te checken op geldige waardes moet dat wellicht lukken.

De data die je "ontvangt" voordat je j2me prog draait wordt waarschijnlijk gewoon geflushed naar niets.

Verwijderd

Topicstarter
Ik heb de oplossing gevonden, namelijk dit :

Java:
1
                in.skip(in.available());


dat zorgt ervoor dat je zeker een lege buffer hebt.

Nu weet ik dat de datastream een lengte heeft van 342 karakters.

Maar ik zou deze buffer bv dubbel zo groot maken ..
en daaruit zou ik het casenummer moeten uithalen, envanf daar 342 karakters verder tellen

dus in m'n buffer zoeken naar "00" waarbij er 16 karakters later een "01" staat .. als dit waar is moet hij vanaf die 00, 342 karakters verder tellen, en dan in een string opslaan ..

hoe zou ik dat best aanpakken?
alvast bedankt!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 08-04 02:18

Nick_S

++?????++ Out of Cheese Error

Je moet dus zorgen dat je een buffer (array) hebt, waar je 16 tekens in kwijt kan. Deze ga je vullen met tekens tot je er 16 hebt.

Dan ga je kijken of teken 1 "00" is en teken 16 "01" is, zo ja, you're lucky! ;)
Dan ga je verder lezen, je leest teken 17 in de array op plaats 17 mod 16 (oftewel plaats 1) en controleert of plaats 2 "00" is en plaats 1 "01" is.

Etc...

Heb je de goeie sequence gevonden, kun je de eerste 16 tekens op de goede plek in de nieuwe buffer van 342 tekens zetten (plaats 1 tot 16) en je stream verder lezen tot je buffer vol zit.

Dit is het even theoretisch, even geen tijd om het uit te werken en te testen.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

available is niet altijd beschikbaar, als het werkt heb je mazzel :) Skip doet niets anders dan bytes weg lezen eigenlijk.
Wat ik zou doen is zoiets als dit:
code:
1
2
byte[] buf = new byte[1024];
int read = in.read(buf);


in read staat dan het aantal gelezen bytes. Dan ga je in de byte array zoeken naar het begin van je stream. Heb je die gevonden dan kopieer je die bytes naar je stringbuffer en ga je op de normale manier verder met lezen van bytes zodra je alles uit je buffer hebt gevist. Misschien kom je erachter dat het toch niet het begin was van je stream (bijv als 00 in de data zit) en dan moet je dus je stringbuffer weer leeggooien en opnieuw beginnen.

Skip heeft niet zoveel nut omdat in principe direct na je skip er alweer bytes binnen kunnen komen die niet perse het begin van het bericht hoeven te zijn.

(Nick en Ik zijn het eens :))

Verwijderd

Topicstarter
ik ben nu aan het programmeren geslagen om proberen de juiste sequentie te vinden uit m'n binnengekomen data ..


ik moet dus op zoek gaan naar een " 00 , waarbij er 18 plaatsen verder een 01 zit, nog eens 18 plaatsen verder een 03 " .. als dit goed is, moet ie 324 plaatsen in de buffer steken vanaf die 00 "

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    try {
        chr = in.read(); // inlezen van de inputStream
        switch (++teller){
            
            case 1: // case id verwacht
                if(chr == casenummer){   // synchronisatie OK
                 buffer(chr);   // in de buffer steken via een zelfgemaakte functie
                }
                else{ // synchronisatie nt OK
                    teller=0;
                    casenummer=0;
                    rcv.delete(0,342);
                }
                break;
                
            case 9: // laatste data klaarzetten voor volgende case
                teller =0;
                if(++casenummer == maxcase){
                    casenummer=0;
                }
                
            default : // data
                buffer(chr);      // in de buffer steken via een zelfgemaakte functie
   
        } 


het probleem is dat dat de buffer dus nooit gevuld wordt?
bedankt!
Pagina: 1