Pessoal tenho um problema que está difícil de encontrar solução. Tenho um balança que no Hyperterminal ele vem da seguinte forma:
(STX)p´0000253000 (essa é a forma descrita no manual)
Porém quando conecto pelo Java (de acordo com o tuturial do GUJ) essa string vem toda quebrada, algo do tipo:
(STX)
p´
002
53
0000
É alguma falha na hora de coletar os dados? Será problema da própria API (eu uso a RXTX)?
O chip de interface serial (normalmente compatível com INS 16550) contém um buffer de recepção de 8 ou 16 bytes. (Depende um pouco da compatibilidade do chip: se ele for compatível com 8250, o seu buffer é de apenas 8 bytes.)
Quando esse buffer enche, ou então por timeout, uma interrupção de hardware é gerada, que faz com que o device driver do Windows ou do Linux leia o valor desse buffer. (E é por isso que
Isso quer dizer que os dados chegarão “em pedaços” e você é que precisa analisar para saber quando eles terminam: no seu caso, provavelmente você vai ter de pegar um byte de cada vez, até chegar ao ETX ou LF. Ou então, o que também pode ocorrer, é supor que os seus dados (a partir do STX) vão chegar todos dentro de 0,7 segundos (digamos), e você pega apenas os dados que chegarem dentro desse tempo.
Cara, aumentei o meu timeout para 999999999 (o máximo para um int) antes pegava sempre 2 bytes por linha e agora em alguns casos pega 4 bytes. Tem como eu alterar um int para ser maior que o citado acima? Tentei com BigInteger e não ceu certo.
Outra coisa vc diz em pegar byte a byte analisar até o ETX. Desculpe pela ignorancia mas não sei nem por onde começar a fazer isso (creio que essa seja a solução mais refinada e indicada para o caso). Vc tem alguma fonte de onde eu posso aprender a fazer isso pegar byte por byte até um determinado byte? Fiquei boiando legal.
Vc em outra ocasião também mandou uma rotina para imprimir um array de bytes, usei ela e também ocorre o mesmo, vem tudo dividido em várias linhas.
A entrada serial é uma InputStream, portanto você pode ler um byte de cada vez, usando read().
Não converta logo de cara para uma String, já que você quer ler só bytes.
Quando se usa interface serial, só converta para String depois que você já analisou tudo.
Humm, muito interassante isso que vc falou, só mais uma pergunta idiota, vamos supor que eu faço um laço (por exemplo) que fique lendo com read(), como eu faço para identificar o byte que virá com ETX ou LF para finalizar a captura e então converter para String?
Para juntar os bytes, use um vetor de bytes. (Acho que você sabe usar arrays e vetores, já que está lidando com comunicação serial)
A seguir, converta-os com o construtor da classe String que recebe um array de bytes. (Provavelmente você terá de especificar o início e a quantidade de bytes a serem convertidos, já que vai querer limpar a String da sujeira que veio - STX, ETX e outras coisas esquisitas.)
Certo, como sou novato em Java estou meio enrolado aqui, eu fiz o seguinte:
criei um Array de bytes mas não consigo jogar nessa Array o valor dos bytes, na verdade consigo conta-los e vejo que vão normalmente 2 de cada vez.
O meu método é o seguinte:
public void serialEvent(SerialPortEvent ev){
switch (ev.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] bufferLeitura = new byte[16];
try {
while ( entrada.available() > 0 ) {
nodeBytes = entrada.read(bufferLeitura);
}
String Dadoslidos = new String(bufferLeitura);
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Erro durante leitura! STATUS: " + e,
"Erro!",
JOptionPane.ERROR_MESSAGE);
System.out.println("Erro durante a leitura: " + e );
}
System.out.println("n.o de bytes lidos : " + nodeBytes );
break;
}
}
Oi, tambem to pegando dados de balança.
Eu usei o codigo abaixo pra detectar o \n e pegar sem quebra, porem a velocidade
diminuiu, fico pegando dados de duas placas simultaneamente mas tem vezes que ele pula e vem em branco. Mas talvez no seu caso que é só nao quebrar ajude.
Segue o codigo:
Cara tentei implementar esse seu exemplo mas aqui não imprimiu nada, como vc consegue pegar os dados de balança sem quebrar v se vc consegue dar uma luz que só falta isso para eu liberar um app:
O método que imprime o dados da minha balança é o seguinte:
public void serialEvent(SerialPortEvent ev){
switch (ev.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] bufferLeitura = new byte[16];
try {
while ( entrada.available() > 0 ) {
nodeBytes = entrada.read(bufferLeitura);
}
String Dadoslidos = new String(bufferLeitura);
if (bufferLeitura.length == 0) {
System.out.println("Nada lido!");
} else if (bufferLeitura.length == 1 ){
System.out.println("Apenas um byte foi lido!");
} else {
System.out.println(Dadoslidos);
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Erro durante leitura! STATUS: " + e,
"Erro!",
JOptionPane.ERROR_MESSAGE);
System.out.println("Erro durante a leitura: " + e );
}
System.out.println("n.o de bytes lidos : " + nodeBytes );
break;
}
}
Se eu faço como acima, dando um System para imprimir o Dadoslidos o retorno que obtenho é o seguinte:
p`
00
17
40
00
00
00
Se eu uso o hyperterminal isso sai tudo em uma única linha. Só no Java que o negócio tá quebrando tudo aqui.
O peso tá vindo certo (1740) só que vai quebrado. Só preciso de um jeito de capturar tudo junto.
Será que vc pode dar um help?