maven依赖:
<dependency>
<groupId>io.github.java-native</groupId>
<artifactId>jssc</artifactId>
<version>2.9.4</version>
</dependency>
代码示例:
package com.hs.modbusstu.utils;
import jssc.SerialPort;
import jssc.SerialPortException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* jssc工具类
*/
public class JsscUtilSingleton {
public static final String HEX_PLACE_HOLDER = "0";
/**
* 十六进制进位阈值
*/
public static final int HEX_CARRY_THRESHOLD = 15;
private static class JsscUtil {
public static final JsscUtilSingleton JSSC_UTIL_SINGLETON = new JsscUtilSingleton();
}
public static JsscUtilSingleton getInstance() {
return JsscUtil.JSSC_UTIL_SINGLETON;
}
/**
* 发送数据
* 统一发送指令的方法
*
* @param serialPort
* @param bytes 命令字节数组
*/
public static List<String> sendData(SerialPort serialPort, byte[] bytes) {
if (serialPort != null && serialPort.isOpened()) {
try {
serialPort.writeBytes(bytes);
// 延时时间,50ms多次测试最稳当
Thread.sleep(50);
// 读取命令返回数据
String[] resCode = serialPort.readHexStringArray();
if (resCode == null || resCode.length == 0) {
return Collections.emptyList();
} else {
System.out.println("命令发送后的返回值: " + Arrays.toString(resCode));
return Arrays.asList(resCode);
}
} catch (SerialPortException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return Collections.emptyList();
}
public static String sendDataResStr(SerialPort serialPort, byte[] bytes) {
if (serialPort != null && serialPort.isOpened()) {
try {
serialPort.writeBytes(bytes);
// 延时时间,50ms多次测试最稳当
Thread.sleep(50);
// 读取命令返回数据
String resCode = serialPort.readHexString();
if (resCode == null || resCode.isEmpty()) {
return null;
} else {
System.out.println("命令发送后的返回值: " + resCode);
return resCode.replaceAll(" ", "");
}
} catch (SerialPortException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return null;
}
/**
* jssc链接端口
*
* @param portName
* @param baudRate
* @return
*/
public SerialPort openSerialPort(String portName, int baudRate) {
final SerialPort serialPort = new SerialPort(portName);
try {
serialPort.openPort();
serialPort.setParams(baudRate, 8, 1, 0);
if (serialPort.isOpened()) {
System.out.println("打开串口: " + serialPort.getPortName());
}
} catch (SerialPortException e) {
throw new RuntimeException(e);
}
return serialPort;
}
/**
* 关闭端口
*
* @param serialPort
* @return
*/
public static boolean closePort(final SerialPort serialPort) {
try {
return serialPort.closePort();
} catch (SerialPortException e) {
throw new RuntimeException(e);
}
}
/**
* 获取校验和
* 光谱仪
*
* @param lengthHigh
* @param lengthLow
* @param commandId
* @param dataHigh
* @param dataLow
* @return
*/
public static String getChecksum(int lengthHigh, int lengthLow, int commandId, int dataHigh, int dataLow) {
// 求和
int sumRes = lengthHigh + lengthLow + commandId + dataHigh + dataLow;
int check = sumRes & 0xFF;
System.out.println("check is: " + check);
String checkStr = Integer.toHexString(check);
if (check > HEX_CARRY_THRESHOLD) {
return checkStr;
} else {
return HEX_PLACE_HOLDER + checkStr;
}
}
/**
* 初始化命令
* 光谱仪
*
* @param commandId
* @param data
* @return
*/
public static String generateCommand(int commandId, int data) {
int dataLength = 0;
if (data > 0) {
// 当data有数据的时候则,数据位两位
dataLength = 2;
}
// 从length到checksum
int length = 4 + dataLength;
int lengthHigh = (length >> 8) & 0xFF;
// 低位
int lengthlow = length & 0xFF;
// 数据高位
int dataHigh = (data >> 8) & 0xFF;
int dataLow = data & 0xFF;
// 计算checksum
String checkSum = getChecksum(lengthHigh, lengthlow, commandId, dataHigh, dataLow);
System.out.println("checkSum is: " + checkSum);
// 构造命令
StringBuilder commandStr = new StringBuilder("AA,55")
// 设置长度length
.append(lengthHigh <= 0 ? "00" : (lengthHigh > 15 ? Integer.toHexString(lengthHigh) : "0" + Integer.toHexString(lengthHigh)))
.append(lengthlow <= 0 ? "00" : (lengthlow > 15 ? Integer.toHexString(lengthlow) : "0" + Integer.toHexString(lengthlow)))
// commandId
.append(commandId > 15 ? Integer.toHexString(commandId) : "0" + Integer.toHexString(commandId));
// 如果0存在
if (data > 0) {
commandStr.append(dataHigh > 15 ? Integer.toHexString(dataHigh) : "0" + Integer.toHexString(dataHigh))
.append(dataLow > 15 ? Integer.toHexString(dataLow) : "0" + Integer.toHexString(dataLow));
}
//.append(dataHigh <= 0 ? "00" : (dataHigh > 15 ? Integer.toHexString(dataHigh) : "0" + Integer.toHexString(dataHigh)))
//.append(dataLow <= 0 ? "00" : (dataLow > 15 ? Integer.toHexString(dataLow) : "0" + Integer.toHexString(dataLow)))
// 设置checksum
commandStr.append(checkSum);
return commandStr.toString();
}
/**
* 光谱仪发送命令封装
*
* @param commandId
* @param data
* @return
*/
public static String spectrometerSendCommand(SerialPort serialPort, int commandId, int data) {
// 构造命令字符串
String commandStr = generateCommand(commandId, data);
System.out.println("发送字符串命令: " + commandStr);
// 十六进制字符串转字节数组
byte[] command = hexStringToByteArray(commandStr);
// 发送命令
String resStr = sendDataResStr(serialPort, command);
System.out.println("返回字符串为:" + resStr);
// 光谱仪设置积分时间,如果第一次没发送成功则重新调用一次发送命令方法
if (resStr == null) {
resStr = JsscUtilSingleton.sendDataResStr(serialPort, command);
}
// 切出返回数据
String dataStr = resStr.substring(10, resStr.length() - 2);
System.out.println("切片出data值为: " + dataStr);
return dataStr;
}
/**
* 16进制转Ascii
*
* @param hexStr
* @return
*/
public static String hexToAscii(String hexStr) {
StringBuilder output = new StringBuilder("");
for (int i = 0; i < hexStr.length(); i += 2) {
String str = hexStr.substring(i, i + 2);
output.append((char) Integer.parseInt(str, 16));
}
return output.toString();
}
/**
* 16进制表示的字符串转换为字节数组
*
* @param hexString 16进制表示的字符串
* @return byte[] 字节数组
*/
public static byte[] hexStringToByteArray(String hexString) {
hexString = hexString.replaceAll(",", "");
int len = hexString.length();
byte[] bytes = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
// 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个字节
bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
.digit(hexString.charAt(i + 1), 16));
}
return bytes;
}
}
这篇博客介绍了如何在Java开发中进行串口通信,提供了详细的maven依赖信息,并展示了具体的代码示例。
1599

被折叠的 条评论
为什么被折叠?



