java RXTX实现串口通信。可发送命令,但是无法获取到串口返回值

Dracula979 2017-03-06 05:48:56
代码如下:


package com.boco.util;
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 java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.CharBuffer;
import java.util.Random;


/**
* 串口操作实现类
* @author Anlw
*
*/
public class Port implements SerialPortEventListener {
private CommPortIdentifier portId;
private SerialPort serialPort;
private OutputStreamWriter out;
private InputStreamReader in;
private String COMname;

public String getCOMname() {
return COMname;
}

public void setCOMname(String mname) {
COMname = mname;
}

public CommPortIdentifier getPortId() {
return portId;
}

public void setPortId(CommPortIdentifier portId) {
this.portId = portId;
}

public SerialPort getSerialPort() {
return serialPort;
}

public void setSerialPort(SerialPort serialPort) {
this.serialPort = serialPort;
}

public OutputStreamWriter getOut() {
return out;
}

public void setOut(OutputStreamWriter out) {
this.out = out;
}

public InputStreamReader getIn() {
return in;
}

public void setIn(InputStreamReader in) {
this.in = in;
}

public boolean isused = true;

public boolean isIsused() {
return isused;
}

public void setIsused(boolean isused) {
this.isused = isused;
}


/**
* 构造器打开com口
* @param portName
* @return
*/
public Port(String portName) {
try {
portId = CommPortIdentifier.getPortIdentifier(portName);
if (portId == null) {
System.out.println("port is null");
}
try {
serialPort = (SerialPort) portId.open(getrechargeablePassword(), 20000);
} catch (PortInUseException e) {
System.gc();
System.out.println("COM端口被占用,请选择正确的COM端口!!");
}
// 下面是初始化COM口的传输参数,如传输速率:9600等
try {
serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
setCOMname(portId.getName());
setIsused(true);
} catch (Exception e) {
System.gc();
}
// 下面是得到用于和COM口通讯的输入、输出流。
try {
out = new OutputStreamWriter(serialPort.getOutputStream());
// serialPort.setRTS(true);
in = new InputStreamReader(serialPort.getInputStream());
// //向串口添加事件监听对象。
// serialPort.addEventListener(this);
// //设置当端口有可用数据时触发事件,此设置必不可少。
// serialPort.notifyOnDataAvailable(true);

} catch (Exception e) {
System.gc();
}


} catch (NoSuchPortException e) {
System.gc();
System.out.println("无此COM端口,请选择正确的COM端口!!");
}
}

// 获取密码
public static String getrechargeablePassword() {
Random random = new Random();
char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'c',
'b', 'd', 'f', 'e', 'g', 'h', 'j', 'i', 'l', 'k', 'n', 'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'w',
'v' };
String strRand = "";
for (int i = 0; i < 18; i++) {
strRand = strRand + String.valueOf(codeSequence[random.nextInt(59)]);
}
return strRand;
}

/**
* 关闭COM口
* @return boolean
*/
public void close() {
try {
in.close();
out.close();
serialPort.close();
System.gc();
setIsused(false);
} catch (Exception e) {
}

}

/**
* 向串口中写入字符串命令
* @param s 字符串命令
* @throws Exception 异常
*/
public void writeln(String s) throws Exception {
out.write(s);
out.write('\r');
out.flush();

}

/**
* 读取COM命令的返回字符串
* @return 结果字符串
* @throws Exception
*/
public String read(){
int n, i;
char c;
String answer = "";
for (i = 0; i < 100; i++) {
try {
while (in.ready()) {
n = in.read();
if (n != -1) {
c = (char) n;
answer = answer + c;

Thread.sleep(1);
} else
break;
}
if(!"".equals(answer)){
System.out.println(answer);
}
Thread.sleep(100);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (answer.indexOf("OK") != -1) {
break;
}

}
return answer;
}

/**
* 向串口发送AT指令
* @param atcommand 指令内容
* @return 指令返回结果
* @throws java.rmi.RemoteException
*/
public String sendAT(String atcommand) throws java.rmi.RemoteException {
String returnStr = "";
try {
Thread.sleep(100);
writeln(atcommand);
System.out.println(atcommand);
Thread.sleep(800);
returnStr = read();
System.out.println(returnStr+"---AT返回值");
Thread.sleep(150);
} catch (Exception e) {
System.gc();
}
return returnStr;
}


//监听注释了,和没有用监听一个道理获取不到返回值
@Override
public void serialEvent(SerialPortEvent event) {
System.out.println("进入监听!");

switch (event.getEventType()) {
case SerialPortEvent.BI:
System.out.println("通讯中断");
case SerialPortEvent.OE:
System.out.println("溢位错误");
case SerialPortEvent.FE:
System.out.println("帧错误");
case SerialPortEvent.PE:
System.out.println("奇偶校验错");
case SerialPortEvent.CD:
System.out.println("载波检测");
case SerialPortEvent.CTS:
System.out.println("清除发送");
case SerialPortEvent.DSR:
System.out.println("数据设备准备好");
case SerialPortEvent.RI:
System.out.println("振铃指示");
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
System.out.println("输出缓冲区已清空");
break;
case SerialPortEvent.DATA_AVAILABLE:
try{
int n, i;
char c;
String answer = "";
for (i = 0; i < 100; i++) {
while (in.ready()) {
n = in.read();
//System.out.println(n+"--n的值");
if (n != -1) {
c = (char) n;
answer = answer + c;

} else
break;
}
if(answer!=""&&!answer.equals(""));
System.out.println(answer);
// if (answer.indexOf("OK") != -1) {
// break;
// }
}
}catch(Exception e){
e.printStackTrace();
}
break;
}
}

}
...全文
634 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
do_wa5810 2020-06-18
  • 打赏
  • 举报
回复
串口工具类一般问题不大,CSDN里就有很多,不过看你这个好像有点问题,添加串口监听,检查一下你发送的报文是否正确,发送的时候一般都是按16进制发送,才会返回正确数据,读取串口数据,字符串转换
qq_37159170 2017-04-11
  • 打赏
  • 举报
回复
我也遇到这样的问题,楼主解决了吗
Dracula979 2017-03-07
  • 打赏
  • 举报
回复
大神在哪里啊!!

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧