我尝试连接到这样的数据记录器:
我可以通过串口发送一个问题,这只不过是一个字节数组。问题是我无法得到答案。我知道数据记录器以9600波特进行通信。我试图连接示波器,看它是否是程序或硬件问题,但示波器似乎给我一个答案,但我无法接收。这意味着问题肯定是软件。下面我将在示波器中显示答案
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
public class SerialRead implements SerialPortEventListener
{
private SerialPort serialPort;
private static String st;
private String PORT_ID;
private static SerialRead mInstance = null;
private InputStream input;
private OutputStream output;
private static final int TIME_OUT = 2000;
//TODO: inserisci il baud per la velocità di acquisizione
private static final int DATA_RATE = 9600;
public static SerialRead getInstance()
{
if (mInstance == null) {
mInstance = new SerialRead();
}
return mInstance;
}
/**
* setto il valore della PORT_ID e vado a restituire l'istanza della classe
* @param PORT_ID
* @return
*/
public SerialRead setPORT_ID(String PORT_ID) {
this.PORT_ID = PORT_ID;
if (PORT_ID == null){
throw new NullPointerException("Devi dare un valore alla porta");
}
return this;
}
private SerialRead() {
//costruttore interno
initialize();
close();
}
/**
* metodo che va a settare i parametri per l'inizializzazione della porta seriale ed
* per la comunicazione seriale per gestire sucessivamente la richiesta con un
* InputStream e OutputSteam
* @return
*/
public SerialRead initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// iterate through, looking for the port
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
if (currPortId.getName().equals(PORT_ID)) {
portId = currPortId;
System.out.println("-Porta connessa da " + SerialRead.class.getSimpleName());
break;
}
}
try {
serialPort = (SerialPort) portId.open(PORT_ID, TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
}
return this;
}
/**
* chiude la porta seriale così da liberare la comunicazione per la scrittura o la lettura
* questo perchè è monodirezionale
*/
private synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
/**
* Richiamo il metodo definito all'interno dell'interfaccia implementata SerialPortEventListener
* Creo un thread continuo per la lettura dei dati che andrà a terminare alla lettura di un dato specifico
* Andremo a leggere i dati solamente nel caso in cui siano disponibili
* @param oEvent
*/
@Override
public synchronized void serialEvent(final SerialPortEvent oEvent) {
new Thread(new Runnable() {
@Override
public void run() {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
int available = input.available();
byte[] chunk = new byte[available];
//System.out.println(chunk);
input.read(chunk, 0, available);
st = new String(chunk);
System.out.print(st);
/*try{ //impostato per risparmiare prestazioni e eseguire il ciclo meno spesso
Thread.sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}*/
}
catch (IOException e) {
System.out.println("IO Error Occurred: " + e.toString());
}
}
}
}).start();
}
}
SerialWriter.java
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
public class SerialWriter
{
/**
* inizializzazione porte e strumenti per la scrittura della seriale
*/
private SerialPort serialPort;
private String PORT_ID;
private static SerialWriter mInstance = null;
private CommPortIdentifier portId = null;
private InputStream input;
private OutputStream output;
private static final int TIME_OUT = 2000;
//TODO: inserisci il baud per la velocità di acquisizione
private static final int DATA_RATE = 9600;
private SerialWriter() {
//costruttore interno
close();
}
public static SerialWriter getInstance() {
if (mInstance == null) {
mInstance = new SerialWriter();
}
return mInstance;
}
/**
* setto il valore della PORT_ID e vado a restituire l'istanza della classe
* @param PORT_ID
* @return
*/
public SerialWriter setPORT_ID(String PORT_ID) {
this.PORT_ID = PORT_ID;
if (PORT_ID == null){
throw new NullPointerException("Devi dare un valore alla porta");
}
return this;
}
/**
* metodo che va a settare i parametri per l'inizializzazione della porta seriale ed
* per la comunicazione seriale per gestire sucessivamente la richiesta con un
* InputStream e OutputSteam
* @return
*/
public SerialWriter initialize() {
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// iterate through, looking for the port
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
//for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(PORT_ID)) {
portId = currPortId;
System.out.println("-Porta connessa da " + SerialWriter.class.getSimpleName());
break;
}
//}
}
if (portId == null) {
System.out.println("scanner is not connected !");
}
try {
serialPort = (SerialPort) portId.open(PORT_ID, TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
}
return this;
}
/**
* chiude la porta seriale così da liberare la comunicazione per la scrittura o la lettura
* questo perchè è monodirezionale
*/
private synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
System.out.println("-Porta chiusa da " + SerialWriter.class.getSimpleName());
}
}
/**
* metodo create per inviare una serie ("infinita") di messaggi tramite il parametro varags(un array di elementi)
* @param messagge
*/
public void sendData(String... messagge) {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
OutputStream outstream = null;
try {
outstream = serialPort.getOutputStream();
for (String currentMessage: messagge) {
//TODO: da cancellare- solo per debugging 1-2 riga
System.out.println(currentMessage);
outstream.write("\n".getBytes());
outstream.write(currentMessage.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
close();
}
public synchronized void sendData(byte... messagge) {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
OutputStream outstream = null;
try {
outstream = serialPort.getOutputStream();
/*for (byte currentMessage: messagge) {
//TODO: da cancellare- solo per debugging 1-2 riga
System.out.println(currentMessage);
//outstream.write("\n".getBytes());
outstream.write(currentMessage);
outstream.flush();
}*/
outstream.write(messagge);
//outstream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
close();
}
public void sendData(char... messagge) {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
OutputStream outstream = null;
try {
outstream = serialPort.getOutputStream();
for (char currentMessage: messagge) {
//TODO: da cancellare- solo per debugging 1-2 riga
System.out.println(Integer.toBinaryString(currentMessage));
//outstream.write("\n".getBytes());
outstream.write(String.valueOf(currentMessage).getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
close();
}
}
和主要活动:
public class SerialeEsegui
{
public static void main(String args[]) {
String PORT_ID = "COM4";
SerialRead.getInstance().setPORT_ID(PORT_ID).initialize();
}
答案 0 :(得分:0)
在你的代码中没有发送请求所以我假设这个设备是自己发送的。 Modbus协议远比标准串行通信复杂。人们通常需要构建类似协议栈的东西才能接收消息。我们使用Modbus做了很多工作,我们正在使用SuperCom库(adontec.com)来完成这项工作。它还提供了一个名为RS_RXMODBUS的功能,可以接收原始Modbus数据。不幸的是,这个库不是免费的,但是非常可靠。
答案 1 :(得分:0)
似乎错误发生在关闭序列然后重新打开它的close()
方法上。实际上,您已经为打开和关闭的串行创建了两个类,分别是写入和读取(SerialWriting.java和SerialReading.java)。但这没有任何意义,事实上,创建单个类更加正确和简单。它仅对序列进行一次初始化,然后您可以直接在其中管理数据的读取和写入。问题似乎是你花了太多时间从一个类改为另一个类,然后关闭串口然后重新打开它,从而失去了示波器中显示的数据记录器的响应。在下面的代码中,所有内容都由一个类管理,您可以在读完数据后调用close()
方法。
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
public class SerialManager implements SerialPortEventListener
{
/**
* inizializzazione porte e strumenti per la scrittura della seriale
*/
private SerialPort serialPort;
private String PORT_ID;
private static String st;
private static SerialManager mInstance = null;
private CommPortIdentifier portId = null;
private InputStream input;
private OutputStream output;
private static final int TIME_OUT = 2000;
//TODO: inserisci il baud per la velocità di acquisizione
private static final int DATA_RATE = 9600;
private SerialManager() {
//costruttore interno
close();
}
public static SerialManager getInstance() {
if (mInstance == null) {
mInstance = new SerialManager();
}
return mInstance;
}
/**
* setto il valore della PORT_ID e vado a restituire l'istanza della classe
* @param PORT_ID
* @return
*/
public SerialManager setPORT_ID(String PORT_ID) {
this.PORT_ID = PORT_ID;
if (PORT_ID == null){
throw new NullPointerException("Devi dare un valore alla porta");
}
return this;
}
/**
* metodo che va a settare i parametri per l'inizializzazione della porta seriale ed
* per la comunicazione seriale per gestire sucessivamente la richiesta con un
* InputStream e OutputSteam
* @return
*/
public SerialManager initialize() {
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// iterate through, looking for the port
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
//for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(PORT_ID)) {
portId = currPortId;
System.out.println("-Porta connessa da " + SerialManager.class.getSimpleName());
break;
}
//}
}
if (portId == null) {
System.out.println("scanner is not connected !");
}
try {
serialPort = (SerialPort) portId.open(PORT_ID, TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) { e.printStackTrace();}
return this;
}
/**
* chiude la porta seriale così da liberare la comunicazione per la scrittura o la lettura
* questo perchè è monodirezionale
*/
private synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
System.out.println("\n-Porta chiusa da " + SerialManager.class.getSimpleName());
}
}
public synchronized void sendData(byte... messagge) {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
OutputStream outstream = null;
try {
outstream = serialPort.getOutputStream();
outstream.write(messagge);
//outstream.flush();
for (byte m : messagge) {
System.out.print(m + " ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
//close();
try {
System.out.println("\nSeriale in ascolto (in esadecimale)");
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
e.printStackTrace();
}
}
@Override
public void serialEvent(final SerialPortEvent oEvent) {
final StringBuilder builder = new StringBuilder();
new Thread(new Runnable() {
@Override
public void run() {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
int available = input.available();
byte[] chunk = new byte[available];
input.read(chunk, 0, available);
for (byte b : chunk) {
builder.append(b).append(" ");
}
System.out.print(builder.toString());
}
catch (IOException e) {
System.out.println("IO Error Occurred: " + e.toString());
}
}
}
}).start();
}
}
和主要活动:
public class SerialeEsegui
{
public static void main(String args[]) {
String PORT_ID = "COM4";
int b = unsignedToBytes((byte) 0x93);
int c = unsignedToBytes((byte) 0xf4);
int f = unsignedToBytes((byte) 0xfd);
int z = unsignedToBytes((byte) 0xf1);
//Request example
byte array[] = new byte[]{0x01, 0x03, 0x00,(byte) b, 0x00, 0x0b, (byte) c, 0x20};
byte array1[] = new byte[]{0x01, 0x10, 0x00,(byte) b, 0x00, 0x0b, 0x16, 0x23,
0x40, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, (byte) f, (byte) z};
SerialManager.getInstance().setPORT_ID(PORT_ID).initialize().sendData(array);
}
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}
}