Microcontrollerantwort mit X-Port Java Applet auswerten

Gast #1764841
Lesenswert?

Hallo,

habe folgendes Problem:
Über ein Applet auf einem X-Port gebe ich einen ATmega1281v Befehle. 
Wenn der uC diese ausführt sendet er eine Antwort (z.B. COMMIT_C_OKAY). 
Diese Antwort wiederrum wird vom Java-Applet in einer Text Area 
angezeigt.

Eine dieser Antworten vom uC enthält Zeichen die vom Applet nicht 
dargestellt werden können, weshalb ich diese Antwort abfange und in 
hexadezimale Darstellung konvertiere. Diese wird dann in Text Area 
ausgegeben.

Das funktioniert auch einige Male (ca 17 Mal) ganz gut. Irgendwann 
werden keine Antworten des uCs mehr angezeigt. Der uC lässt sich 
allerdings weiterhin steuern.

Ich vermute mal, dass es am Puffer liegen könnte.

Hier mal der Empfangsteil des Codes:
1
// print received data on text area
2
  public void run()
3
  {
4
      //int test;
5
    Thread me = Thread.currentThread();
6
      while (timer == me) {
7
        int i;
8
      
9
          try {
10
              Thread.currentThread().sleep(200);
11
          } catch (InterruptedException e) { }
12
          if ( (gtp != null) && ((i = gtp.available()) > 0) ) {
13
          
14
        String received;
15
        byte[] in = new byte[100];
16
        
17
        in = gtp.receive();                      // write received bytes in in[]
18
        received = new String(in);                  // covert byte[] to string
19
        Ringbuffer ring = new Ringbuffer(200);
20
        // if it's a response to a GET_CONF-command (GET_CONF_OKAY_), convert received frame to hex than display it in the text area
21
        if((in[0]== 0x47) && (in[1]== 0x45) && (in[2]== 0x54) && (in[3] == 0x5F) && (in[4] == 0x43) && (in[5] == 0x4F) && (in[6] == 0x4E) && 
22
           (in[7]== 0x46) && (in[8]== 0x5F) && (in[9]== 0x4F) && (in[10]== 0x4B) && (in[11]== 0x41) && (in[12]== 0x59) && (in[13]== 0x5F))
23
        {            
24
          String tempStringBuffer = "GET_CONF_OKAY_(";      // write prelude of the response
25
          
26
          // config frame data from in[14] to in[length-2]
27
          for(int j = 14; j < in.length-2; j++) 
28
          {
29
            String temp = Integer.toHexString(in[j] & 0xFF);   // convert the byte array to a string of hexadecimal bytes
30
            if (temp.length() < 2)
31
            {
32
              tempStringBuffer += "0";            // if hex number consists of only one digit, add a '0' in front of the value
33
            }
34
            tempStringBuffer += temp;              // write converted hex to output string
35
            tempStringBuffer += " ";              // divider between the hexadecimal byte blocks
36
          }
37
          tempStringBuffer += ")\n\r";              // conclusion of config frame with additional "line feed" and "carriage return" symbol
38
          
39
          textArea.append(tempStringBuffer);            // print string in text area
40
                    textArea.setCaretPosition(textArea.getText().length());  // view always last row in text area
41
        }
42
        // for every uC response of a command, except the GET_CONFIG command
43
        else
44
        {
45
          textArea.append(received);                // print received string in text area
46
          textArea.setCaretPosition(textArea.getText().length()); // view always last row in text area
47
        }
48
        //java.util.Arrays.fill(in, 0); 
49
        received = "";
50
      }
51
      }
52
  }

Vielleicht habt ihr ja eine Idee
Vieln Dank im Voraus...
Gast #1765181
Lesenswert?

Aus
1
byte[] in = new byte[100];
2
in = gtp.receive();                      
3
received = new String(in);

würde ich erstmal
1
received = new String(gtp.receive());

machen.

Ist vermutlich nicht der Grund, sprang mir aber ins Auge... ^^

Generell würde ich Dir empfehlen den Code mal aufzuräumen und zu 
entrümpeln.
Was macht z.B. der Ringbuffer da? Wird nicht weiter verwendet oder?

Und wenn ich mir die if-clause anschaue krieg ich gaaanz große Augen:
Du fragst tatsächlich manuell und hexadezimal ab, ob der empfangene 
String mit "GET_CONF_OK_" anfängt?!? oO
Wie wäre es mit
1
if(received.startsWith("GET_CONF_OK_"){
2
    ....
3
}

Welcher Puffer wo genau überläuft lässt sich anhand des Code-Snippets eh 
nicht genau sagen.
In dem Teil den Du gepostet hast sollte es eigentlich zu keinen 
Problemen mit dem Puffer kommen.

Kann es evtl. sein, dass der Thread einfach zu macht?
Also z.B. timer != me wird?
Gast #1765204
Lesenswert?

Ich nochmal.

Schau Dir mal das folgende Snippet an, vllt. hilft es ja weiter... ;)
1
  public static void main (String[] args) {
2

3
    String received = "GET_CONF_OKAY_7832z4";
4
    String output = null;
5

6
    if(received.startsWith("GET_CONF_OKAY_")){
7
      String payload = received.substring("GET_CONF_OKAY_".length(), received.length());
8
      output = "GET_CONF_OKAY_";
9
      for(int i = 0; i < payload.length(); i++){
10
        output += "0x" + StringUtils.leftPad(Integer.toHexString(payload.charAt(i)), 2, '0') + "_";
11
      }
12
    }
13
    System.out.println(output.substring(0, output.length()-1));
14
  }

StringUtils sind Teil des Apache commons Projekts.
Gast #1765893
Lesenswert?

Hallo,
gibt es eine Möglichkeit mit Java Strings "Interrupt gesteuert" 
einzulesen. Durch die Abfrage alle 200ms werden manche Antwort-Strings 
in meinem Programm zusammengesetzt. Gibt es eine Möglichkeit diese auch 
einzeln auszulesen?
Gast #1766039
Lesenswert?

Die receive()-Methode hat keinen Puffer.
Wenn ich das sleep rausnehme, kommen die einzelnen Pakete zerstückelt 
an.

Am Ende jedes Pakets ist noch "\n\r" angehängt. Wie kann ich einen 
Puffer implementieren, der immer wenn diese Zeichen kommen, den String 
zur hex-Umwandlung schickt?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren