Linux/windows com串口 java 接收数据 并解析 web程序
1.首先应公司要求再 com 口本来使用 .net 由于 .net 适用 linux 太麻烦 改为java
准备工作 准备 RXTXconmm.jar(版本很重要) 因为版本问题我搞了一天。
主要讲述linux 系统使用串口(windows 比 linux 更简单)
话不多说直接上代码
@RequestMapping(value = "/porttest",method ={RequestMethod.POST,RequestMethod.GET}) @ResponseBody public void porttest(DevicesEntity devices,HttpServletRequest request) { serialPortTest ss=new serialPortTest(); ss.searchSerialPort(); // 搜索串口 ss.connectSerialPort(); // 连接串口 }
public void connectSerialPort() { // TODO Auto-generated method stub String comName; if (mListComName.size() > 0) { comName = mListComName.get(0); String PortName = comName; String rate_value = serialPortParms.RATE[1]; String databit_value = serialPortParms.DATABIT[0]; String stopbit_value = serialPortParms.STOPBIT[0]; HashMap<String, Comparable> params = new HashMap<String, Comparable>(); System.out.println(PortName+"!!!!!!!!!!!!!!!!!!!!!!!!!!"); int parityInt = SerialPort.PARITY_NONE; params.put(serialReader.PARAMS_PORT, PortName); // 端口名称 params.put(serialReader.PARAMS_RATE, rate_value); // 波特率 params.put(serialReader.PARAMS_DATABITS, databit_value); // 数据位 params.put(serialReader.PARAMS_STOPBITS, stopbit_value); // 停止位 params.put(serialReader.PARAMS_PARITY, parityInt); // 无奇偶校验 params.put(serialReader.PARAMS_TIMEOUT, 100); // 设备超时时间 1秒 params.put(serialReader.PARAMS_DELAY, 100); // 端口数据准备时间 1秒 try { sr.open(params); sr.addObserver(serialPortTest.this); System.out.println(PortName + ":已经打开"); } catch (Exception e1) { System.out.println("端口被占用"); } } }
package ClientDemo; import gnu.io.CommPort; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException; import static com.jeecg.common.DateUtil.getNowDate; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Observable; import java.util.TooManyListenersException; import org.apache.log4j.Logger; import org.jeecgframework.web.system.service.SystemService; import org.springframework.beans.factory.annotation.Autowired; import com.jeecg.pdwsn.entity.ChannelsEntity; import com.jeecg.pdwsn.entity.DataEntity; import com.jeecg.pdwsn.entity.DevicesEntity; import com.jeecg.pdwsn.entity.SensorsEntity; import com.jeecg.pdwsn.entity.WarningEntity; import com.jeecg.pdwsn.service.DevicesServiceI; import com.jeecg.pdwsn.service.SensorsServiceI; import com.jeecg.pdwsn.service.impl.DevicesServiceImpl; public class serialReader extends Observable implements Runnable, SerialPortEventListener { private static final Logger logger = Logger.getLogger(DevicesServiceImpl.class); static CommPortIdentifier portId; int delayRead = 100; int numBytes; // private static byte[] readBuffer = new byte[1024]; // //private static char[] readBuffer = new char[1024]; static Enumeration portList; InputStream inputStream; OutputStream outputStream; static SerialPort serialPort; HashMap serialParams; Thread readThread; boolean isOpen = false; public static final String PARAMS_DELAY = "delay read"; // public static final String PARAMS_TIMEOUT = "timeout"; // 超时时间 public static final String PARAMS_PORT = "port name"; // 端口名称 public static final String PARAMS_DATABITS = "data bits"; // public static final String PARAMS_STOPBITS = "stop bits"; // public static final String PARAMS_PARITY = "parity"; // 奇偶校验 public static final String PARAMS_RATE = "rate"; // private HashMap<Byte, byte[]> map; public boolean isOpen() { return isOpen; } /** * 初始化端口操作的参数. * * @throws SerialPortException * * @see */ public serialReader() { isOpen = false; } public void open(HashMap params) throws NoSuchPortException, PortInUseException, IOException, UnsupportedCommOperationException, TooManyListenersException { serialParams = params; if (isOpen) { close(); } /* try { */ // 参数初始 int timeout = Integer.parseInt(serialParams.get(PARAMS_TIMEOUT) .toString()); int rate = Integer.parseInt(serialParams.get(PARAMS_RATE).toString()); int dataBits = Integer.parseInt(serialParams.get(PARAMS_DATABITS) .toString()); int stopBits = Integer.parseInt(serialParams.get(PARAMS_STOPBITS) .toString()); int parity = Integer.parseInt(serialParams.get(PARAMS_PARITY) .toString()); delayRead = Integer.parseInt(serialParams.get(PARAMS_DELAY).toString()); String port = serialParams.get(PARAMS_PORT).toString(); // 打开端口 portId = CommPortIdentifier.getPortIdentifier(port); serialPort = (SerialPort) portId.open("SerialReader", timeout); inputStream = serialPort.getInputStream(); serialPort.addEventListener(this); serialPort.notifyOnDataAvailable(true); serialPort.setSerialPortParams(rate, dataBits, stopBits, parity); isOpen = true; /* * } catch (PortInUseException e) { // * 端口"+serialParams.get( PARAMS_PORT ).toString()+"已经被占�?; * * } catch (TooManyListenersException e) { // "端口"+serialParams.get( * PARAMS_PORT ).toString()+"监听者过�?; } catch * (UnsupportedCommOperationException e) { // "端口操作命令不支�?; } catch * (NoSuchPortException e) { // "端口"+serialParams.get( PARAMS_PORT * ).toString()+"不存�?; } catch (IOException e) { // * "打开端口"+serialParams.get( PARAMS_PORT ).toString()+"失败"; } */ serialParams.clear(); /* Thread readThread = new Thread(this); readThread.start();*/ } public void run() { try { Thread.sleep(50); } catch (InterruptedException e) { } } public void start() { try { outputStream = serialPort.getOutputStream(); } catch (IOException e) { } try { readThread = new Thread(this); readThread.start(); } catch (Exception e) { } } // start() end public void run(byte[] message) { try { Thread.sleep(4); } catch (InterruptedException e) { } try { if (message != null) { System.out.println("run message:" + message); outputStream.write(message); } } catch (IOException e) { } } public void close() { if (isOpen) { try { serialPort.notifyOnDataAvailable(false); serialPort.removeEventListener(); inputStream.close(); serialPort.close(); isOpen = false; } catch (IOException ex) { // "关闭串口失败"; } } } TempHumidity tempHumidity = new TempHumidity(); private List<Double> fValue = new ArrayList<Double>(); // 温度值 //char[] hex2char = hex.toCharArray(); int[] buffer = new int[8192]; int[] bufTmp = new int[2048]; // 接收数据缓冲区2 int dataLen = 0; // 接收数据的总长度 int step = 0; // 解析步骤 int readBytes=0; List<Double> splitt=new ArrayList<Double>(); @Override public void serialEvent(SerialPortEvent event) { // TODO Auto-generated method stub try { Thread.sleep(delayRead); } catch (InterruptedException e) { e.printStackTrace(); } switch (event.getEventType()) { case SerialPortEvent.BI: // 10 case SerialPortEvent.OE: // 7 case SerialPortEvent.FE: // 9 case SerialPortEvent.PE: // 8 case SerialPortEvent.CD: // 6 case SerialPortEvent.CTS: // 3 case SerialPortEvent.DSR: // 4 case SerialPortEvent.RI: // 5 case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 break; case SerialPortEvent.DATA_AVAILABLE: // 1 int len=readBuffer.length; int count=0; try { // 多次读取,将所有数据读 while (inputStream.available() > 0) { count++; readBuffer = new byte[inputStream.available()]; numBytes =inputStream.read(readBuffer); //readBuffer System.out.println("readBuffer"+new char[inputStream.available()]+"SSsssssssssssssss"+numBytes); } // 打印接收到的字节数据 //System.out.println("长度"+readBuffer[]+"readBuffer.toString();"+readBuffer.toString()); int[] iBuffer = new int[8192]; for (int i = 0; i < numBytes; i++) { //System.out.println(); /* changeMessage(readBuffer, numBytes);*/ //iBuffer[i] = ((byte)readBuffer[i] & 0xff); buffer[dataLen] = ((byte)readBuffer[i] & 0xff); System.out.println("原始数据\t\t\t"+ buffer[dataLen]); logger.info("原始数据\t\t\t"+ buffer[dataLen]); switch (step) { case 0: //AA=170 if (0xAA == buffer[0]) { step++; dataLen++; } else { step = 0; dataLen = 0; } break; case 1: step++; dataLen++; break; case 2: dataLen++; if (dataLen >= buffer[1] + 2) { step++; } break; case 3: //bb 十进制187 if (0xBB == buffer[dataLen]) { //0f =15 十进制 //System.out.println("温度湿度"+buffer[1]); if (buffer[1] < 0x0F) {// 温湿度 for (int j = 0; j < buffer[1]-4; j++) { bufTmp[j] = buffer[j + 4]; //System.out.println("温度湿度"+buffer[j + 4]); } System.out.println("进入温湿度"); AnalysisWenShiDu(8); //logger.info( "完整数据3 1"+iBuffer[i]); //logger.log(null, "AnalysisWenShiDu"); //System.out.println("AnalysisWenShiDu"); } else {// 电缆数据 for (int j = 0; j < buffer[1] - 2; j++) { bufTmp[j] = buffer[j + 2];// 除去包头、长度、尾的数据 //System.out.println(buffer[j + 2]+"除去包头、长度、尾的数据"); } // System.out.println( "当前次数"+bufTmp[2]+"bufTmpbufTmpbufTmp\t\t "+bufTmp[i] ); logger.info("当前次数"+bufTmp[2]+"bufTmpbufTmpbufTmp\t\t "+bufTmp[i]); // System.out.println( "bufTmpbufTmpbufTmp222\t\t "+bufTmp[2] ); AnalysisData(bufTmp,bufTmp[2]); if (bufTmp[2] == 8) {// 第八条电缆数据 ///插入数据; StringBuffer sssss=new StringBuffer(); for (int j = 0; j < splitt.size(); j++) { sssss.append(splitt.get(j)+";"); } HttpPostUtil.getHanYuanUtils("http://localhost:8080/jeecg/rest/webshishishuju/fasong?sssss="+sssss); splitt.clear(); splitt = new ArrayList(); dataLen = 0; } } } step = 0; dataLen = 0; break; default: step = 0; dataLen = 0; break; } } } catch (IOException e) { e.printStackTrace(); } break; } } int cou=0; @Autowired DevicesServiceI devicesService; @Autowired private SystemService systemService; @Autowired private SensorsServiceI sensorsServiceI; /* public List diaoyong() { return splitt; }*/ private List AnalysisData(int [] bufTmp2,int curGP) { try { //System.out.println("bufTmp2[1]原始数据"+bufTmp2[1]); //bufTmp2[4] == 20 int len = bufTmp2[4] * 2; int temp = 0; Double ftemp = 0.0; // 长度40 for (int i = 5; i < len +5; i++) { if (i % 2 == 1) { temp = bufTmp2[i] << 8; temp += bufTmp2[i + 1]; //System.out.println("bufTmp2[i]"+bufTmp2[i]); // System.out.println("temp"+temp); int st = temp; // System.out.println("ststst"+st); if (st > 0) { ftemp = st * 0.0625; } else if (st < 0) { ftemp = -(~st + 1) * 0.0625; } else if (st == 0) { ftemp = 0.0; } System.out.println(ftemp+"ftemp"); splitt.add(Double.parseDouble(new DecimalFormat("0.00").format(ftemp))); i += 1; } } } catch (Exception e) { } return fValue; } // List<Double> wd=new ArrayList<Double>(); private List AnalysisWenShiDu(int len) { // 仓内温湿度(T1H T1L H1H H1L) // 仓外温湿度(T2H T2L H2H H2L) tempHumidity.in_temp = GetFloat1(bufTmp[0], bufTmp[1]); tempHumidity.in_humidity = GetFloat1(bufTmp[2], bufTmp[3]); double a=GetFloat1(bufTmp[0], bufTmp[1]); double b=GetFloat1(bufTmp[2], bufTmp[3]); double c=GetFloat1(bufTmp[4], bufTmp[5]); double d=GetFloat1(bufTmp[6], bufTmp[7]); System.out.println("a温度"+a+"b湿度"+b); tempHumidity.out_temp = GetFloat1(bufTmp[4], bufTmp[5]); tempHumidity.out_humidity = GetFloat1(bufTmp[6], bufTmp[7]); splitt.add(Double.parseDouble(new DecimalFormat("0.00").format(a))); splitt.add(Double.parseDouble(new DecimalFormat("0.00").format(b))); splitt.add(Double.parseDouble(new DecimalFormat("0.00").format(c))); splitt.add(Double.parseDouble(new DecimalFormat("0.00").format(d))); return splitt; } public static void main(String[] args) { int temp=0; temp = 170 << 8; // System.out.println(temp+"temp"); } private float GetFloat1(int bufTmp2,int bufTmp3) { int temp = 0; float ftemp = 0f; temp = bufTmp2 << 8; temp += bufTmp3; int st = temp; if (st > 0) { ftemp = st * 0.1f; } else if (st < 0) { ftemp = (0xFFFF - temp) * 0.1f; } else if (st == 0) { ftemp = 0; } //System.out.println("温度湿度!!!!!!!!!!!!!!!!!!!!!!!!!"+ftemp); return ftemp; } // 通过observer pattern将收到的数据给observer // 将buffer中的空字节删除后再发送更新消息通知观察者 public void changeMessage(byte[] message, int length) { boolean flag = false; byte type = message[3]; setChanged(); notifyObservers(message); } static void listPorts() { Enumeration portEnum = CommPortIdentifier.getPortIdentifiers(); while (portEnum.hasMoreElements()) { CommPortIdentifier portIdentifier = (CommPortIdentifier) portEnum .nextElement(); } } static String getPortTypeName(int portType) { switch (portType) { case CommPortIdentifier.PORT_I2C: return "I2C"; case CommPortIdentifier.PORT_PARALLEL: return "Parallel"; case CommPortIdentifier.PORT_RAW: return "Raw"; case CommPortIdentifier.PORT_RS485: return "RS485"; case CommPortIdentifier.PORT_SERIAL: return "Serial"; default: return "unknown type"; } } public HashSet<CommPortIdentifier> getAvailableSerialPorts()// 本来static { HashSet<CommPortIdentifier> h = new HashSet<CommPortIdentifier>(); Enumeration thePorts = CommPortIdentifier.getPortIdentifiers(); while (thePorts.hasMoreElements()) { CommPortIdentifier com = (CommPortIdentifier) thePorts .nextElement(); switch (com.getPortType()) { case CommPortIdentifier.PORT_SERIAL: try { CommPort thePort = com.open("CommUtil", 50); thePort.close(); h.add(com); } catch (PortInUseException e) { System.out.println("Port, " + com.getName() + ", is in use."); } catch (Exception e) { System.out.println("Failed to open port " + com.getName() + e); } } } return h; } public class TempHumidity { public float in_temp; // 舱内温度 public float in_humidity; // 舱内湿度 public float out_temp; public float out_humidity; } }
public class serialPortParms { public static final String[] RATE = { "115200", "9600", "4800", "2400" }; public static final String[] DATABIT = { "8", "7", "6", "5" }; public static final String[] STOPBIT = { "1", "1.5", "2" }; }
如果解析失败 查看 RXTXconmm.jar 版本
技术交流qq 1552138571
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】