1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > java实现 串口通讯

java实现 串口通讯

时间:2018-09-05 21:34:03

相关推荐

java实现 串口通讯

参考Java实现串口通信_我不吃芹菜的博客-CSDN博客_java 串口

java 串口通讯,直接控制报警灯的灯亮和播放音乐。

报警灯接口文档:接收16进制数组 。

报警灯指令文档:

工具方法: hexToByte () 把16进制 转成 bit,传参会用到。

public static byte hexToByte(String arg) {int val = Integer.valueOf(arg, 16).intValue();byte c = (byte) (val & 0xff);return c;}

实现类 Chuankou.java

package com.hs.server;import com.hs.util.NumberUtils;import gnu.io.*;import lombok.extern.slf4j.Slf4j;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.Enumeration;/*** 串口通讯 modbus 485*/@Slf4jpublic class ChuanKou {public static SerialPort port = null;/*** 打开电脑上指定的串口** @param portName 端口名称,如 COM1,为 null 时,默认使用电脑中能用的端口中的第一个* @param b 波特率(baudrate),如 9600* @param d 数据位(datebits),如 SerialPort.DATABITS_8 = 8* @param s 停止位(stopbits),如 SerialPort.STOPBITS_1 = 1* @param p 校验位 (parity),如 SerialPort.PARITY_NONE = 0* @return 打开的串口对象,打开失败时,返回 null*/public static final SerialPort openComPort(String portName, int b, int d, int s, int p) {Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();CommPort commPort = null;try {//当没有传入可用的 com 口时,默认使用电脑中可用的 com 口中的第一个// if (portName == null || "".equals(portName)) {//List<String> comPortList = findSystemAllComPort();//if (comPortList != null && comPortList.size() > 0) {//portName = comPortList.get(0);//}// }log.info("开始打开串口:portName=" + portName + ",baudrate=" + b + ",datebits=" + d + ",stopbits=" + s + ",parity=" + p);//通过端口名称识别指定 COM 端口CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);/*** open(String TheOwner, int i):打开端口* TheOwner 自定义一个端口名称,随便自定义即可* i:打开的端口的超时时间,单位毫秒,超时则抛出异常:PortInUseException if in use.* 如果此时串口已经被占用,则抛出异常:gnu.io.PortInUseException: Unknown Application*/commPort = portIdentifier.open(portName, 5000);/*** 判断端口是不是串口* public abstract class SerialPort extends CommPort*/if (commPort instanceof SerialPort) {SerialPort serialPort = (SerialPort) commPort;port = serialPort;/*** 设置串口参数:setSerialPortParams( int b, int d, int s, int p )* b:波特率(baudrate)* d:数据位(datebits),SerialPort 支持 5,6,7,8* s:停止位(stopbits),SerialPort 支持 1,2,3* p:校验位 (parity),SerialPort 支持 0,1,2,3,4* 如果参数设置错误,则抛出异常:gnu.io.UnsupportedCommOperationException: Invalid Parameter* 此时必须关闭串口,否则下次 portIdentifier.open 时会打不开串口,因为已经被占用*/serialPort.setSerialPortParams(b, d, s, p);log.info("打开串口 " + portName + " 成功...");return serialPort;} else {log.error("当前端口 " + commPort.getName() + " 不是串口...");}} catch (NoSuchPortException e) {log.info("NoSuchPortException === ");e.printStackTrace();} catch (PortInUseException e) {log.warn("串口 " + portName + " 已经被占用,请先解除占用...");e.printStackTrace();} catch (UnsupportedCommOperationException e) {log.warn("串口参数设置错误,关闭串口,数据位[5-8]、停止位[1-3]、验证位[0-4]...");e.printStackTrace();if (commPort != null) {//此时必须关闭串口,否则下次 portIdentifier.open 时会打不开串口,因为已经被占用commPort.close();}}log.error("打开串口 " + portName + " 失败...");return null;}/*** 往串口发送数据** @param serialPort 串口对象*/public static void sendDataToComPort(SerialPort serialPort, byte[] orders) {OutputStream outputStream = null;try {if (serialPort != null) {outputStream = serialPort.getOutputStream();outputStream.write(orders);outputStream.flush();log.info("往串口 " + serialPort.getName() + " 发送数据:" + Arrays.toString(orders) + " 完成...");} else {log.error("gnu.io.SerialPort 为null,取消数据发送...");}} catch (IOException e) {e.printStackTrace();} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 关闭串口** @param serialPort 待关闭的串口对象*/public static void closeComPort(SerialPort serialPort) {if (serialPort != null) {serialPort.close();log.info("关闭串口 " + serialPort.getName());}else{log.info("串口未关闭,串口为空");}}public static void main(String[] args) {String string = Integer.toHexString(31);System.out.println(string);// SerialPort serialPort = ChuanKou.openComPort("COM7", 9600, 8, 1, 502);// byte[] orders = {01,06,31,03,00,04};// ChuanKou.sendDataToComPort(serialPort,orders);System.out.println(Integer.parseInt(string,16));;}public static void WARN(String com){if(com==null){com="COM7";}SerialPort serialPort = ChuanKou.openComPort(com, 9600, 8, 1, 0);byte[] orders = {NumberUtils.hexToByte("FF"),NumberUtils.hexToByte("06"),NumberUtils.hexToByte("11"),NumberUtils.hexToByte("03"),NumberUtils.hexToByte("00"),NumberUtils.hexToByte("04"),NumberUtils.hexToByte("68"),NumberUtils.hexToByte("EB")};ChuanKou.sendDataToComPort(serialPort,orders);ChuanKou.closeComPort(ChuanKou.port);}}

遇到的问题及解决

一、java崩溃,原因缺少RXTXcomm.jar 包 和rxtxSerial.dll 配置

no rxtxSerial64 in java.library.path thrown while loading gnu.io.RXTXCommDriver

解决:

1、将rxtxParallel.dll和rxtxSerial.dll文件放到${JAVA_HOME}(jdk目录,不是jre目录)\jre\bin目录下

如:C:\Program Files\Java\jdk1.8.0_31\jre\bin

2、将RXTXcomm.jar 包放到{JAVA_HOME}jdk目录\jre\lib\ext目录下即可

如:C:\Program Files\Java\jdk1.8.0_31\jre\lib\ext

如图:

二、jdk版本不合适

# A fatal error has been detected by the Java Runtime Environment:

java version "1.8.0_341"

Java(TM) SE Runtime Environm

See problematic frame for where to report the bug.

解决:jdk使用1.8.031版本。

相关附件传送门:

链接:/s/1OgZ-SxJwQ58riKx620P9Ew

提取码:jf98

补充:获取校验码,传入参数的前几位,获取后两位的校验码,每次换前面的参数都要重新获取校验码。比如选择绿灯红灯还是爆闪常亮。

/*** 获取校验码* crc16 X16+x15+x2+1* 16进制报文是 02 03 00 00 00 40 CRC16* 传输的str:“020300000040”* 结果:4409* @param str* @return*/public static String getCRC(String str) {byte[] bytes = NumberUtils.hexStringToBytes(str);int CRC = 0x0000ffff;int POLYNOMIAL = 0x0000a001;int i, j;for (i = 0; i < bytes.length; i++) {CRC ^= ((int) bytes[i] & 0x000000ff);for (j = 0; j < 8; j++) {if ((CRC & 0x00000001) != 0) {CRC >>= 1;CRC ^= POLYNOMIAL;} else {CRC >>= 1;}}}String crc = Integer.toHexString(CRC);if (crc.length() == 2) {crc = "00" + crc;} else if (crc.length() == 3) {crc = "0" + crc;}crc = crc.substring(2, 4) + crc.substring(0, 2);return crc.toUpperCase();}

拓展:

控制报警灯亮的时间的方法有两种:

一是选择想要播放时间长的音乐文件

二是用程序控制,亮灯指令和关灯指令,中间休息想要的时间。

public static void WARN(String com){if(com==null){com="COM7";}SerialPort serialPort = ChuanKou.openComPort(com, 9600, 8, 1, 0);byte[] orders = {NumberUtils.hexToByte("FF"),NumberUtils.hexToByte("06"),NumberUtils.hexToByte("31"),NumberUtils.hexToByte("03"),NumberUtils.hexToByte("00"),NumberUtils.hexToByte("04"),NumberUtils.hexToByte("63"),NumberUtils.hexToByte("2B")};ChuanKou.sendDataToComPort(serialPort,orders);//制定串口发送指令ChuanKou.closeComPort(ChuanKou.port);//关闭报警灯}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。