Java 与 Arduino uno 使用 RXTX串口通信



Java 与 Arduino uno 使用 RXTX串口通信

OS:win64位操作系统

rxtx:64位

下载地址:http://download.csdn.net/detail/h_hongchang/8428621

windows平台:
1、把rxtxParallel.dll、rxtxSerial.dll拷贝到:C:\WINDOWS\system32下。
2、如果是在开发的时候(JDK),需要把RXTXcomm.jar、rxtxParallel.dll、rxtxSerial.dll拷贝到..\jre…\lib\ext下;如:D:\Program Files\Java\jre1.6.0_02\lib\ext
3、而且需要把项目1.右键->2.Preperties(首选项)->3.Java Build Path->4.Libraries->5.展开RXTXcomm.jar->6.Native library location:(None)->7.浏览External Folder(选择至该项目的lib文件夹,如:E:/Item/MyItem/WebRoot/WEB-INF/lib).

 

以下是java代码:


 

[java] view plain copy

  1. package com.rxtx.test;
  2. import gnu.io.CommPortIdentifier;
  3. import gnu.io.PortInUseException;
  4. import gnu.io.SerialPort;
  5. import gnu.io.SerialPortEvent;
  6. import gnu.io.SerialPortEventListener;
  7. import gnu.io.UnsupportedCommOperationException;
  8. import java.io.BufferedInputStream;
  9. import java.io.BufferedOutputStream;
  10. import java.io.BufferedReader;
  11. import java.io.BufferedWriter;
  12. import java.io.IOException;
  13. import java.io.InputStream;
  14. import java.io.InputStreamReader;
  15. import java.io.OutputStream;
  16. import java.io.OutputStreamWriter;
  17. import java.util.Enumeration;
  18. import java.util.TooManyListenersException;
  19. /**
  20.  * @项目名称 :串口监听
  21.  * @文件名称 :
  22.  * @所在包 :
  23.  * @功能描述 :
  24.  *    串口类
  25.  * @创建者 :hhc
  26.  * @创建日期 :2015.02.06
  27.  * @修改记录 :
  28.  */
  29. public class SerialPortListener implements Runnable, SerialPortEventListener {
  30.     private String appName = ”串口通讯”;
  31.     private int timeout = 2000;//open 端口时的等待时间
  32.     private int threadTime = 0;
  33.     private CommPortIdentifier commPort;
  34.     private SerialPort serialPort;
  35.     private InputStream inputStream;
  36.     private OutputStream outputStream;
  37.     /**
  38.      * @方法名称 :listPort
  39.      * @功能描述 :列出所有可用的串口
  40.      * @返回值类型 :void
  41.      */
  42.     @SuppressWarnings(“rawtypes”)
  43.     public void listPort(){
  44.         CommPortIdentifier cpid;//当前串口对象
  45.         Enumeration en = CommPortIdentifier.getPortIdentifiers();
  46.         System.out.print(“列出所有端口:”);
  47.         while(en.hasMoreElements()){
  48.             cpid = (CommPortIdentifier)en.nextElement();
  49.             //检测端口类型是否为串口
  50.             if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL){
  51.                 System.out.println(cpid.getName() + ”, ” + cpid.getCurrentOwner());
  52.             }
  53.         }
  54.     }
  55.     /**
  56.      * @方法名称 :openPort
  57.      * @功能描述 :选择一个端口,比如:COM1 并实例 SerialPort
  58.      * @返回值类型 :void
  59.      * @param portName
  60.      */
  61.     private void openPort(String portName){
  62.         /* 打开该指定串口 */
  63.         this.commPort = null;
  64.         CommPortIdentifier cpid;
  65.         Enumeration en = CommPortIdentifier.getPortIdentifiers();
  66.         while(en.hasMoreElements()){
  67.             cpid = (CommPortIdentifier)en.nextElement();
  68.             if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL && cpid.getName().equals(portName)){
  69.                 this.commPort = cpid;
  70.                 break;
  71.             }
  72.         }
  73.         /* 实例 SerialPort*/
  74.         if(commPort == null)
  75.             log(String.format(“无法找到名字为’%1$s’的串口!”, portName));
  76.         else{
  77.             log(“当前端口:”+commPort.getName());
  78.             try{
  79.                 //应用程序名【随意命名】,等待的毫秒数
  80.                 serialPort = (SerialPort)commPort.open(appName, timeout);
  81.             }catch(PortInUseException e){
  82.                  // 端口已经被占用
  83.                 throw new RuntimeException(String.format(“端口’%1$s’正在使用中!”,commPort.getName()));
  84.             }
  85.         }
  86.     }
  87.     /**
  88.      * @方法名称 :checkPort
  89.      * @功能描述 :检查端口是否正确连接
  90.      * @返回值类型 :void
  91.      */
  92.     private void checkPort(){
  93.         if(commPort == null)
  94.             throw new RuntimeException(“没有选择端口,请使用 ” +”selectPort(String portName) 方法选择端口”);
  95.         if(serialPort == null){
  96.             throw new RuntimeException(“SerialPort 对象无效!”);
  97.         }
  98.     }
  99.     /**
  100.      * @方法名称 :write
  101.      * @功能描述 :向端口发送数据,请在调用此方法前 先选择端口,并确定SerialPort正常打开!
  102.      * @返回值类型 :void
  103.      *    @param message
  104.      * @throws IOException
  105.      */
  106.     public void write(String message) throws InterruptedException {
  107.         checkPort();
  108.         try{
  109.             outputStream = new BufferedOutputStream(serialPort.getOutputStream());
  110.             outputStream.write(message.getBytes());
  111.             log(“消息:’”+message+”‘发送成功!”);
  112.             outputStream.close();
  113.         }catch(IOException e){
  114.             throw new RuntimeException(“向端口发送信息时出错:”+e.getMessage());
  115.         }
  116.         /*另一种
  117.          try {
  118.             // 进行输入输出操作
  119.             OutputStreamWriter writer = new OutputStreamWriter(serialPort.getOutputStream());
  120.             BufferedWriter bw = new BufferedWriter(writer);
  121.             bw.write(message);
  122.             bw.flush();
  123.             bw.close();
  124.             writer.close();
  125.             System.out.println(“消息:’”+message+”‘发送成功!”);
  126.         } catch (IOException e) {
  127.             throw new RuntimeException(“向端口发送信息时出错:”+e.getMessage());
  128.         }*/
  129.     }
  130.     /**
  131.      * @方法名称 :startRead
  132.      * @功能描述 :开始监听从端口中接收的数据
  133.      * @返回值类型 :void
  134.      *    @param time  监听程序时间,单位为秒,0 则是一直监听
  135.      */
  136.     public void startRead(int time){
  137.         checkPort();
  138.         try{
  139.             inputStream = new BufferedInputStream(serialPort.getInputStream());
  140.         }catch(IOException e){
  141.             throw new RuntimeException(“获取端口的InputStream出错:”+e.getMessage());
  142.         }
  143.         try{
  144.             serialPort.addEventListener(this);
  145.             // 设置可监听
  146.             serialPort.notifyOnDataAvailable(true);
  147.             log(String.format(“开始监听来自’%1$s’的数据————–”, commPort.getName()));
  148.             serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
  149.         }catch(TooManyListenersException e){
  150.              //端口监听者过多;
  151.             throw new RuntimeException(e.getMessage());
  152.         } catch (UnsupportedCommOperationException e) {
  153.             //”端口操作命令不支持”;
  154.             e.printStackTrace();
  155.         }
  156.         /* 关闭监听 */
  157.         if(time > 0){
  158.             this.threadTime = time*1000;
  159.             Thread t = new Thread(this);
  160.             t.start();
  161.             log(String.format(“监听程序将在%1$d秒后关闭。。。。”, time));
  162.         }
  163.     }
  164.     /**
  165.      * @方法名称 :close
  166.      * @功能描述 :关闭 SerialPort
  167.      * @返回值类型 :void
  168.      */
  169.     public void close(){
  170.         serialPort.close();
  171.         serialPort = null;
  172.         commPort = null;
  173.     }
  174.     public void log(String msg){
  175.         System.out.println(appName+” –> ”+msg);
  176.     }
  177.     /**
  178.      * 数据接收的监听处理函数
  179.      */
  180.     @Override
  181.     public void serialEvent(SerialPortEvent arg0){
  182.         switch(arg0.getEventType()){
  183.         case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
  184.         case SerialPortEvent.OE:/*Overrun error,溢位错误*/
  185.         case SerialPortEvent.FE:/*Framing error,传帧错误*/
  186.         case SerialPortEvent.PE:/*Parity error,校验错误*/
  187.         case SerialPortEvent.CD:/*Carrier detect,载波检测*/
  188.         case SerialPortEvent.CTS:/*Clear to send,清除发送*/
  189.         case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
  190.         case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
  191.         case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
  192.             break;
  193.         case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
  194.             byte[] readBuffer = new byte[1024];
  195.             String readStr=”";
  196.             String s2 = ”";
  197.             try {
  198.                 while (inputStream.available() > 0) {
  199.                     inputStream.read(readBuffer);
  200.                     readStr += new String(readBuffer).trim();
  201.                 }
  202.                 log(“接收到端口返回数据(长度为”+readStr.length()+”):”+readStr);
  203.             } catch (IOException e) {
  204.                 throw new RuntimeException(e.getMessage());
  205.             }
  206.            /* 另一种// 进行输入输出操作
  207.             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
  208.             String line = null;
  209.             try {
  210.                 while ((line = reader.readLine()) != null) {
  211.                     System.out.println(line);
  212.                 }
  213.                 reader.close();
  214.             } catch (IOException e) {
  215.                 //e.printStackTrace();
  216.             }*/
  217.         }
  218.     }
  219.     @Override
  220.     public void run() {
  221.         try{
  222.             Thread.sleep(threadTime);
  223.             serialPort.close();
  224.             log(String.format(“端口’%1$s’监听关闭了!”, commPort.getName()));
  225.         }catch(Exception e){
  226.             e.printStackTrace();
  227.         }
  228.     }
  229.     /**
  230.      * 测试
  231.      * */
  232.     public static void main(String[] args) throws InterruptedException {
  233.             SerialPortListener sp = new SerialPortListener();
  234.             /* 列出所有*/
  235.             sp.listPort();
  236.             /* 开打相应端口*/
  237.             sp.openPort(“COM4″);
  238.             /* 设置为一直监听*/
  239.             sp.startRead(0);
  240.             /* 首次连接后需暂停2秒再继续执行否则数据会有问题*/
  241.             Thread.sleep(2000);
  242.             sp.write(“我”);
  243.             /* 之后发送信息前后间隔至少40ms,否则会将上条返返回信息合并为一条接收(视硬件情况调节)*/
  244.             Thread.sleep(40);
  245.             sp.write(“你”);
  246.             Thread.sleep(5000);
  247.             sp.write(“我们”);
  248.     }
  249. }

以下是 arduino 代码:

 

 

[plain] view plain copy

  1. <span style=”font-size:14px;”>String comdata =”";//接收的字符串
  2. void setup() {
  3.     Serial.begin(9600);//串口波特率
  4. }
  5. void loop() {
  6.     if(Serial.available() > 0){
  7.         /* 接收字符串 */
  8.         while (Serial.available() > 0)
  9.         {
  10.             comdata += char(Serial.read());
  11.             delay(2);
  12.         }
  13.         if (comdata.length() > 0){
  14.             if(comdata==”我”){
  15.                 Serial.println(“我什么我”);
  16.             }
  17.             if(comdata==”你”){
  18.                 Serial.println(“你什么你”);
  19.             }
  20.             if(comdata==”我们”){
  21.                 Serial.println(“我们什么我们”);
  22.             }
  23.             comdata = ”";
  24.         }
  25.     }
  26. }</span>

 

 

运行后效果: