java实现与RS232串口的通信
操作前软件环境准备:
1.下载虚拟串口VSPD V6.0或V6.9,在本机上模拟串口。
2.下载友善串口测试助手,方便串口通信测试
java部分:
网上搜到有两个开源类库可以进行操作:
comm.jar(2.0版本支持windows,3.0支持linux),我测试只支持32位环境(启动时win32com.dll报错)
1.下载comm.jar、win32com.dll和javax.comm.properties。
介绍:comm.jar提供了通讯用的java API,win32com.dll提供了供comm.jar调用的本地驱动接口,javax.comm.properties是这个驱动的类配置文件
2.拷贝javacomm.jar到<JAVA_HOME>\jre\lib\ext目录下面;
3.拷贝javax.comm.properties到<JAVA_HOME>\jre\lib目录下面;
4.拷贝win32com.dll到<JAVA_HOME>\jre\bin目录下面;
RXTXComm.jar,支持64位环境
①jar包下载
https://download.****.net/download/weixin_41351690/10492338
拷贝 RXTXcomm.jar 到 <JAVA_HOME>\jre\lib\ext目录中;
拷贝 rxtxSerial.dll 到 <JAVA_HOME>\jre\bin目录中;
拷贝 rxtxParallel.dll 到 <JAVA_HOME>\jre\bin目录中;
②maven配置(同样要拷贝到jdk/jre目录下)
<dependency>
<groupId>org.bidib.jbidib.org.qbang.rxtx</groupId>
<artifactId>rxtxcomm</artifactId>
<version>2.2</version>
</dependency>
Demo:
入口:
@Test
public void test3() throws InterruptedException{
List<String> portNameList = new ArrayList<String>();
portNameList.add("COM4");
portNameList.add("COM6");
portNameList.add("COM8");
try {
/*
* Rs232Dto dto = JacksonUtil.fromJSON(
* "{\"opCode\":\"01H\",\"param1\":\"huilu\",\"param2\":\"www.baidu.com\"}",
* Rs232Dto.class); System.out.println(dto);
*/
RxtxBuilder.init(portNameList);
CommUtil comm4 = RxtxBuilder.comms.get(0);
CommUtil comm6 = RxtxBuilder.comms.get(1);
CommUtil comm8 = RxtxBuilder.comms.get(2);
while (true) {
String msg = queue.take();
if (msg.contains("4")) {
if (msg.contains("H") ) {
comm4.send("4fail");
}else {
comm4.send("4success");
}
}
if (msg.contains("6")) {
if (msg.contains("H") ) {
comm6.send("6fail");
}else {
comm6.send("6success");
}
}
if (msg.contains("8")) {
if (msg.contains("H") ) {
comm8.send("8fail");
}else {
comm8.send("8success");
}
}
Thread.sleep(100);
}
} finally {
//comm4.ClosePort(); comm6.ClosePort(); comm8.ClosePort();
}
}
串口监听响应类的构建器:
package com.star.demo.project.test;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import gnu.io.CommPortIdentifier;
public class RxtxBuilder {
static List<CommUtil> comms = new ArrayList<CommUtil>();
static void init(List<String> names) {
Enumeration portList = CommPortIdentifier.getPortIdentifiers(); // 得到当前连接上的端口
while (portList.hasMoreElements()) {
CommPortIdentifier temp = (CommPortIdentifier) portList.nextElement();
if (temp.getPortType() == CommPortIdentifier.PORT_SERIAL) {// 判断如果端口类型是串口
if (names.contains(temp.getName())) { // 判断如果端口已经启动就连接
System.err.println("端口---" + temp.getName() + "启动监听");
CommUtil comm = new CommUtil(temp, temp.getName());
comms.add(comm);
}
}
}
}
}
串口监听响应类:
package com.star.demo.project.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
public class CommUtil implements SerialPortEventListener {
InputStream inputStream; // 从串口来的输入流
OutputStream outputStream;// 向串口输出的流
SerialPort serialPort; // 串口的引用
CommPortIdentifier portId;
int count = 0;
public CommUtil(CommPortIdentifier temp ,String name) {
try {
portId = temp;
serialPort = (SerialPort) portId.open("My" + name, 2000);
} catch (PortInUseException e) {
}
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
}
try {
serialPort.addEventListener(this); // 给当前串口添加一个监听器
} catch (TooManyListenersException e) {
}
serialPort.notifyOnDataAvailable(true); // 当有数据时通知
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, // 设置串口读写参数
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
}
}
@Override
public void serialEvent(SerialPortEvent event) {
switch (event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:// 当有可用数据时读取数据,并且给串口返回数据
byte[] readBuffer = new byte[20];
try {
while (inputStream.available() > 0) {
//System.out.println("data size---"+inputStream.available());
int numBytes = inputStream.read(readBuffer);
//System.out.println("data---"+numBytes);
}
//System.out.println("content-"+ count++ +"--"+new String(readBuffer).trim());
String req = new String(readBuffer);
System.out.println(Thread.currentThread()+"---"+new String(readBuffer).trim());
UserRepositoryTests.queue.offer(req);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
public void send(String content) {
try {
outputStream.write(content.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public void ClosePort() {
if (serialPort != null) {
serialPort.close();
}
}
}