0
votes

I am stuck in a strange issue while reading data from serial port in Java.

I have to read data from serial port via a polling method in a thread which is working fine, but I have a requirement where I need to write data to a serial port and read ACK back. Writing data to the serial port is successful but I am not able to read data back. Here there are two read operations one in thread and one in main thread.

Once I receive serial write data I paused the thread which is reading data from the serial port using a flag and started reading data from serial port again once write is done, but I am not able to read data. I disabled reading serial port after write operation and enabled thread which reads serial port in thread, here I am seeing ACK data from serial port.

Can any suggest what is going on wrong with this serial read operation? It is not buffered read/write operation.

2
I'm not sure I follow your logic. You seem like you're reading from three different threads at once, which doesn't sound like a good idea.gobernador
It is not three different threads but two threads , one thread which polls for serial read continuously and other in main thread which reads only when it performs write operationRajesh SO
While I still don't know the reason for this, I believe I understand the issue. I believe he's saying that the main thread sends a write command, and has a read (the ACK-Checker) in it that should see an ACK afterwards, and has a read in another thread (lets call it the "general reader") to do every other read operation. The problem appears to be that when he writes from the main thread, that ACK-checker does not see an ACK. If he disables the "ACK-checker", then the "general reader" sees the ACK when it does its normal polling (which it normally shouldn't). Is this correct?Xantham
yes Xantham, thanks for putting my question in proper manner.Rajesh SO

2 Answers

0
votes

I strongly recommend using only one dedicated thread for accessing serial port reading. The most reliable solution used to be an interrupt handler shoveling all the received data to a threadsafe state machine. Trying to read the serial port from multiple threads calls for problems. Serial port IO doesn't care that you "paused your thread", the data can be already fetched in and lost due to context switch.

So simply keep reading what comes in and if ACK is expected and obtained, inform the main thread via semaphore. In a dirty brutally simplified pseudocode:

Main thread loop:

{
  serialReaderThread.isAckExpected = true
  sendWriteCommand();
  ackReceivedSemaphore.wait();
}

Serial reader thread loop:

{
  readData();
  if( isAckExpected && data == ack ) {
    mainThread.ackReceivedSemaphore.notify();
    isAckExpected = false
  }
}

You need to set isAckExpected before sending the write command, because if your serial peer is fast enough, you might get the response back before your sendWriteCommand even returns.

0
votes

You should not have different threads attempting to read from the serial port. The correct architecture is to have the single thread do the reading and distribute the incoming data to interested clients via multiple queues.

You would have a "normal read processing" thread that is given data by the read thread. When you need to do the write/ack sequence, the thread doing the write/ack would temporarily register itself with the read thread and divert the data stream.

You still have to deal with any interleaving of data (i.e. normal data being received after the write request but before the ack is received), but that is up to your application.