Para quem conhece rxtx ou javax.comm

Fala galera,

Comecei a usar a pouco tempo a API RxTx para leitura de dados da porta serial do computador. Estou desenvolvendo uma aplicação simples que precisa ler dados de uma balança Toledo, dessas de pesar caminhão.

Primeiro fui ate a balanca e conectei o laptop nela atraves do cabo serial, e atraves do Hyperterminal, consegui colher alguns dados que sao enviados.

Importante que observei que esse tipo de balanca fica enviando constantemente a string com o valor da pesagem para o computador, em media 6x por segundo.

Para desenvolver utilizei dois computadores ligados por um cabo serial. Um dos computadores esta simulando a balanca toledo, pois a balanca esta em Vitoria/ES e eu estou no interior de SP, nao tenho como desenvolver o software la. Criei entao um simulador que gera uma String parecida com a gerada pela balanca e fica enviando essa string 6x por segundo.

O Outro computador recebe os dados enviados pelo computador simulador, e faz a leitura da string e os tratamentos necessarios para apresentar o peso.

Bom, para quem conhece javax.comm sabe que existe uma interface chamada SerialPortEventListener, se eu tenho uma classe que implementa essa classe entao tenho que implementar o metodo serialEvent. Esse metodo e disparado sempre que ocorre algum evento na porta serial do computador que esta recebendo os dados.

No meu caso isso esta ocorrendo porem estou com problemas nessa parte.

Para testar o mecanismo criei a seguinte string abcdefghijklmnopqrstuvxyz1234567890 e essa esta sendo enviada 6x por segundo pelo computador simulador.

No receptor existe o seguinte implementacao no metodo serialEvent:

   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: 
            try { 
               byte[] buffer = new byte[in.available()]; 
               in.read(buffer); 
               System.out.println("RXTX:" + new String(buffer)); 
            } catch (IOException e) { 
               e.printStackTrace(); 
            } 
      } 
   } 

A minha intencao e simplesmente imprimir a mesma string que estou enviando do computador simulador, no console do computador receptor.

E eu imagina que o RxTx iria gerar apenas um unico evento para receber toda a String, mas nao e isso que esta acontecendo.

Por incressa que parivel, olha a resposta que eu estou obtendo no console

[list]
Stable Library

Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
RXTX:efghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567
RXTX:890
RXTX:abcdefghijklmnop
RXTX:qrstuvxy
RXTX:z1234567890
RXTX:abcdefgh
RXTX:ijklmnopqrstuvxyz1234567890
RXTX:abcdefgh
RXTX:ijklmnopqrstuvxy
RXTX:z1234567890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567
RXTX:890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567890
RXTX:abcdefgh
RXTX:ijklmnopqrstuvxy
RXTX:z1234567890
RXTX:abcdefgh
RXTX:ijklmnop
RXTX:qrstuvxyz1234567890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567
RXTX:890
RXTX:abcdefghijklmnop
RXTX:qrstuvxyz1234567
RXTX:890
[/list]

Perceba que cada minha com pre-fixo RXTX e um evento que esta sendo tratado pelo programa receptor.

Assim ta muito longe de ser uma solucao pois eu esperava o seguinte resultado.

[list]
Stable Library

Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
RXTX:abcdefghijklmnopqrstuvxyz1234567890
[/list]

O que eu percebi ate agora e que o Rxtx cria varios eventos para a mesma string, enviando ela em pedacos o que confunde meu codigo.

Alguem saberia me dizer como eu faco, para que o rxtx notifique apenas um evento para cada string???

Se alguem souber e puder colaborar eu agradeco muito.

Abraco

Não tem como; isso é porque ele pega o buffer da porta serial (INS16550? não sei mais os nomes dos chips) que normalmente tem 8 ou 16 bytes, e a cada interrupção de hardware (ou timeout) ele gera esse tal evento de leitura.
(Se você percebeu, “abcdefghijklmnop” tem 16 bytes, e “abcdefgh” tem 8)

Uma coisa que eu fiz em um programa que escrevi (não estou mais com o fonte dele aqui) é verificar (usando System.currentTimeMillis()) qual foi o tempo em que a primeira parte da mensagem chegou, e ir acumulando todos os dados que chegaram até que se passasse um determinado tempo (digamos 500 ms), ou então quando recebesse um determinado terminador (digamos LF - depende da configuração do seu dispositivo serial).

Esse problema não é só do rxtx ou do JavaComm; isso pode ocorrer com outras bibliotecas que lêem dados pela serial.

Amigo eu precisaria de algo parecido, preciso conectar minha linha telefonica no meu micro, e o modem atender a ligação e receber os caracteres que for digitado no telefone, Alguem tem um exemplo?
Obrigado.

Amigo eu precisaria de algo parecido, preciso conectar minha linha telefonica no meu micro, e o modem atender a ligação e receber os caracteres que for digitado no telefone, Alguem tem um exemplo?
Obrigado.

[quote=thingol]Não tem como; isso é porque ele pega o buffer da porta serial (INS16550? não sei mais os nomes dos chips) que normalmente tem 8 ou 16 bytes, e a cada interrupção de hardware (ou timeout) ele gera esse tal evento de leitura.
(Se você percebeu, “abcdefghijklmnop” tem 16 bytes, e “abcdefgh” tem 8)

Uma coisa que eu fiz em um programa que escrevi (não estou mais com o fonte dele aqui) é verificar (usando System.currentTimeMillis()) qual foi o tempo em que a primeira parte da mensagem chegou, e ir acumulando todos os dados que chegaram até que se passasse um determinado tempo (digamos 500 ms), ou então quando recebesse um determinado terminador (digamos LF - depende da configuração do seu dispositivo serial).

Esse problema não é só do rxtx ou do JavaComm; isso pode ocorrer com outras bibliotecas que lêem dados pela serial.
[/quote]

Resolvi em parte o problema

				try {
					byte[] buffer = new byte[35];
					in.read(buffer,0,35);
					System.out.println("RXTX:" + new String(buffer));
				} catch (IOException e) {
					e.printStackTrace();
				} 

Agora estou forçando o InputStream a ler apenas 35 bytes, e então tenho uma espécie de Fila aqui, onde a API vai armazendando os bytes e minha aplicaçào vai lendo de 35 em 35 bytes.

Isso até funcionou mais ainda assim ocasionalmente eu estou tendo um outro problema na resposta, dêem uma olhada nisso:

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123
RXTX:4567890abcdefghijklmnopqrstuvxyz123

Ja deu pra entender o que esta acontecendo agora né!!!

Ele perde o sincronismo, porque o dispositivo que esta ligado ao computador é independente, ou seja, eu não tenho como enviar um sinal para o dispositivo autorizante ele a enviar os dados, ele fica enviando a todo momento, assim não tem como eu manter o sincronismo.

Nossa ta complicado isso aqui. Se alguem tiver alguma dica…

[quote=MikeMonteiro]Amigo eu precisaria de algo parecido, preciso conectar minha linha telefonica no meu micro, e o modem atender a ligação e receber os caracteres que for digitado no telefone, Alguem tem um exemplo?
Obrigado.
[/quote]

Nao tenho exemplo, mas o que vc precisa e mais simples do que o meu problema hahahahaha…

A comunicacao com Modem pela porta serial e realizada atraves de comandos que vc consegue controlar o fluxo de execucao, vc apenas precisa pegar a documentacao do modem para saber que tipo de dados deve enviar e que tipo de informacao recebera.

Você tem a especificação da tal balança?
Provavelmente ela manda uma mensagem que inicia com um caracter especial (talvez STX = (char)03) e termina com um caracter especial (talvez ETX = (char)04).
Ou então ela lhe manda uma mensagem que termina com LF ((char) 10).
Além disso ela não deve lhe mandar 6 mensagens por segundo (no máximo 1 mensagem por pesagem!)
Infelizmente não lidei com essa balança, mas normalmente dispositivos com interface serial trabalham dessa forma.
Vá ao site da Toledo, baixe o manual, se estiver disponível (ou telefone para alguém de lá - !), e veja o que a tal balança faz.
Não faça um simulador “meia boca”. Faça as coisas direito :stuck_out_tongue:

[quote=thingol]Você tem a especificação da tal balança?
Provavelmente ela manda uma mensagem que inicia com um caracter especial (talvez STX = (char)03) e termina com um caracter especial (talvez ETX = (char)04).
Ou então ela lhe manda uma mensagem que termina com LF ((char) 10).
Além disso ela não deve lhe mandar 6 mensagens por segundo (no máximo 1 mensagem por pesagem!)
Infelizmente não lidei com essa balança, mas normalmente dispositivos com interface serial trabalham dessa forma.
Vá ao site da Toledo, baixe o manual, se estiver disponível (ou telefone para alguém de lá - !), e veja o que a tal balança faz.
Não faça um simulador “meia boca”. Faça as coisas direito :stuck_out_tongue:
[/quote]

Ola thingol,

Obrigado pela dicas, mas ainda não cheguei nesse ponto não, antes de entender o protocolo, etc… preciso entender bem como essa API esta trabalhando para ver se realmente é confiável e se vai atender minhas necessidades no futuro.

Mas valew mesmo assim.

[quote=oswaldo.neto][quote=thingol]Você tem a especificação da tal balança?
Provavelmente ela manda uma mensagem que inicia com um caracter especial (talvez STX = (char)03) e termina com um caracter especial (talvez ETX = (char)04).
Ou então ela lhe manda uma mensagem que termina com LF ((char) 10).
Além disso ela não deve lhe mandar 6 mensagens por segundo (no máximo 1 mensagem por pesagem!)
Infelizmente não lidei com essa balança, mas normalmente dispositivos com interface serial trabalham dessa forma.
Vá ao site da Toledo, baixe o manual, se estiver disponível (ou telefone para alguém de lá - !), e veja o que a tal balança faz.
Não faça um simulador “meia boca”. Faça as coisas direito :stuck_out_tongue:
[/quote]

Ola thingol,

Obrigado pela dicas, mas ainda não cheguei nesse ponto não, antes de entender o protocolo, etc… preciso entender bem como essa API esta trabalhando para ver se realmente é confiável e se vai atender minhas necessidades no futuro.

Mas valew mesmo assim.
[/quote]

Só complementando manda 6x por segundo o peso SIM, não é como as balanças de supermercado, é uma balança industrial.

De qualquer maneira, não sei se ajuda alguma coisa:
http://www.toledobrasil.com.br/suporte/manuais.asp

Lendo um dos manuais parece que existem 5 protocolos (P01, P02, … P05). Não sei qual o modelo de sua balança, por isso é interessante consultar o pessoal da Engenharia de Soluções da Toledo.

Achei na Internet um arquivo com o nome Projeto_Toledo_P03.zip. É um programa em Delphi que simula uma balança Toledo usando o protocolo P03. Nele há um PDF - “Artigo TheClub Balanca Toledo.pdf” com a descrição e explicação do protocolo, e um Simulador_P03_Demo.exe - não sei o que ele faz. Mas dê uma procuradinha http://www.igara.com.br/downloads/toledo_p03/projeto_toledo_p03.zip

Legal o programa, valeu pela dica, de qualquer maneira a minha ideia de criar um simulador de balanca nao era de todo ruim.

:slight_smile:

[quote=thingol]De qualquer maneira, não sei se ajuda alguma coisa:
http://www.toledobrasil.com.br/suporte/manuais.asp

Lendo um dos manuais parece que existem 5 protocolos (P01, P02, … P05). Não sei qual o modelo de sua balança, por isso é interessante consultar o pessoal da Engenharia de Soluções da Toledo.[/quote]

Otimo cara…

Acabei de baixar alguns manuais, era realmente isso que eu estava precisando. O protocolo que eu estou utilizando é o P03, e agora com a documentação vai ficar tudo bem mais fácil.

Agora só preciso mesmo é entender um pouco mais essa API RxTx e ver como posso resolver o meu problema…

Na verdade ja tenho uma solucao na cabeça baseado no que voce falou e na documentacao da Toledo, a balança realmente envia um caracter STX = 02H como inicio de texto, assim posso criar uma logica para pegar a partir desse caracter + 17 bytes e vou ter o que eu preciso.

Valew pelas dicas amigo.

Provavelmente, no caso da balança toledo, você pode configurar ela pra ela mandar um STX no começo e um ETX no fim do conjunto de bytes. Aí não tem erro, você lê até chegar o ETX, sem se preocupar com o tempo…

Falou