sexta-feira, 18 de janeiro de 2013

Manipulando Comunicação Serial com a api javacomm



Fala Galera! Neste post venho falar um pouco de comunicação Serial com java. Como assim?

Quem nunca quis conectar uma impressora à aplicação, um teclado paralelo com display e tals? Esta API facilita e muito nossa vida para este tipo de ação. Então vamos aos passos:

1) Baixar a API:

 Você encontra a API disponível no site:
 http://java.sun.com/products/javacomm/index.jsp
 Basta baixar a API e realizar os procedimentos de instalação. Após baixar a API, descompactá-la, você
terá:

o  Copiar o arquivo win32com.dll para o diretório C:\JavaSDK\BIN (isto é, o diretório onde o
J2SDK foi instalado no seu PC).  

o  Copiar o arquivo comm.jar para o diretório C:\JavaSDK\BIN\LIB.  

o  Copiar o arquivo javax.comm.properties para o diretório C:\JavaSDK\BIN\LIB. 

o  Em seguida configure o CLASSPATH para que ele reconheça o arquivo comm.jar.

RECONHECENDO AS PORTAS

//....
Enumeration listaDePortas;
listaDePortas = CommPortIdentifier.getPortIdentifiers();
//...
//..
 int i = 0; portas = new String[10];
while (listaDePortas.hasMoreElements()) {
  CommPortIdentifier ips = (CommPortIdentifier)listaDePortas.nextElement(); portas[i] = ips.getName();
  i++;
 }
//..

ABRINDO AS PORTAS

O método getPortIdentifier(String porta) da classe CommPortIdentifier retorna um identificador da porta escolhida. Precisamos instanciar um objeto para receber esse identificador:
 
CommIdentifier cp = CommPortIdentifier.getPortIdentifier(minhaPortaEscolhida); 
Em seguida criamos uma instância da classe SerialPort utilizando o identificador. Note que uma conversão deverá ser feita. A porta só pode ser instanciada através desse “casting” e ao mesmo tempo abrimos a porta para comunicação:

SerialPort porta = (SerialPort)cp.open("SComm",timeout); 
O método open() tem como parâmetros o nome da classe principal (faça isso para não gerar conflitos) e o valor desejado para timeout. Em seguida, precisamos atribuir fluxos de entrada e saída. Basta utilizar as classes Abstratas OutputStream e InputStream, já que a classe SerialPort implementa os métodos de entrada e saída dessas classes para comunicação serial. Para ler dados na porta serial:

InputStream entrada = porta.getInputStream();
E para escrever dados na porta serial:

OutputStream saida = porta.getOutputStream();
Em seguida precisamos configurar os parâmetros de comunicação serial, para isso utilizamos o método setSerialPortParams:
 
porta.setSerialPortParams(baudrate, porta.DATABITS_8, porta.STOPBITS_2, porta.PARITY_NONE);

ENVIANDO DADOS

Depois de configurar a porta para comunicar e definido o fluxo de saída, podemos comunicar os dados. Isso é bem simples:

String msg = “Olá Mundo!”;
saida.write(msg.getBytes());
Thread.sleep(100);
saida.flush();

RECEBENDO DADOS


porta.addEventListener(this);
porta.notifyOnDataAvailable(true);
public void serialEvent(SerialPortEvent ev){
  switch (ev.getEventType()) {
    //…
   case SerialPortEvent.DATA_AVAILABLE: byte[] bufferLeitura = new byte[20];
     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) {
         System.out.println("Erro durante a leitura: " + e );
    }
   System.out.println("n.o de bytes lidos : " + nodeBytes ); break; }

Segue Abaixo meu código de exemplo completo:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package testeintegra;

/**
 *
 * @author Bruno Santos
 */
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import javax.swing.JOptionPane;

public class testeCon implements SerialPortEventListener {

    static public final char STX = 12; //inicio de um bloco de mensagem  
    static public final char ETX = 0x03; //fim de um bloco de mensagem  
    static public final char EOT = 0x04; //fim de uma troca de mensagem  
    static public final char ACK = 0x06; //ack normal = ok  
    static public final char NAK = 0x15; //não ack  
    static public final char FS = 0x1C;  //separador de campos da mensagem  
    static public final char GS = 0x1D;  //separador de campos da mensagem  
    static public final char US = 0x1F;  //separador de campos da mensagem  
    private static String[] portas;
    private static int baudrate;
    InputStream datain;
    public static InputStream entrada;
    OutputStream dataout;
    public static SerialPort porta;
    public static final String nomePorta = "COM9";
    boolean encontrada = false;

    public SerialPort getPorta(String porta) {

        SerialPort serialPort = null;
        CommPortIdentifier portId;
        Enumeration portList;
        //Obtem a lista de portas abaixo (no arquivo javax.comm.properties, vou falar depois)  
        portList = CommPortIdentifier.getPortIdentifiers();


        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();
            //Pega só as portas seriais  
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                //Esse cara aqui vê se a porta que ele encontrou é a que vc quer!!  
                if (portId.getName().equals(porta)) {
                    System.out.println("Porta encontrada " + porta);

                    encontrada = true;

                    try {
                        //SimpleWrite é o nome da aplicação e 2000 o timeout  
                        serialPort = (SerialPort) portId.open("SimpleWrite", 2000);

                    } catch (PortInUseException e) {
                        System.out.println("Port in use.");

                        continue;
                    }

                    /* No linux temos que carregar o módulo serial_cs, se não esses parametrôs não funcionam 
                    
                    try { 
                    serialPort.setSerialPortParams(9600, 
                    SerialPort.DATABITS_8, 
                    SerialPort.STOPBITS_1, 
                    SerialPort.PARITY_NONE); 
                    } catch (UnsupportedCommOperationException e) {} 
                     */

                    try {
                        //Notificar quando o output está clean  
                        serialPort.notifyOnOutputEmpty(true);
                    } catch (Exception e) {
                        System.out.println("Error setting event notification");
                        System.out.println(e.toString());

                    }
                }
            }
        }
        System.out.println(serialPort);
        return serialPort;

    }

    private void executa() {
        porta = getPorta(nomePorta);

        try {
            datain = porta.getInputStream();
            dataout = porta.getOutputStream();
            byte msg[] = {NAK};
            dataout.write(msg);
            String valor;
            //O buffer!!!  
            byte buff[] = new byte[100];
            int lidos = 0;
            lidos = datain.read(buff);
            System.out.println(lidos);
            if (lidos > 0) {


                while (lidos != 13) {
                    lidos = lidos + datain.read(buff);
                    valor = String.valueOf(datain.read() + datain.read());
                    System.out.println(valor);
                }
                System.out.println("Senha digitada foi");
//         if (buff[0]==NAK){  
//             System.out.println("Deu pau!!");  
//               
//         }else if (buff[0]==ACK){  
//             System.out.println("Festa!!!");  
//             System.out.println(msg);
//         }}  
            }
            porta.close();
        } catch (Exception e) {
            // Deu pau ao obter portas  
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws NoSuchPortException, PortInUseException, IOException, UnsupportedCommOperationException, InterruptedException {
        //    testeCon com = new testeCon();
        //  com.executa();
        testeCon teste = new testeCon();
        teste.teste();
    }

    private void teste() throws NoSuchPortException, PortInUseException, IOException, UnsupportedCommOperationException, InterruptedException {
        Enumeration listaDePortas;
        listaDePortas = CommPortIdentifier.getPortIdentifiers();
        int i = 0;

        portas = new String[10];
        while (listaDePortas.hasMoreElements()) {
            CommPortIdentifier ips = (CommPortIdentifier) listaDePortas.nextElement();
            portas[i] = ips.getName();
            i++;

        }
        CommPortIdentifier cp = CommPortIdentifier.getPortIdentifier("COM9");
        porta = (SerialPort) cp.open("SComm", 10);
        entrada = porta.getInputStream();
        OutputStream saida = porta.getOutputStream();
        porta.setSerialPortParams(9600, porta.DATABITS_8, porta.STOPBITS_1, porta.PARITY_NONE);

        String msg = "eu";
        saida.write(msg.getBytes());
        Thread.sleep(10000);
        saida.flush();
        
      

    }

    public void serialEvent(SerialPort event) throws TooManyListenersException {
        porta.addEventListener(this);
        porta.notifyOnDataAvailable(true);
        int nodeBytes = 0;
        switch (SerialPortEvent.DATA_AVAILABLE) {
            //… 
            case SerialPortEvent.DATA_AVAILABLE:
                byte[] bufferLeitura = new byte[20];
                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 {
                       JOptionPane.showMessageDialog(null, Dadoslidos);
                       
                    }
                } catch (Exception e) {
                    System.out.println("Erro durante a leitura: " + e);
                }
                System.out.println("n.o de bytes lidos : " + nodeBytes);
                break;
        }
    }
}

É isso ai galera! Espero que tenham gostado. Abraços!


Leia mais em: API de comunicação SERIAL da SUN (Javacomm) http://www.devmedia.com.br/api-de-comunicacao-serial-da-sun-javacomm/4169#ixzz2IKaJxjl6

3 comentários:

  1. Desculpe-me pela minha ignorância, mas consegui me cadastrar.

    ResponderExcluir
    Respostas
    1. Basta clicar no botão do lado direito que diz Participar deste site..

      Abraços!

      Excluir
  2. Este comentário foi removido pelo autor.

    ResponderExcluir

Admin: Bruno

Olá Galera! muito grato por estarem acessando nosso blog. Espero que seja possível transmitir de forma compreensível um pouco de meus conhecimentos em programação, para esta comunidade de desenvolvedores que cresce cada vez mais! Espero que Gostem! Abraço! E meu enorme obrigado à Renato Simões, Átila Soares,Wanderson Quinto, Emerson e a toda galera que sempre ajudou meu sincero obrigado....
Especialmente a Natalia Failache e Rita de Cassia que sempre apoiaram este sonho....

De seu amigo Bruno Rafael.