我是串口通信的新手,需要一些帮助来掌握它。
我需要与控制板通信。该委员会有时可以发送我需要作出反应的事件,并且需要将事件发送给委员会并等待响应。
我们已经建立了一个协议,其中每个事件始终为12个字节,而前2个字节确定事件的类型。
我知道,当我发送特定消息时,我需要等待具有特定指示字节的消息。 同时我希望对董事会发出的事件做出反应。例如,董事会可能会说它过热,而与此同时,我要它执行一些命令并做出答复。
我的问题是,如果我在等待期望的响应的同时写端口并阻塞一秒钟,我如何确保我不“窃取”我的听众期望的数据?例如。串行端口就像流一样工作,一旦我读完,我就越过了可以重读的地方。
我已经使用jSerialComm完成了此操作,希望可以为我的问题提供一些启发。
首先,使用addDataListener方法注册的侦听器。我希望在以“ T”开头的端口上存在事件时触发该事件。
private static LockerSerialPort getLockerSerialPort(final DeviceClient client) {
return MySerialPort.create(COM_PORT)
.addListener(EventListener.newBuilder()
.addEventHandler(createLocalEventHandler())
.build());
}
private static EventHandler createLocalEventHandler() {
return new EventHandler() {
@Override
public void execute(final byte[] event) {
System.out.println(new String(event));
}
@Override
public byte[] getEventIdentifier() {
// I want this listener to be executed when events that start with T are sent to the port
return "T".getBytes();
}
@Override
public String getName() {
return "T handler";
}
};
}
接下来,我希望能够写入端口并立即获得响应,因为需要知道该命令是否成功。
private byte[] waitForResponse(final byte[] bytes) throws LockerException {
write(bytes);
return blockingRead();
}
private void write(final byte[] bytes) throws LockerException {
try (var out = serialPort.getOutputStream()) {
out.write(bytes);
} catch (final IOException e) {
throw Exception.from(e, "Failed to write to serial port %s", getComPort());
}
}
public byte[] blockingRead() {
return blockingRead(DEFAULT_READ_TIMEOUT);
}
private byte[] blockingRead(final int readTimeout) {
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, readTimeout, 0);
try {
byte[] readBuffer = new byte[PACKET_SIZE];
final int bytesRead = serialPort.readBytes(readBuffer, readBuffer.length);
if (bytesRead != PACKET_SIZE) {
throw RuntimeException.from(null, "Expected %d bytes in packet, got %d", PACKET_SIZE, bytesRead);
}
return readBuffer;
} catch (final Exception e) {
throw RuntimeException.from(e, "Failed to read packet within specified time (%d ms)", readTimeout);
}
}
当我打电话给waitForResponse("command")
时,我怎么知道我的阻塞读取没有从监听器中窃取数据?
这两种模式不兼容吗?通常如何处理这种情况?