Sobre a comunicação Serial Java + Arduino
Neste artigo demonstrarei como ligar e desligar um led, através de comandos enviados pela porta serial (USB) utilizando Java e uma placa Arduino.
Para ler outro artigo que aborda a comunicação serial clique aqui para ler o artigo de Fábio Souza, e caso queira saber mais sobre programação no Arduino clique aqui.
Mas por que utilizar Universal Serial Bus (USB)?
A comunicação USB é uma tecnologia que tornou mais simples e rápida a conexão de diversos tipos de aparelhos (Pendrives,MP3-players, impressoras, celulares, HDs externos, etc). Além de facilitar a conexão de diversos dispositivos, o padrão USB oferece:
- Plug-and-play: a maioria dos dispositivos são reconhecidos automaticamente;
- Alimentação: os dispositivos não precisam ser ligados a uma fonte de energia externa, já que a própria USB fornece energia. (Lembrado a USB fornece no máximo 5 Volts e 500 mA de corrente);
- Múltipla conexão: vários dispositivos podem ser conectados através de uma única porta, mas para isso deve-se utilizar um Hub;
- Compatibilidade: são compatíveis com a maioria dos sistemas operacionais disponíveis no mercado.
A comunicação entre os sistemas embarcados e os computadores muitas vezes são realizadas via porta paralela (DB25) e porta serial (DB-9). A utilização desses meios de comunicação pode facilitar uma alteração futura mas, por outro lado, dependendo do dispositivo, a implementação do software no computador pode ser complexa e trabalhosa. Além do mais, podemos danificar permanentemente a placa mãe do computador quando estamos utilizando a porta paralela e ocorre uma descarga elétrica ou invertermos a polaridade de um componente.
Esse artigo foi elaborado utilizado o Arduino Mega 2560, NetBeans 7.4, Windows 7 Professional x64 e Ubuntu 12.04 LTS (x64), estou considerando que as IDE’s Arduino 1.0.5 ou superior e NetBeans 7.4 ou superior já estejam instaladas e funcionando corretamente.
Obs.: Pode-se utilizar também o Arduino Uno, ADK, Pro.
Passo 01: Download dos arquivos
Acesse o site e faça download dos arquivos rxtxSerial.dll, librxtxSerial.so e RXTXcomm.jar.
Obs.: Lembrando de que devemos fazer download dos arquivos de acordo a arquitetura do sistema operacional 32-bits (x86) ou 64-bits (x64).
Passo 02: Instalação dos arquivos
Windows
Copie o arquivo rxtxSerial.dll para:
- C:\Program Files\Java\jdkx.x.x\bin, onde x.x.x é a versão do JDK, por exemplo C:\Program Files\Java\jdk1.6.40\bin;
- C:\Program Files\Java\jrex\bin, onde x é a versão do JRE, por exemplo C:\Program Files\Java\jre7\bin;
- C:\Windows\System32;
- C:\Windows\SysWOW64 (caso sistema operacional 64-bits (x64)).
Copie o arquivo RXTXcomm.jar para:
- C:\Program Files\Java\jre\jrex\lib\ext, onde x é a versão do JRE, por exemplo C:\Program Files\Java\jre7\lib\ext.
Linux
Copie o arquivo librxtxSerial.so para:
- /usr/lib/, exemplo: cp /home/Usuario/librxtxSerial.so /usr/lib/.
Copie o arquivo RXTXcomm.jar para:
- /usr/share/java/, exemplo.: cp /home/Usuario/RXTXcomm.jar /usr/share/java/.
Passo 03: Programa Arduino
Conecte o cabo USB no Arduino e abra a IDE do Arduino, defina a porta COM (Tools > Serial Port > COM3 ou /dev/ttyUSB0), digite o código abaixo e depois clique no upload. Pronto, o programa já foi carregado no arduino.
Obs.: Geralmente utiliza-se a porta COM3 (Windows) e /dev/ttyUSB0 (Linux), caso apareça outra porta não tem problema, desde que a porta correta seja informada no programa em Java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
int ledPin = 13; //atribui o pino 13 a variável ledPin int dado; //variável que receberá os dados da porta serial void setup(){ Serial.begin(9600);//frequência da porta serial pinMode(ledPin,OUTPUT); //define o pino o ledPin como saída } void loop(){ if(Serial.available() > 0){ //verifica se existe comunicação com a porta serial dado = Serial.read();//lê os dados da porta serial switch(dado){ case 1: digitalWrite(ledPin,HIGH); //liga o pino ledPin break; case 2: digitalWrite(ledPin,LOW); //desliga o pino ledPin break; } } } |
Passo 04: Programa Java
Abra o programa NetBeans 7.4 criei um projeto Aplicação Java (Arquivo > Novo Projeto > Java > Aplicação Java) e vamos chamá-lo de ComunicacaoSerial.
Renomeie o pacote “comunicacaoserial” para “br.com.embarcados.comunicaoserial” e depois apague a classe ComunicacaoSerial.java que foi gerada.
Feito isso, adicione um JFrame no pacote “br.com.embarcados.comunicaoserial” (botão direito em cima do pacote > Novo > Form Frame), e chame-o de JFInterface.
Na Paleta de controle de Swing (lado direito da tela), clique em cima do botão e arraste para dentro do JFInterface. Após esse passo altere o nome da variável jButtom1 para jBLenOn e altere o texto do botão para Ligar. Basta clicar com o botão direito em cima do botão e escolher as opções Editar Texto e Alterar nome da variável.
Copie mais 02 botões para o JFInterface e repita o mesmo processo renomeando-os para ID: jBLenOff, jBClose e Text: Desligar e Sair.
Acrescente duas classes no projeto “Arduino.java e ControlePorta.java” (botão direito em cima do pacote > Novo > Classe Java.
No arquivo Arduino.java realizaremos o envio das informações para o Arduino e no arquivo ControlePorta.java faremos toda a programação para enviar os dados através da porta serial.
Adicione o código abaixo no arquivo ControlePorta.java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
package br.com.embarcados.comunicacaoserial; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.SerialPort; import java.io.IOException; import java.io.OutputStream; import javax.swing.JOptionPane; public class ControlePorta { private OutputStream serialOut; private int taxa; private String portaCOM; /** * Construtor da classe ControlePorta * @param portaCOM - Porta COM que será utilizada para enviar os dados para o arduino * @param taxa - Taxa de transferência da porta serial geralmente é 9600 */ public ControlePorta(String portaCOM, int taxa) { this.portaCOM = portaCOM; this.taxa = taxa; this.initialize(); } /** * Médoto que verifica se a comunicação com a porta serial está ok */ private void initialize() { try { //Define uma variável portId do tipo CommPortIdentifier para realizar a comunicação serial CommPortIdentifier portId = null; try { //Tenta verificar se a porta COM informada existe portId = CommPortIdentifier.getPortIdentifier(this.portaCOM); }catch (NoSuchPortException npe) { //Caso a porta COM não exista será exibido um erro JOptionPane.showMessageDialog(null, "Porta COM não encontrada.", "Porta COM", JOptionPane.PLAIN_MESSAGE); } //Abre a porta COM SerialPort port = (SerialPort) portId.open("Comunicação serial", this.taxa); serialOut = port.getOutputStream(); port.setSerialPortParams(this.taxa, //taxa de transferência da porta serial SerialPort.DATABITS_8, //taxa de 10 bits 8 (envio) SerialPort.STOPBITS_1, //taxa de 10 bits 1 (recebimento) SerialPort.PARITY_NONE); //receber e enviar dados }catch (Exception e) { e.printStackTrace(); } } /** * Método que fecha a comunicação com a porta serial */ public void close() { try { serialOut.close(); }catch (IOException e) { JOptionPane.showMessageDialog(null, "Não foi possível fechar porta COM.", "Fechar porta COM", JOptionPane.PLAIN_MESSAGE); } } /** * @param opcao - Valor a ser enviado pela porta serial */ public void enviaDados(int opcao){ try { serialOut.write(opcao);//escreve o valor na porta serial para ser enviado } catch (IOException ex) { JOptionPane.showMessageDialog(null, "Não foi possível enviar o dado. ", "Enviar dados", JOptionPane.PLAIN_MESSAGE); } } } |
Após adicionar o código acima acontecerá vários erros conforme a mensagem abaixo.
Esses erros aconteceram porque não adicionamos o arquivo RXTXcomm.jar no nosso projeto. Para adicioná-lo clique com o botão direito em cima da pasta Biblioteca e escolha Adicionar JAR/Pasta… e informe o diretório onde o arquivo RXTXcomm.jar (C:\Program Files\Java\jre7\lib\ext\RXTXcomm.jar, caso esteja utilizando Windows) ou (/usr/share/java/ RXTXcomm.jar, caso esteja utilizando Linux).
Limpe e construa o projeto (botão direito em cima do projeto ComunicacaoSerial > Limpar e Construir) e os problemas serão corrigidos conforme pode-se ver na imagem abaixo.
Agora adicione o código abaixo no arquivo Arduino.java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package br.com.embarcados.comunicacaoserial; import javax.swing.JButton; /** * @author klauder */ public class Arduino { private ControlePorta arduino; /** * Construtor da classe Arduino */ public Arduino(){ arduino = new ControlePorta("COM3",9600);//Windows - porta e taxa de transmissão //arduino = new ControlePorta("/dev/ttyUSB0",9600);//Linux - porta e taxa de transmissão } /** * Envia o comando para a porta serial * @param button - Botão que é clicado na interface Java */ public void comunicacaoArduino(JButton button) { if("Ligar".equals(button.getActionCommand())){ arduino.enviaDados(1); System.out.println(button.getText());//Imprime o nome do botão pressionado } else if("Desligar".equals(button.getActionCommand())){ arduino.enviaDados(2); System.out.println(button.getText()); } else{ arduino.close(); System.out.println(button.getText());//Imprime o nome do botão pressionado } } } |
Feito isso, falta implementar a ação a ser executada quando um determinado botão for pressionado.
Abra o arquivo JFInterface.java, clique com o botão direito em cima do botão “Ligar” e acione o método MousedClicked. Será criado automaticamente um método dentro da classe JFInterface.java conforme a imagem abaixo.
Declare uma variável do tipo Arduino antes do construtor da classe JFInterface, conforme a figura abaixo.
Dentro do método jBLedOnMouseClicked criado anteriormente adicione o código conn.comunicacaoArduino(jBLedOn).
Esse comando irá acionar o método comunicacaoArduino(), passando o botão clicado, que por sua vez irá enviar o dado pela porta serial.
Adicione o mesmo evento para o botão “Desligar” e coloque o código abaixo:
Adicione o mesmo evento para o botão “Sair” e coloque o código abaixo:
Passo 05: Executando o programa
Agora basta apenas conectar o seu Arduino à porta USB do seu computador e clicar em Executar o projeto Java. Ao aparecer a Tela, basta apenas clicar no botão “Ligar” para ligar, “Desligar” para desligar o Led e “Sair” para encerrar aplicação.
Os códigos fontes utilizados na elaboração desse artigo estão disponíveis nesse link.
Espero que tenham gostado e até breve.
Referências
Poderiam fazer um tutorial do Java lendo as informações emitidas pela arduino.
Eu fiz o mesmo procedimento no Eclipse, porém ele nao reconhece a
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.SerialPort;
e o arquivo RXTXcomm.jar ja está adicionado na JRE System Librar. Se puder ajudar, por favor, será de grande ajuda !
Excelente tutorial, porém quando executo o programa aparece que a porta COM não pode ser encontrada. Estou usando um Arduíno Nano e meu Sistema Operacional é o Linux Mint 18.3 xfce. Não entendo porquê não está encontrando.
Gabriel, desculpe a demora em responder.
Imagino que isso possa ser alguma configuração da porta COM, já tentou rodar em outro SO, PC para ver si não é um problema da porta COM desse PC? Se possível teste outros tutorial que utilizem a porta COM, para ter certeza que ele esteja bem.
Aguardo seu retorno.
Gabriel, desculpe a demora em responder.
Imagino que isso possa ser alguma configuração da porta COM, já tentou rodar em outro SO, PC para ver si não é um problema da porta COM desse PC? Se possível teste outros tutorial que utilizem a porta COM, para ter certeza que ele esteja bem.
Aguardo retorno.
Olá amigão, primeiramente gostaria de Agradecer Pela SUA Iniciativa em transmitir o Conhecimento.
Bom Vamos Lá, DEPOIS de ler ESSE Passo a Passo Varias vezes eu consegui executar o Projeto Dentro do netbeans …
Agora when tento abrir o Arquivo .jar Que se Encontra Dentro da dist massas, Funciona nada …
Andei pesquisando e me parece Ser algo com a principal classe …
Bom Não Sei Como Change …
Se Alguém Além do Klauder Puder me Ajudar agradeço !!!
Diego, que erro dá? Seria como explicar melhor, por favor.
Olá amigão, primeiramente gostaria de agradecer pela sua iniciativa em transmitir o conhecimento.
Bom vamos lá, depois de ler esse passo a passo várias vezes eu consegui executar o projeto dentro do netbeans…
Agora quando tento abrir o arquivo .jar que se encontra dentro da pasta dist, nada funciona…
Andei pesquisando e me parece ser algo com a classe principal…
Bom não sei como alterar…
Se alguém além do Klauder puder me ajudar agradeço!!!
Amigo, como faço para enviar uma String para o arduino a partir do seu código?
Ola Klauder, poderia fazer um projeto em que você receba dados da porta serial e imprima em um arquivo.txt ou se melhor logo para o Excel, poderia variar utilizando um microcontrolador(já que esse está em falta na internet).
Obrigado desde já! Aguardo respostas.
Parabéns!! Ótimo Tututorial!
Estou com o seguinte problema:
java.lang.UnsatisfiedLinkError: C:Program FilesJavajdk1.8.0_31binrxtxSerial.dll: %1 não é um aplicativo Win32 válido thrown while loading gnu.io.RXTXCommDriver
Exception in thread “Sistema Code Control” java.lang.UnsatisfiedLinkError: C:Program FilesJavajdk1.8.0_31binrxtxSerial.dll: %1 não é um aplicativo Win32 válido
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1937)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1855)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at gnu.io.CommPortIdentifier.(CommPortIdentifier.java:123)
at code.control.observer.arduino.ControlePorta.initialize(ControlePorta.java:35)
at code.control.observer.arduino.ControlePorta.(ControlePorta.java:23)
at code.control.observer.arduino.Desbloqueio.executa(Desbloqueio.java:9)
at code.control.observer.Autenticador.lambda$0(Autenticador.java:36)
at code.control.observer.Autenticador$$Lambda$157/1592347142.accept(Unknown Source)
at java.util.Vector$VectorSpliterator.forEachRemaining(Vector.java:1414)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at code.control.observer.Autenticador.atualizar(Autenticador.java:31)
at code.control.observer.Sistema.notificarObservadores(Sistema.java:53)
at code.control.qr.aciona.LeitorQR.run(LeitorQR.java:105)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Alguém pode me dar uma luz?
Ola Klauder queria saber com faço para enviar comandos não para um arduino mas para um modem GSM. E receba sinal do modem. Obrigado