串口数据上传下发

技术交流群:233513714  


1
import gnu.io.CommPortIdentifier; 2 import gnu.io.NoSuchPortException; 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 9 import java.io.IOException; 10 import java.io.InputStream; 11 import java.io.OutputStream; 12 import java.util.ArrayList; 13 import java.util.List; 14 import java.util.TooManyListenersException; 15 16 import org.springframework.stereotype.Controller; 17 import org.springframework.web.bind.annotation.RequestMapping; 18 19 import com.aotoso.control.Log.Log; 20 import com.aotoso.control.base.BaseController; 21 import com.aotoso.entity.FirstInformationManage.CarManageBean; 22 import com.aotoso.server.FirstInformationManage.CarManageService; 23 import com.aotoso.util.PageData; 24 25 /** 26 * 处理下发、串口上传的数据 27 */ 28 @Controller 29 @RequestMapping("/com") 30 public class PortCommunication extends BaseController implements SerialPortEventListener { 31   // 获取串口 32   public static SerialPort serialPort; 33   // 创建输入流,用于获取串口传入的数据 34   private InputStream inputStream; 35 36   /** 37   * 打开串口 38   * @return 39   */ 40   @RequestMapping(value = "/openCOM") 41   public SerialPort OpenCOM(){ 42     System.out.println("打开串口"); 43     try { 44       //找到串口名称为COM3的串口 45       CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier("COM3"); 46       //设置串口通信名称(名称是随意命名的),阻塞时的毫秒数 47       serialPort = (SerialPort)portIdentifier.open("TMR饲喂监控系统串口通信", 2000); 48       //获取串口输入流 49       inputStream = serialPort.getInputStream(); 50       //在打开串口的同时开启监听串口事件 51       serialPort.addEventListener(this); 52       //设置串口有数据的事件,当为true时有效 53       serialPort.notifyOnDataAvailable(true); 54       //设置串口通信参数,波特率9600、数据位8、停止位1、校验方式0表示无 55       serialPort.setSerialPortParams(9600, 8, 1, 0); 56       //设置流量控制为不受控制 57       serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); 58       return serialPort; 59     } catch (NoSuchPortException e) { 60       System.out.println("端口不存在"); 61     } catch (PortInUseException e) { 62       System.out.println("端口已经被占用"); 63     } catch (UnsupportedCommOperationException e) { 64       System.out.println("端口操作命令不支持"); 65     } catch (TooManyListenersException e) { 66       System.out.println("端口中数据读取异常"); 67     } catch (IOException e) { 68       System.out.println("输入或输出异常"); 69     } 70     return null; 71   } 72 73   /** 74   * 关闭串口 75   */ 76   @RequestMapping(value = "/CloseCom") 77   public void CloseCom(){ 78     System.out.println("关闭串口"); 79     serialPort.close(); 80   } 81 82   /** 83   * 发送数据 84   * @param by 85   */ 86   public void outputInformationToTMR(byte[] by) { 87     try{ 88       //准备一个输出流 89       OutputStream outputStream = serialPort.getOutputStream(); 90       //向串口传送数据 91       outputStream.write(by); 92       //刷新此输出流并强制写出所有缓冲的输出字节 93       outputStream.flush(); 94       //关闭输出流并释放所有和此流有关的系统资源 95       outputStream.close(); 96     } catch (IOException e) { 97       System.out.println("端口打开异常"); 98     } 99   } 100 101   /** 102   * 监听串口(此方法继承自SerialPortEventListener) 103   */ 104   @Override 105   public void serialEvent(SerialPortEvent event) { 106     switch (event.getEventType()) { 107     case SerialPortEvent.BI: //通信中断 108     case SerialPortEvent.OE: //溢位错误 109     case SerialPortEvent.FE: //帧错误 110     case SerialPortEvent.PE: //奇偶错误 111     case SerialPortEvent.CD: //载波错误 112     case SerialPortEvent.CTS: //清除发送 113     case SerialPortEvent.DSR: //数据设备准备好 114     case SerialPortEvent.RI: //振铃错误 115     case SerialPortEvent.OUTPUT_BUFFER_EMPTY: //输出缓冲区已清空 116       break; 117     case SerialPortEvent.DATA_AVAILABLE: //有数据到达 118       readCom(); 119       Log.LogForTXT(""); 120       break; 121     } 122   } 123 124   /** 125   * 接收串口中的数据 126   */ 127   public void readCom(){ 128     try { 129       //等待1毫秒,以便让数据读取完整 130       Thread.sleep(100); 131     } catch (InterruptedException e1) { 132       e1.printStackTrace(); 133     } 134     // buffer中的实际数据字节数 135     int numBytes = 0; 136     // 4k的buffer空间,缓存串口读入的数据 137     byte[] readBuffer = new byte[4096]; 138     try { 139       // 多次读取,将所有数据读入 140       while (inputStream.available() > 0) { 141         numBytes = inputStream.read(readBuffer); 142       } 143     } catch (Exception e) { 144       e.printStackTrace(); 145     } 146     System.out.println(bytesToHexString(readBuffer)); 147   } 148 149   /** 150   * 将Hex格式的数据转换为16进制的字符串 151   * @param by 152   * @return string 153   */ 154   public String bytesToHexString(byte[] by){ 155     StringBuilder stringBuilder = new StringBuilder(""); 156     for (int i = 0; i < by.length; i++) { 157       int in = by[i] & 0xFF; 158       String str = Integer.toHexString(in); 159       if (str.length() < 2) { 160         stringBuilder.append(0); 161       } 162       stringBuilder.append(str); 163     } 164     return stringBuilder.toString(); 165   } 166 }
原文地址:https://www.cnblogs.com/cnndevelop/p/6034420.html