Javax.comm. Capturando □'s na leitura dos dados

6 respostas
Augusto_

Pessoal,

fiz um programa usando uma classe que peguei aqui no GUJ pra capturar dados de um GPS via bluetooth. O programa funciona normalmente, exceto pelo fato de estar pegando quadradinhos na leitura, no lugar de pegar os dados certos. Eis um exemplo:

A impressao que da eh que o java nao reconhece os caracteres e bota esses quadradinhos no lugar. Alguem sabe ou tem alguma nocao do que pode ser ou como posso resolver isso? Eis o código, ligeiramente modificado:

package model;

import javax.comm.*;  
import java.io.*;  
  
//classe Principal  
public class ModelRTK implements SerialPortEventListener {  
    //propriedades  
    private String Porta;  
    public String Dadoslidos;  
    public int nodeBytes;  
    private int baudrate;  
    private int timeout;  
    private CommPortIdentifier cp;  
    private SerialPort porta;  
    private OutputStream saida;  
    private InputStream entrada;   
    //indicadores  
    public boolean IDPortaOK; //true porta EXISTE  
    public boolean PortaOK;// true porta aberta  
    private boolean Leitura;  
    private boolean Escrita;  
    
    public ModelBD bd;
      
    //private principal pri;  
    //construtor default paridade : par  
    //baudrate: 9600 bps stopbits: 2 COM 1  
    public ModelRTK(String p, String usuario, String senha, String conexao, String root, String senhaRoot) 
    	throws Exception {  
    	
    	bd = new ModelBD(usuario, senha, conexao, root, senhaRoot);
    	
        //pri = new principal();  
        Porta = p;  
        baudrate = 115200;  
        timeout = 1000;  
        
        ObterIdDaPorta();
        AbrirPorta();
        HabilitarEscrita();
        EnviarUmaString("%%em,/dev/ser/b,/msg/nmea/GGA:1\n");
        HabilitarLeitura();
        LerDados();
        
        
        //System.out.println("Entrei no construtor");  
    };  
    //um Objeto ComObj é passado ao construtor  
    //com detalhes de qual porta abrir  
    //e informações sobre configurações  
    public ModelRTK( String p , int b , int t ){  
        this.Porta = p;  
        this.baudrate = b;  
        this.timeout = t;  
    };  
    //habilita escrita de dados  
    public void HabilitarEscrita(){  
        Escrita = true;  
        Leitura = false;  
   }  
    //habilita leitura de dados  
    public void HabilitarLeitura(){  
        Escrita = false;  
        Leitura = true;  
    }  
    //Obtém o ID da PORTA  
    public void ObterIdDaPorta() throws Exception {  
  
            cp = CommPortIdentifier.getPortIdentifier(Porta);  
            //ResultSet a = (ResultSet) CommPortIdentifier.getPortIdentifiers();
            
            //while(a.next()) {
            //	System.out.println(a.getRow());
            //}
            //System.out.println(cp + "  " + Porta);  
            if ( cp == null ) {  
                //System.out.println("A " + Porta + " nao existe!" );  
                //System.out.println("ERRO!Abortando..." );  
                IDPortaOK = false;  
            }  
            IDPortaOK = true;  
       
    }  
    //Abre a comunicação da porta  
    public void AbrirPorta() throws Exception {    
            porta = (SerialPort)cp.open("RTK",timeout);  
            PortaOK = true;  
            //System.out.println("Porta aberta com sucesso!");  
            //configurar parâmetros  
            porta.setSerialPortParams(baudrate,  
            SerialPort.DATABITS_8,  
            SerialPort.STOPBITS_2,  
            SerialPort.PARITY_NONE);  
    }  
    //função que envie um bit para a porta serial  
    public void EnviarUmaString(String msg) throws Exception {  
        if (Escrita==true) {  
         
                saida = porta.getOutputStream();  
                //System.out.println("FLUXO OK!");  
           
                //System.out.println("Enviando um byte para " + Porta );  
                //System.out.println("Enviando : " + msg );  
                saida.write(msg.getBytes());  
                Thread.sleep(100);  
                saida.flush();  
           
        } else {  
            //System.exit(1);  
        }  
        
       
    }  
   //leitura de dados na serial  
    public void LerDados() throws Exception {  
        if (Leitura == true){  
           
                entrada = porta.getInputStream();  
                //System.out.println("FLUXO OK!");  
             
                porta.addEventListener(this);  
                //System.out.println("SUCESSO. Porta aguardando...");  
            
            porta.notifyOnDataAvailable(true);  
           
       	}  
    }  
    
    //gerenciador de eventos de leitura na serial  
    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[40];  
	            try {  
	                while ( entrada.available() > 0 ) {  
	                    nodeBytes = entrada.read(bufferLeitura);  
	                }  
	                String Dadoslidos = new String(bufferLeitura);
	                
	                System.out.println(Dadoslidos);
	                
	                if (bufferLeitura.length == 0) {  
	                    //System.out.println("Nada lido!");  
	                } else if (bufferLeitura.length == 1 ){  
	                    //System.out.println("Apenas um byte foi lido!");  
	                } else {  
	                    bd.atualizaPosicao(Dadoslidos);

	                    if(Dadoslidos.substring(0,2).equals(new String("00"))){  
	                       // System.out.println("entrei");  
	                        //pri.atualizaInfo(Dadoslidos.substring(0,2), "velVento");  
	                       // System.out.println("passei");  
	                    }  
	                }
	                
	                
	                 
	            } catch (Exception e) {  
	                //System.out.println("Erro durante a leitura: " + e );  
	            }  
	            //System.out.println("n.o de bytes lidos : " + nodeBytes );  
            break;  
        }  
    }  
    //função que fecha a conexão  
    public void FecharCom() throws Exception {   
            porta.close();  
    }  
    //Acessores  
    public String obterPorta(){  
        return Porta;  
    }  
    public int obterBaudrate(){  
        return baudrate;  
    }  
}

Grato.

6 Respostas

T

Se puder, não use strings e sim arrays de bytes para efetuar comunicação serial. É que strings são convertidos de/para arrays de bytes com alguns problemas. Para comprovar isso, crie um array de bytes com 256 bytes, contendo os bytes de -128 a +127, e converta-o para uma string usando new String (bytes).
Você vai ver que a string resultante não contém todos os bytes originais - alguns deles serão convertidos para o caracter ‘?’.

S

faz como Thingol disse mas sempre verifique se os bytes no vetor são menores que 0, pois se for o valor é maior que 127.

no java o byte é sinalizado e permite operações somente com valores de -128 à 127.

faça o seguinte:

int[] valoresValidos = new Int[n];

for(..)
{ 
     if (VetorDeByte[i] < 0)
         valoresValidos[i] = ((short) VetorDebyte[i] & 0xFF);
}

é interessante criar uma classe pra fazer essas operações com tipos sinalizados(signed).

Augusto_

Valeu pela ajuda, mas desse jeito ainda estava pegando quadradinhos.

Acho que consegui resolver o problema aumentando o tamanho do buffer de leitura pra 1024

linha 144:
byte[] bufferLeitura = new byte[1024];

parece que funcionou, mas como tenho que testar em ambiente aberto soh vou poder testar amanha, dai venho aqui pra falar com vcs

abs

C

Só fique esperto na hora de enviar/receber valores maiores que 255 dai vc precisa realizar uma conversao

por exemplo vc deseja enviar o 0xABC
voce precisa separar em Mais significativo e menos significativo
e enviar
0x0A
0xBC

int dados = 0xABC;
int MSB,LSB;
//desloca em 8 bits para a direita
MSB = (dados >>8 ) & 0x0F;
LSB = dados & 0xFF;

abraços

pyro

Se quiser alguma referencia utilize a RXTX: http://www.viamais.net/blog/index.php?s=rxtx

Augusto_

caiortp:
Só fique esperto na hora de enviar/receber valores maiores que 255 dai vc precisa realizar uma conversao

por exemplo vc deseja enviar o 0xABC
voce precisa separar em Mais significativo e menos significativo
e enviar
0x0A
0xBC

int dados = 0xABC;
int MSB,LSB;
//desloca em 8 bits para a direita
MSB = (dados >>8 ) & 0x0F;
LSB = dados & 0xFF;

abraços

Entendi, valeu pela dica. Mas acredito que o GPS ja trabalhe direto com caracteres comuns. Pelo menos eu já fiz vários testes nele e funcionou. Vale a dica pra quando eu for mexer com outros tipos de dispositivos.

Criado 19 de agosto de 2008
Ultima resposta 20 de ago. de 2008
Respostas 6
Participantes 5