Como juntar bytes lidos na Comunicação serial

[b]Saudações pessoal!

Estou fazendo um TC de Rfid e estou utilizando uma classe de comunicação serial da SUN
O dispositivo esta comunicando tudo certinho, consigo escrever e ler dados dele atraves desta classe , o problema é o seguinte… a classe esta lendo byte por byte na qual estou convertendo para string, se o dispositivo ler uma informação tipo “1nGU” a classe ira me retornar palavra por palavra, sendo assim eu não consigo fazer nenhum if ou grava-la em um banco de dados
Gostaria de saber se não tem como eu ler ou somar todos esses bytes para uma palavra só. abaixo esta o codigo ques estou utilizando:[/b]

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TwoWaySerialComm {

    public TwoWaySerialComm() {
        super();
    }

    void connect(String portName) throws Exception {
        CommPortIdentifier portIdentifier =
                CommPortIdentifier.getPortIdentifier(portName);
        if (portIdentifier.isCurrentlyOwned()) {
            System.out.println("Error: `port is currently in use");
        } else {
            CommPort commPort =
                    portIdentifier.open(this.getClass().getName(), 2000);

            if (commPort instanceof SerialPort) {
                SerialPort serialPort = (SerialPort) commPort;

                serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

                OutputStream out = serialPort.getOutputStream();
                InputStream in = serialPort.getInputStream();

             //   InputStream in = serialPort.getInputStream();

                 (new Thread(new SerialWriter(out))).start();
               (new Thread(new SerialReader(in))).start();
               
            } else {
                System.out.println("Error: only serial ports are handled by this example.");
            }
        }
    }

    public static class SerialReader implements Runnable {

        InputStream in;

        public SerialReader(InputStream in) {
            this.in = in;
        }

        public void run() {
            byte[] buffer = new byte[1024];
            int len = -1;

            try {
                while ((len = this.in.read(buffer)) > -1) {                      //<------------ Aqui estou contando quandos bytes que tem no buffer se não 
                                                                                                //                   haver byte nenhum o read me retorna -1 e sai do laço                   
                       String ler = (new String(buffer,0 ,len));                //<--------------Aqui estou convertendo para String e zerando o buffer
                       System.out.println(ler);                                      //<---------- A informação que é pra vir eh "1nGU" acada 2,5seg se eu tirar 
                                                                                              //                  o "ln" ele me imprime assim :1nGU 1nGU 1nGU 1nGU, se eu deixar "ln" 
                                                                                              //                  imprime assim: 1
                                                                                              //                                         n
                                                                                             //                                          G
                                                                                             //                                          U
                }
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static class SerialWriter implements Runnable {

        OutputStream out;

        public SerialWriter(OutputStream out) {
            this.out = out;
        }

        public void run() {
            try {
                int c = 0;
                while ((c = System.in.read()) > -1) {
                    this.out.write(c);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Se alguem puder ajudar eu agradeço muito ! :frowning:

  1. Não converta a o buffer numa String. Como a classe String tem encoding, a menos que os dados sejam mesmo texto, você não deveria fazer isso! No lugar use arrays de ints ou a classe ByteBuffer.

  2. Você pode juntar bytes usando operadores bitwise, por exemplo:

[code]
int b1 = 10; //Byte 1, em binário 00001010
int b2 = 127; //Byte 2, em binário 01111111

//Afasta b1 8 bits para direita e preenche o conteúdo com b2.
int valor = b1 << 8 | b2; //2687, Valor em binário: 00001010 01111111[/code]

[quote=ViniGodoy]1. Não converta a o buffer numa String. Como a classe String tem encoding, a menos que os dados sejam mesmo texto, você não deveria fazer isso! No lugar use arrays de ints ou a classe ByteBuffer.

  1. Você pode juntar bytes usando operadores bitwise, por exemplo:

[code]
int b1 = 10; //Byte 1, em binário 00001010
int b2 = 127; //Byte 2, em binário 01111111

//Afasta b1 8 bits para direita e preenche o conteúdo com b2.
int valor = b1 << 8 | b2; //2687, Valor em binário: 00001010 01111111[/code][/quote]

Obrigado pela resposta Vini, sobre esse codigo que vc passou você pode me dize como eu implemento ele na minha classe, pois não entendi porque vc definio aqueles valores para b1 e b2

Agradeço a atenção

Eu defini quaisquer valores. Só para te mostrar como a operação funciona.
Preste atenção nos bits.

[quote=ViniGodoy]Eu defini quaisquer valores. Só para te mostrar como a operação funciona.
Preste atenção nos bits.[/quote]

Ah entendi Vini… mais isso daria certo se eu soubesse oque eu estou lendo não eh? mais eu não sei pois o leitor lê varias Tags e cada uma tem um nome

consegui agora esse jeito :

[code]
byte[] buffer = new byte[4096];
int len = -1;

        ByteArrayOutputStream out2 = new ByteArrayOutputStream();
        try {

            while ((len = this.in.read(buffer, 0, buffer.length)) != -1) {
                out2.write(buffer, 0, len);


                buffer = out2.toByteArray();
                String valor = new String(buffer);
                System.out.println("String lida: " + valor);
            }
 [/code]

So tem um problema agora com esse codigo, ele não esta zerando o buffer, tem algum jeito de zerar o buffer do out2.toByteArray() quando para de receber bytes do this.in.read ??

Agradeço pelas respostas Vini!

Mas o que exatamente você quer fazer? Pq se vc não sabe o protocolo envolvido na comunicação, fica difícil te ajudar.

A serial está te enviando Strings ou dados Binários? Se for Strings, não tem sentido falar em juntar bytes. Basta ir montando as strings com os bytes e concatenando num buffer, ou exibindo na tela. Para isso, é só usar um Append de um StringBuilder no lugar daquele println, e retornar esse StringBuilder quando encontrar um \n (ou outro terminador, definido pelo protocolo). Como vc pode observar no seu print, a informação chega aos poucos e isso é perfeitamente normal.

Se for dados binários, é imprescindível que você conheça o protocolo.

Primeiro como o Vinny mesmo disse procure nos apresentar o protocolo.

Segundo você pode utilizar o método read da classe InputStream que te retorna o decimal do caracter, dessa forma vc lê todos os caracteres e com base no protocolo junta em uma palavra apenas.

Mas o que exatamente você quer fazer? Pq se vc não sabe o protocolo envolvido na comunicação, fica difícil te ajudar.

A serial está te enviando Strings ou dados Binários? Se for Strings, não tem sentido falar em juntar bytes. Basta ir montando as strings com os bytes e concatenando num buffer, ou exibindo na tela. Para isso, é só usar um Append de um StringBuilder no lugar daquele println, e retornar esse StringBuilder quando encontrar um \n (ou outro terminador, definido pelo protocolo). Como vc pode observar no seu print, a informação chega aos poucos e isso é perfeitamente normal.

Se for dados binários, é imprescindível que você conheça o protocolo.[/quote]

Então Vini, oque eu sei é o seguinte este dispositivo se eu conecta-lo no hyperterminal ele fica me dando as strings prontas que no caso são as indentificações(id, ex: 1nGU) dos transmissores que estão no alcance, ele me da os id destes transmissores acada 2,5seg. Acredito que a serial esta me enviando Strings me fale mais sobre esse append de um StringBuilder , acredito que de certo pq quando acaba o envio de Strings ele encontra um \n

Obrigado !

Seu método deve ficar mais ou menos assim, então:

[code]public void run() {
byte[] buffer = new byte[1024];
int len = -1;

try {
	StringBuilder sb = new StringBuilder();
	while ((len = this.in.read(buffer)) &gt; -1) {
		for (int i = 0; i &lt; len; i++) {
			char ch = (char)buffer[i];
			sb.append(ch);
			if (ch == '\n') {
				processarLinha(sb.toString());
				sb = new StringBuilder();
			}
		}
	}
	
} catch (IOException e) {
	e.printStackTrace();
}

}

public void processarLinha(String linha) {
System.out.printf("Linha lida: %s%n", linha);
}[/code]

[quote=ViniGodoy]Seu método deve ficar mais ou menos assim, então:

[code]public void run() {
byte[] buffer = new byte[1024];
int len = -1;

try {
	StringBuilder sb = new StringBuilder();
	while ((len = this.in.read(buffer)) &gt; -1) {
		for (int i = 0; i &lt; len; i++) {
			char ch = (char)buffer[i];
			sb.append(ch);
			if (ch == '\n') {
				processarLinha(sb.toString());
				sb = new StringBuilder();
			}
		}
	}
	
} catch (IOException e) {
	e.printStackTrace();
}

}

public void processarLinha(String linha) {
System.out.printf("Linha lida: %s%n", linha);
}[/code][/quote]

Deu certo cara !!
So tive que muda o (ch == '\n') para (ch == ' ') pois não esta dando com \n
Tem como tirar o \n do objeto linha, pois ele esta escrevendo e dando um espaço?

Vini Brigadão cara, vc me ajudo muito , Abraço!!