hi folks,
ich arbeite momentan an einem projekt bei dem ich bidirektionale serielle kommunikation benötige.
ich benutze die java comm api 2.0 für windows.
die serielle kommunikation klappt gut, allerdings habe ich ein verständnis-/design- problem.
ich habe zum test eine klasse TestSerialConnection in mit einer Main methode, in der der Programmfaden abläuft, anglegt.
in der main methode instanziere ich erst die parameterklasse, setze comport parameter und instanziere anschließend die SerialConnection. die objekte sind da und ich kann z.B. was auf die Serielle rausschreiben.
Wenn daten reinkommen wirft die comm api einen event und die daten sind im SerialConnection objekt verfügbar. momentan gebe ich sie über system.out.println aus.
ich will allerdings mit den inputdaten in meinem TestSerialConnection objekt arbeiten und intelligent auf die inputdaten antworten!
und hier meine eigentliche frage:
ist es möglich dass das SerialConnection objekt ein event an die TestSerialConnection schickt und sagt: "ich hab daten für dich, mach damit was du willst!" oder geht es nur in dem ich das SerialConnection objekt immer vom TestSerialConnection objekt aus frage: "hast du daten?"
anbei der quellcode
danke für eure hilfe!
flo
ich arbeite momentan an einem projekt bei dem ich bidirektionale serielle kommunikation benötige.
ich benutze die java comm api 2.0 für windows.
die serielle kommunikation klappt gut, allerdings habe ich ein verständnis-/design- problem.
ich habe zum test eine klasse TestSerialConnection in mit einer Main methode, in der der Programmfaden abläuft, anglegt.
in der main methode instanziere ich erst die parameterklasse, setze comport parameter und instanziere anschließend die SerialConnection. die objekte sind da und ich kann z.B. was auf die Serielle rausschreiben.
Wenn daten reinkommen wirft die comm api einen event und die daten sind im SerialConnection objekt verfügbar. momentan gebe ich sie über system.out.println aus.
ich will allerdings mit den inputdaten in meinem TestSerialConnection objekt arbeiten und intelligent auf die inputdaten antworten!
und hier meine eigentliche frage:
ist es möglich dass das SerialConnection objekt ein event an die TestSerialConnection schickt und sagt: "ich hab daten für dich, mach damit was du willst!" oder geht es nur in dem ich das SerialConnection objekt immer vom TestSerialConnection objekt aus frage: "hast du daten?"
anbei der quellcode
danke für eure hilfe!
flo
Code:
public class TestSerialConnection {
public static void main(String[] args) {
// TODO Auto-generated method stub
SerialParameters serialProps = new SerialParameters();
serialProps.setPortName("COM2");
serialProps.setBaudRate(9600);
serialProps.setDatabits(8);
serialProps.setStopbits(1);
SerialConnection serialConn = new SerialConnection(serialProps);
try {
serialConn.openConnection();
} catch (SerialConnectionException e2) {
System.out.println("Error open COM: " + serialProps.getPortName());
}
serialConn.write("teststring\r\n");
}
}
Code:
public class SerialConnection implements SerialPortEventListener, CommPortOwnershipListener {
private SerialParameters parameters;
private OutputStream os;
private InputStream is;
private CommPortIdentifier portId;
private SerialPort sPort;
private boolean open;
public SerialConnection(SerialParameters parameters) {
this.parameters = parameters;
this.open = false;
}
public void openConnection() throws SerialConnectionException {
try {
portId = CommPortIdentifier.getPortIdentifier(parameters.getPortName());
} catch (NoSuchPortException e) {
throw new SerialConnectionException(e.getMessage());
}
try {
sPort = (SerialPort)portId.open("SerialConnection", 30000);
System.out.println(portId.getName() + " opened for serial communication");
} catch (PortInUseException e) {
throw new SerialConnectionException(e.getMessage());
}
try {
setConnectionParameters();
} catch (SerialConnectionException e) {
sPort.close();
throw e;
}
try {
os = sPort.getOutputStream();
is = sPort.getInputStream();
} catch (IOException e) {
// ignore this because often the serial port will be idle
//sPort.close();
//throw new SerialConnectionException("Error opening i/o streams");
}
// Add this object as an event listener for the serial port.
try {
sPort.addEventListener(this);
} catch (TooManyListenersException e) {
sPort.close();
throw new SerialConnectionException("too many listeners added");
}
// Set notifyOnDataAvailable to true to allow event driven input.
sPort.notifyOnDataAvailable(true);
// Set receive timeout to allow breaking out of polling loop during
// input handling.
try {
sPort.enableReceiveTimeout(30);
} catch (UnsupportedCommOperationException e) {
}
// Add ownership listener to allow ownership event handling.
portId.addPortOwnershipListener(this);
this.open = true;
}
/**
Sets the connection parameters to the setting in the parameters object.
If set fails return the parameters object to origional settings and
throw exception.
*/
public void setConnectionParameters() throws SerialConnectionException {
// Set connection parameters, if set fails return parameters object
// to original state.
try {
sPort.setSerialPortParams(parameters.getBaudRate(),
parameters.getDatabits(),
parameters.getStopbits(),
parameters.getParity());
} catch (UnsupportedCommOperationException e) {
throw new SerialConnectionException("Unsupported parameter");
}
// Set flow control.
try {
sPort.setFlowControlMode(parameters.getFlowControlIn()
| parameters.getFlowControlOut());
} catch (UnsupportedCommOperationException e) {
throw new SerialConnectionException("Unsupported flow control");
}
}
/**
Close the port and clean up associated elements.
*/
public void closeConnection() {
// If port is alread closed just return.
if (!this.open) return;
// Check to make sure sPort has reference to avoid a NPE.
if (sPort != null) {
try {
// close the i/o streams.
os.close();
is.close();
} catch (IOException e) {
System.err.println(e);
}
// Close the port.
sPort.close();
// Remove the ownership listener.
portId.removePortOwnershipListener(this);
System.out.println(portId.getName() + " closed");
}
this.open = false;
}
/**
Send a one second break signal.
*/
public void sendBreak() {
sPort.sendBreak(1000);
}
/**
Reports the open status of the port.
@return true if port is open, false if port is closed.
*/
public boolean isOpen() {
return this.open;
}
/**
Handles SerialPortEvents. The two types of SerialPortEvents that this
program is registered to listen for are DATA_AVAILABLE and BI. During
DATA_AVAILABLE the port buffer is read until it is drained, when no more
data is availble and 30ms has passed the method returns. When a BI
event occurs the words BREAK RECEIVED are written to the messageAreaIn.
*/
public void serialEvent(SerialPortEvent e) {
// Create a StringBuffer and int to receive input data.
StringBuffer inputBuffer = new StringBuffer();
int newData = 0;
// Read data until -1 is returned. If \r is received substitute
// \n for correct newline handling.
while (newData != -1) {
try {
newData = is.read();
if (newData == -1) break;
if ('\r' == (char)newData) {
inputBuffer.append('\n');
} else {
inputBuffer.append((char)newData);
}
} catch (IOException ex) {
System.err.println(ex);
return;
}
}
// print input
System.out.print(inputBuffer);
}
public void ownershipChange(int type) {
if (type == CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED) {
System.out.print("An other application tries to use the selected com-port: ignore it ;-)\n");
}
}
public void write (String data) {
try {
byte sendbytes[] = data.getBytes();
os.write(sendbytes);
} catch (IOException e) {
System.err.println("OutputStream write error: " + e);
}
}
}