使用Java串口通信


         很老套的代码,但是却费时很久,找到过很多参考代码,但是要不然和本身项目不太符合,要不然就运行不出来,报串口找不到的错误,也还因为jar包整了很久,去各种百度解决办法才真正实现使用java实现串口通信。

          1.  jar包的导入

                   1.1  如果你的电脑安装的是32位的JDK,那么有两种解决方案

                            A. 

[html]  view plain  copy
  1. 将文件comm.jar拷贝到%JAVA_HOME%\jre\lib\ext;    
  2. 文件javax.comm. properties拷贝到%JAVA_HOME%\jre\lib;     
  3. 文件win32comm.dll拷贝到%JAVA_HOME%\bin。    
  4. 注意%JAVA_HOME%是jdk的路径,而非jre。    

                            B. 使用Rxtx   jar包(32位)

                            下载地址:点击打开链接

                     1.2 如果你的电脑安装的是64位的JDK,那么只能使用Rxtx  jar包(64位)

                            下载地址:点击打开链接

          由于我写的项目是一个动态WEB项目,所以目前只实现了接收串口数据,在WEB页面操作后,再向硬件发送数据还未实现,后续还会更新。

          接收数据的实现思路如下:现在java程序中启动读串口数据的类,读出之后按解析保存至数据库中,WEB的显示后台则从数据库中取数据。

          首先是写好的串口工具类:

         

[html]  view plain  copy
  1. /**  
  2.  * 串口服务类,提供打开、关闭串口,读取、发送串口数据等服务(采用单例设计模式)  
  3.  * @author zhong  
  4.  *  
  5.  */  
  6. public class SerialTool {  
  7.       
  8.     private static SerialTool serialTool = null;  
  9.       
  10.     static {  
  11.         //在该类被ClassLoader加载时就初始化一个SerialTool对象  
  12.         if (serialTool == null) {  
  13.             serialTool = new SerialTool();  
  14.         }  
  15.     }  
  16.       
  17.     //私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象  
  18.     private SerialTool() {}      
  19.       
  20.     /**  
  21.      * 获取提供服务的SerialTool对象  
  22.      * @return serialTool  
  23.      */  
  24.     public static SerialTool getSerialTool() {  
  25.         if (serialTool == null) {  
  26.             serialTool = new SerialTool();  
  27.         }  
  28.         return serialTool;  
  29.     }  
  30.   
  31.   
  32.     /**  
  33.      * 查找所有可用端口  
  34.      * @return 可用端口名称列表  
  35.      */  
  36.     @SuppressWarnings("unchecked")  
  37.     public static final ArrayList<String> findPort() {  
  38.   
  39.         //获得当前所有可用串口  
  40.         Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();      
  41.           
  42.         ArrayList<String> portNameList = new ArrayList<>();  
  43.   
  44.         //将可用串口名添加到List并返回该List  
  45.         while (portList.hasMoreElements()) {  
  46.             String portName = portList.nextElement().getName();  
  47.             portNameList.add(portName);  
  48.         }  
  49.         return portNameList;  
  50.     }  
  51.       
  52.     /**  
  53.      * 打开串口  
  54.      * @param portName 端口名称  
  55.      * @param baudrate 波特率  
  56.      * @return 串口对象  
  57.      * @throws SerialPortParameterFailure 设置串口参数失败  
  58.      * @throws NotASerialPort 端口指向设备不是串口类型  
  59.      * @throws NoSuchPort 没有该端口对应的串口设备  
  60.      * @throws PortInUse 端口已被占用  
  61.      */  
  62.     public static final SerialPort openPort(String portName, int baudrate) throws SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse {  
  63.   
  64.         try {  
  65.   
  66.             //通过端口名识别端口  
  67.             CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);  
  68.   
  69.             //打开端口,并给端口名字和一个timeout(打开操作的超时时间)  
  70.             CommPort commPort = portIdentifier.open(portName, 2000);  
  71.   
  72.             //判断是不是串口  
  73.             if (commPort instanceof SerialPort) {  
  74.                   
  75.                 SerialPort serialPort = (SerialPort) commPort;  
  76.                   
  77.                 try {                          
  78.                     //设置一下串口的波特率等参数  
  79.                     serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);                                
  80.                 } catch (UnsupportedCommOperationException e) {    
  81.                     throw new SerialPortParameterFailure();  
  82.                 }  
  83.                   
  84.                 System.out.println("Open " + portName + " sucessfully !");  
  85.                 return serialPort;  
  86.               
  87.             }          
  88.             else {  
  89.                 //不是串口  
  90.                 throw new NotASerialPort();  
  91.             }  
  92.         } catch (NoSuchPortException e1) {  
  93.           throw new NoSuchPort();  
  94.         } catch (PortInUseException e2) {  
  95.             throw new PortInUse();  
  96.         }  
  97.     }  
  98.       
  99.     /**  
  100.      * 关闭串口  
  101.      * @param serialport 待关闭的串口对象  
  102.      */  
  103.     public static void closePort(SerialPort serialPort) {  
  104.         if (serialPort != null) {  
  105.             serialPort.close();  
  106.             System.out.println("Close " + serialPort + " sucessfully !");  
  107.             serialPort = null;  
  108.         }  
  109.     }  
  110.       
  111.     /**  
  112.      * 往串口发送数据  
  113.      * @param serialPort 串口对象  
  114.      * @param order    待发送数据  
  115.      * @throws SendDataToSerialPortFailure 向串口发送数据失败  
  116.      * @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错  
  117.      */  
  118.     public static void sendToPort(SerialPort serialPort, byte[] order) throws SendDataToSerialPortFailure, SerialPortOutputStreamCloseFailure {  
  119.   
  120.         OutputStream out = null;  
  121.           
  122.         try {  
  123.             out = serialPort.getOutputStream();  
  124.             out.write(order);  
  125.             out.flush();  
  126.               
  127.         } catch (IOException e) {  
  128.             throw new SendDataToSerialPortFailure();  
  129.         } finally {  
  130.             try {  
  131.                 if (out != null) {  
  132.                     out.close();  
  133.                     out = null;  
  134.                 }                  
  135.             } catch (IOException e) {  
  136.                 throw new SerialPortOutputStreamCloseFailure();  
  137.             }  
  138.         }  
  139.           
  140.     }  
  141.       
  142.     /**  
  143.      * 从串口读取数据  
  144.      * @param serialPort 当前已建立连接的SerialPort对象  
  145.      * @return 读取到的数据  
  146.      * @throws ReadDataFromSerialPortFailure 从串口读取数据时出错  
  147.      * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错  
  148.      */  
  149.     public static byte[] readFromPort(SerialPort serialPort) throws ReadDataFromSerialPortFailure, SerialPortInputStreamCloseFailure {  
  150.   
  151.         InputStream in = null;  
  152.         byte[] bytes = null;  
  153.   
  154.         try {  
  155.             in = serialPort.getInputStream();  
  156.             int bufflenth = in.available();        //获取buffer里的数据长度  
  157.               
  158.             while (bufflenth != 0) {                               
  159.                 bytes = new byte[bufflenth];    //初始化byte数组为buffer中数据的长度  
  160.                 in.read(bytes);  
  161.                 bufflenth = in.available();  
  162.             }   
  163.         } catch (IOException e) {  
  164.             throw new ReadDataFromSerialPortFailure();  
  165.         } finally {  
  166.             try {  
  167.                 if (in != null) {  
  168.                     in.close();  
  169.                     in = null;  
  170.                 }  
  171.             } catch(IOException e) {  
  172.                 throw new SerialPortInputStreamCloseFailure();  
  173.             }  
  174.         }  
  175.         return bytes;  
  176.     }  
  177.       
  178.     /**  
  179.      * 添加监听器  
  180.      * @param port     串口对象  
  181.      * @param listener 串口监听器  
  182.      * @throws TooManyListeners 监听类对象过多  
  183.      */  
  184.     public static void addListener(SerialPort port, SerialPortEventListener listener) throws TooManyListeners {  
  185.   
  186.         try {          
  187.             //给串口添加监听器  
  188.             port.addEventListener(listener);  
  189.             //设置当有数据到达时唤醒监听接收线程  
  190.             port.notifyOnDataAvailable(true);  
  191.             //设置当通信中断时唤醒中断线程  
  192.             port.notifyOnBreakInterrupt(true);  
  193.   
  194.         } catch (TooManyListenersException e) {  
  195.             throw new TooManyListeners();  
  196.         }  
  197.     }  
  198.       
  199.       
  200. }  

          写好之后,就是读串口类,要保存至数据库的话就是在读出数据后保存,此处无保存至数据库的代码:

         

[html]  view plain  copy
  1. public class EventListener implements SerialPortEventListener {  
  2.   
  3.      //1.定义变量  
  4.     SerialPort serialPort = null;  
  5.     InputStream inputStream = null;//输入流  
  6.     Thread readThread = null;  
  7.     //2.构造函数:  
  8.     //实现初始化动作:获取串口COM21、打开串口、获取串口输入流对象、为串口添加事件监听对象  
  9.       
  10.     public EventListener() throws NoSuchPortException, PortInUseException{  
  11.         try {  
  12.             //获取串口、打开窗串口、获取串口的输入流。  
  13.             serialPort = SerialTool.openPort("COM3", 115200);  
  14.             inputStream = serialPort.getInputStream();  
  15.             //向串口添加事件监听对象。  
  16.             serialPort.addEventListener(this);  
  17.             //设置当端口有可用数据时触发事件,此设置必不可少。  
  18.             serialPort.notifyOnDataAvailable(true);  
  19.         } catch (IOException e) {  
  20.             e.printStackTrace();  
  21.         } catch (TooManyListenersException e) {  
  22.             // TODO Auto-generated catch block  
  23.             e.printStackTrace();  
  24.         } catch (SerialPortParameterFailure e) {  
  25.             // TODO Auto-generated catch block  
  26.             e.printStackTrace();  
  27.         } catch (NotASerialPort e) {  
  28.             // TODO Auto-generated catch block  
  29.             e.printStackTrace();  
  30.         } catch (NoSuchPort e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         } catch (PortInUse e) {  
  34.             // TODO Auto-generated catch block  
  35.             e.printStackTrace();  
  36.         }finally {  
  37.         //  SerialTool.closePort(serialPort);  
  38.         }  
  39.     }  
  40.   
  41.     //重写继承的监听器方法  
  42.     @Override  
  43.     public void serialEvent(SerialPortEvent event) {  
  44.         //定义用于缓存读入数据的数组  
  45.         byte[] cache = new byte[1024];  
  46.         //记录已经到达串口COM21且未被读取的数据的字节(Byte)数。  
  47.         int availableBytes = 0;  
  48.   
  49.         //如果是数据可用的时间发送,则进行数据的读写  
  50.         if(event.getEventType() == SerialPortEvent.DATA_AVAILABLE){  
  51.             try {  
  52.                 availableBytes = inputStream.available();  
  53.                 while(availableBytes > 0){  
  54.                     inputStream.read(cache);  
  55.                     for(int i = 0; i < cache.length && i < availableBytes; i++){  
  56.                         //解码并输出数据  
  57.                         System.out.print((char)cache[i]);  
  58.                     }  
  59.                     availableBytes = inputStream.available();  
  60.                 }  
  61.                 System.out.println();  
  62.             } catch (IOException e) {  
  63.                 e.printStackTrace();  
  64.             }  
  65.         }  
  66.     }  
  67.   
  68.     public static void main(String[] args) throws NoSuchPortException, PortInUseException {  
  69.         new EventListener();  
  70.     }  
  71.       
  72. }  

再就是向串口发送数据:

[html]  view plain  copy
  1. public class Write {  
  2.     public static void main(String[] args) {  
  3.         SerialPort serialPort = null;                  //打开的端  
  4.         try {  
  5.             //打开串口  
  6.             serialPort = SerialTool.openPort("COM21", 9600);  
  7.             //数组“Hello World!”  
  8.             byte[] bs = new byte[]{'H','e','l','l','o',' ','W','o','r','l','d','!'};  
  9.             //写入数组  
  10.             SerialTool.sendToPort(serialPort, bs);  
  11.         } catch (SerialPortParameterFailure | NotASerialPort | NoSuchPort | PortInUse | SendDataToSerialPortFailure | SerialPortOutputStreamCloseFailure e) {  
  12.             // TODO Auto-generated catch block  
  13.             e.printStackTrace();  
  14.         }finally {  
  15.             //关闭串口  
  16.             SerialTool.closePort(serialPort);  
  17.         }  
  18.     }  
  19. }  

猜你喜欢

转载自blog.csdn.net/xv1356027897/article/details/80207341