2

J'ai écrit un écouteur d'événement supposé lire tous les messages d'un type spécifique d'un récepteur.attraper <CR><LF> dans un tableau d'octets

ici est mon écouteur d'événement:

class SerialPortReader implements SerialPortEventListener { 
    public void serialEvent(SerialPortEvent event) { 
     if (event.isRXCHAR() && event.getEventValue() > 0) {   
      try { 
       byte[] buffer = SP.readBytes(6); 
       String type = new String(buffer); 
       if (type.equals("$GPGGA")){ 
        String line = ""; 
        line = line + type; 
        buffer = SP.readBytes(66); 
        String values = new String(buffer); 
        line = line + values; 
        writer.write(line + "\n"); 
       } 
      } 
      catch (SerialPortException ex) {System.out.println(ex);} 
      catch (IOException ex) {System.out.println(ex);} 
     } 
    } 
} 

en ce moment après je vérifie que le message est du type correct, je viens de lire 80 octets de données, ce qui est à peu près la taille du message. Cependant, parfois le message n'est pas plein et là, il est plus court que d'habitude. c'est la structure du message: enter image description here

comme vous pouvez le voir, s avec <CR><FL> la fin du message. Je voudrais modifier ma méthode afin qu'elle lise chaque octet à la fois et arrête de lire une fois qu'elle a atteint la fin du message. comment puis-je attraper le <CR><FL> à l'intérieur du tableau d'octets?

toute aide serait appréciée. Je vous remercie.

+0

Quel type est 'SP'? S'il s'agit d'un InputStream, vous pouvez l'insérer dans un [BufferedReader] (https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()) et appeler readLine? – Fildor

+0

SP est un port série. Cette méthode fait partie d'un programme plus grand qui communique avec un récepteur GPS via un port série. Je ne peux pas appeler readLine car les données circulent depuis le récepteur sous forme d'octets. –

Répondre

2

Cela dépend de la définition de "messages": sont-ils de longueur fixe ou délimités par une certaine séquence? Dans votre code actuel, vous lisez un "en-tête" de 6 octets et un "message" de 66 octets. Cependant, il semble que vous ne connaissiez pas la longueur a priori, et que le message se termine par un retour à la ligne. Un couple de pointeurs:

  • Vous lisez des octets du flux, puis vous les transformez en chaîne à l'aide du ctor String(byte[]). Le documentation indique que cela utilise le default charset pour votre plate-forme, qui peut être UTF-8, Latin-1 ou n'importe quelle autre région par défaut. Si vous communiquez avec un périphérique via un port série, ce n'est probablement pas ce que vous voulez car le périphérique est susceptible d'avoir un jeu de caractères unique et spécifique pour les messages (peut-être ASCII?). Recherchez ce point et utilisez this String ctor ou, si vous voulez être averti lorsque l'entrée contient des déchets non décodables, CharsetDecoder class.
  • Si les messages sont basés sur le texte et délimités par un saut de ligne, vous devez absolument utiliser un BufferedReader pour lire dans le flux. En supposant que votre port série SP est un InputStream, vous pouvez créer un BufferedReader dessus, puis appeler la méthode readLine() sur le lecteur. Le lecteur continuera à demander des octets à partir du flux jusqu'à ce qu'il voit un saut de ligne, puis retourner la ligne entière à vous en tant que chaîne. Les objets du lecteur encapsulent également le jeu de caractères dont je parlais avant.
+0

vous avez raison, je ne connais pas la longueur apriori du message, seulement si le message est plein. votre deuxième bulletin ressemble à la bonne façon pour moi. Je vais essayer ça plus tard. Je vous remercie. –

+0

le fournisseur de service déclaré comme «public static SerialPort SP» au début d'une autre classe.il n'y a pas de déclenchements de flux d'entrée n'importe où. Je ne comprends pas très bien comment créer un BufferedReader. @Javier Martin pourriez-vous me donner un exemple? Je pensais que je pourrais vérifier la valeur de l'octet, '' devrait être 13 et '' est 10, ou vice versa. ça marcherait? –

+0

@DanyLavrov 'SerialPort' ne semble pas être le javax.comm.SerialPort, non? Pouvez-vous nous dire quelle bibliothèque vous utilisez? – Fildor

0

J'ai réussi à résoudre mon problème. solution assez facile:

String tmp = SP.readString(); 
String[] msgs = tmp.split("\r\n"); 

après avoir lu la chaîne à partir du port série, je fendus par la fin de la ligne.