首页 > 代码库 > 串口数据上传下发

串口数据上传下发

  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 = "http://www.mamicode.com/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 = "http://www.mamicode.com/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 }

 

串口数据上传下发