200分求教串口方面问题,搞定我会再加200分,请大家来帮忙

config_man 2010-06-11 08:14:56
现在我要通过代码发送一组命令给一个设备,发送成功后会有返回值。
在写代码之前用了相关的工具进行测试【主要测试硬件之间的通讯是否正常】,发送命令为“aa00dd0000000055”,当这条命令发送成功后,会有一个返回值,为“FC AA 00 DD 03 00 00 55 55”。
经检测,硬件是没有问题的。因为我要自己写下这个过程,所以我用代码写了这个过程,但是在获得返回值方面存在问题,搞了好长时间也没解决。
所以想问大家,要想得到“FC AA 00 DD 03 00 00 55 55”这样的返回值,代码该如何写?

附代码如下:

package main;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;

public class Main66 {

static Enumeration portList;
static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream outputStream;
static InputStream inputStream;
static BufferedReader br;
static boolean flag = false;
static boolean isPlay = false;

/**
* 红外感应到有人,投影机播放内容,讲到哪个地方,沙盘中对应地址的路灯亮。
*/
public static void main(String[] args) {
controlInfrared();
}

/**
* 红外人体感应
* @throws Exception
*/
public static void controlInfrared() {
try {
//aa00db0100000055 测试灯的命令
//aa00dd0000000055 测试红外命令
byte[] bt = new byte[]{(byte)0xaa,(byte)0x00,(byte)0xdd,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x55};

portId = CommPortIdentifier.getPortIdentifier("COM1");
//打开通讯
serialPort = (SerialPort)portId.open("SimpleWriteApp", 2000);
serialPort.setRTS(true);
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

//打开输出流,写入命令
outputStream = serialPort.getOutputStream();
outputStream.write(bt);
outputStream.flush();


//获得输出流
inputStream = serialPort.getInputStream();

//下面的代码该如何写,才能获得“FC AA 00 DD 03 00 00 55 55”这样的返回值?



outputStream.close();
serialPort.close();

}catch (Exception e) {
e.printStackTrace();
} finally{
//关闭流和端口
try {
if(outputStream != null){
outputStream.close();
}
if(serialPort != null){
serialPort.close();
}
}catch(Exception e){
System.out.println("关闭端口时异常出现:"+e.getMessage());
}
}
}
}



为了方便大家,我尽可能的把一些信息先发出来给大家看。
如果在上面的输入流中用如下方法:
//方法一
byte[] bt2 = new byte[30];
inputStream.read(bt2);
for(byte b : bt2){
System.out.println(b);
}

//方法二
byte[] bt3 = new byte[30];
while(inputStream.available()>0){
inputStream.read(bt3);
}
for(byte b : bt3){
System.out.println(b);
}

//方法三
byte[] bt4 = new byte[30];
int len = 0;
while((len=inputStream.read()) != -1){
inputStream.read(bt4, 0, len);
}
for(byte b : bt4){
System.out.println(b);
}
用上面的3中方法打印的结果都是0 0 0 0.......

**************************************************************************************
如果下面的方法,会报异常
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line=br.readLine()) != null){
System.out.println(line);
}

java.io.IOException: Underlying input stream returned zero bytes
at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at main.Main2.controlInfrared(Main2.java:57)
at main.Main2.main(Main2.java:27)


PS:以前一直用javax.comm包与串口进行通讯,但是今天再用这个时出了点问题,于是改成了用rxtx。
...全文
852 68 打赏 收藏 转发到动态 举报
写回复
用AI写文章
68 条回复
切换为时间正序
请发表友善的回复…
发表回复
config_man 2010-06-30
  • 打赏
  • 举报
回复
今天下午的时候,终于搞定了。感谢各位的支持。
现将代码公布如下:

package com.main2;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

public class Test extends Thread implements SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
static InputStream inputStream;
static OutputStream outputStream;
static SerialPort serialPort;
static int count = 0;

public static void main(String[] args) {
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals("COM3")) {
Test test = new Test();
}
}
}
}

public Test() {
try {
//打开通讯
serialPort = (SerialPort) portId.open("ReadCommApp", 2000);
serialPort.setRTS(false);//此步骤可以省略,猜测默认情况即是false

serialPort.setSerialPortParams(2400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

byte[] bt = new byte[]{(byte)0xaa,(byte)0x00,(byte)0xdd,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x55};

outputStream = serialPort.getOutputStream();
outputStream.write(bt);
outputStream.flush();
outputStream.close();
Thread.sleep(200); //50~~1400

serialPort.setRTS(true);
inputStream = serialPort.getInputStream();

serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
e.printStackTrace();
}
}

public void serialEvent(SerialPortEvent event) {
try{
if (event.getEventType() == event.DATA_AVAILABLE){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch;
while((ch=inputStream.read()) != -1){
count++;
if(count>2){
bos.write(ch);
}

}
byte[] bt = bos.toByteArray();
for(byte b : bt){
System.out.print("b="+b+"\t");//b=-86 b=0 b=-35 b=3 b=0 b=0 b=85 b=85
}
bos.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/config_man/archive/2010/06/30/5705264.aspx

在上面的博客地址中有较为详细的解释。再次感谢大家!!!
Cs_FangYaLong 2010-06-30
  • 打赏
  • 举报
回复
呵呵,完全看不懂,我也要变成高手,嘻嘻嘻
wangsx04 2010-06-30
  • 打赏
  • 举报
回复
膜拜一下 各位大牛们
一头头 2010-06-30
  • 打赏
  • 举报
回复
还没搞定呢?

、、、、、、、、。。。。。。。。。。。
Voxer 2010-06-30
  • 打赏
  • 举报
回复
另外你应该参考rtxx的例子,接受数据应该利用它提供的方法。下面这个类给你参考一下:


/**
* 串口通讯通用管理类,利用开源RTXXComm包来实现串口通讯。 必须的额外文件包括RTXXXcomm.jar,
* rxtxParallel.dll,rxtxSerial.dll,其中这二个dll文件必须放在和java.exe一起的bin目录
*
* @version 1.0
* @author But L.Y.
* @since
*/
public class SerialManager implements SerialPortEventListener {
private CommPortIdentifier portId = null;
private SerialPort serialPort = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;

private String com;
private int sleepTime = 500;// 接收数据的时间间隔,缺省是500毫秒
private byte[] readBuffer = new byte[2048];
private ArrayList<SerialListener> listeners = new ArrayList<SerialListener>();

public void setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
}

public void addListener(SerialListener listener) {
this.listeners.add(listener);
}

public void removeListener(SerialListener listener) {
this.listeners.remove(listener);
}

public void writeData(String[] datas) throws SerialException{
byte[] buffer = new byte[datas.length];
for(int i =0;i<buffer.length;i++)
buffer[i] = Misc.hex2Byte(datas[i]);
try {
this.outputStream.write(buffer);
} catch (IOException e) {
throw new SerialException(SerialException.SERIALERROR, "串口发送数据错误!", e);
}
}

public SerialManager(String com) throws SerialException {
this.com = com;
init();
}

// 打开指定波特率的端口
public void openPort(int baudrate) throws SerialException {
try {
serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
throw new SerialException(SerialException.SERIALFAIL, "以波特率"
+ baudrate + "打开串口(" + com + ")失败!", e);
}
}

private void init() throws SerialException {
initCom();
initPort();
initStream();
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
throw new SerialException(SerialException.SERIALFAIL, "太多的监听者错误!",
e);
}
serialPort.notifyOnDataAvailable(true);
}

private void initCom() throws SerialException {
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
boolean isFound = false;
String com = this.com;
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equalsIgnoreCase(com)) {
isFound = true;
break;
}
}
}
if (!isFound)
throw new SerialException(SerialException.SERIALFAIL, "串口(" + com
+ ")不存在!", null);
}

private void initStream() throws SerialException {
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
throw new SerialException(SerialException.SERIALFAIL, "串口(" + com
+ ")初始化数据失败!", e);
}
}

private void initPort() throws SerialException {
try {
serialPort = (SerialPort) portId.open("SerialManager", 2000);
} catch (PortInUseException e) {
throw new SerialException(SerialException.SERIALFAIL, "串口(" + com
+ ")初始化端口失败!", e);
}
}

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:
try {
int count = 0;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (inputStream.available() > 0) {
count = inputStream.read(readBuffer);
}
if (count >= 0) {
byte[] datas = new byte[count];
for (int i = 0; i < count; i++)
datas[i] = readBuffer[i];
for (int j = 0; j < this.listeners.size(); j++)
listeners.get(j)
.dataReady(new SerialEvent(this, datas));
}
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}

public void close() {
this.serialPort.close();

}

}
Voxer 2010-06-30
  • 打赏
  • 举报
回复
前段时间用rtxx写了串口程序,下面几个方法对你应该有用:

/** java的byte是从-127到127,和16进制转换有一个映射关系 */
public static byte hex2Byte(String hex) {
char[] achar = hex.toCharArray();
return (byte) (toByte(achar[0]) << 4 | toByte(achar[1]));
}

public static byte toByte(char c) {
byte b = (byte) "0123456789ABCDEF".indexOf(c);
return b;
}

public static int byte2Int(byte bL, byte bH) {
return (bH & 0xff) << 8 | bL & 0xff;
}

public static String byte2Hex(byte b) {
return ("" + "0123456789ABCDEF".charAt(0xf & b >> 4) + "0123456789ABCDEF"
.charAt(b & 0xf));
}
亲努力啊 2010-06-30
  • 打赏
  • 举报
回复
来学习的...
angel6709 2010-06-30
  • 打赏
  • 举报
回复
感觉挺简单。。。。
分析一下inputStream 嘛!呵呵
laorer 2010-06-30
  • 打赏
  • 举报
回复
vb好像是可以做成 com组件的吧,具体的不太清楚,你查查,如果可以的话,用 jni在java中调用就是了
config_man 2010-06-23
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 laorer 的回复:]
或许你可以考虑用VB做一个 dll,然后在java中调用吧……
[/Quote]
如果这样的话,那么这个dll必须有返回值给我。不知道可不可以。呵呵。
laorer 2010-06-21
  • 打赏
  • 举报
回复
或许你可以考虑用VB做一个 dll,然后在java中调用吧……
config_man 2010-06-19
  • 打赏
  • 举报
回复
.......
望舒 2010-06-19
  • 打赏
  • 举报
回复
把它当int型试试.一个个读,还不行就考虑用c
xqyky 2010-06-17
  • 打赏
  • 举报
回复
给楼主一个参考:

http://www.captain.at/howto-java-serial-port-javax-comm-rxtx.php
xqyky 2010-06-17
  • 打赏
  • 举报
回复
楼主最明显的错误是没有判断SerialPortEvent.DATA_AVAILABLE。你得到的都是0,为什么不想想这个问题?
AzraelWarrior 2010-06-17
  • 打赏
  • 举报
回复
好多牛人啊!学习一下!
dickli1986 2010-06-16
  • 打赏
  • 举报
回复
VB最简单,不过程序移植比较费劲,试一试
byte[] b = new byte[8];
while(inputStream.read(b)!=-1){System.out.println(b[0]);}
config_man 2010-06-16
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 jinxfei 的回复:]
想帮你但使不上劲儿。

你有用windows自带的“超级终端”调试过吗?
在“开始-->所有程序-->附件-->通信-->超级终端”
[/Quote]
不好意思,硬件被拿去安装了,没东西测试了,悲剧啊。我一定要试试!!!多谢关注,谢谢!!

[Quote=引用 50 楼 whut_lcy 的回复:]
还没搞定啊???
考虑用C/C++吧。最底层的操作。
[/Quote]
汗,不是不会嘛,要是会,哪里会用java啊,麻烦死了。这个东西用vb的话,很简单,但是不会用vb,哎,晕啊。
whut_lcy 2010-06-15
  • 打赏
  • 举报
回复
还没搞定啊???
考虑用C/C++吧。最底层的操作。
ronniegxq 2010-06-15
  • 打赏
  • 举报
回复
好多牛人
加载更多回复(48)

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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