Modbus Serial Errors
I'm starting to use Mango with a USB to serial adapter to read two Modbus slaves. I'm getting the following two errors:
'mainbox': Exception from modbus master: No recipient was found waiting for response for key com.serotonin.modbus4j.serial.SerialWaitingRoomKey@428
'mainbox': Plug3: com.serotonin.messaging.WaitingRoomException: Waiting room too crowded. Already contains the key com.serotonin.modbus4j.serial.SerialWaitingRoomKey@428
I do not get errors if I'm only reading from the slave. It is when I am also writing to them that I get the error. For a simple experiment I have mango pulling one holding register every 5 seconds from the salve.
I have the data point set up as settable and am toggling it from 0 to 1 back and forth and after a few toggels I get the error.
Here is the serial traffic from this experiment:
14:52:14.886: [COM4 19200-N-8-1] On
14:52:27.984: Comm port off.
The data source is set for a 500 ms time out and 2 retrys. the 3 lines I have bolded look like where mango didn't get a response.
I'm not sure what I need to do to relsove this. I have communicated with other PLCs and software to the same slaves before without any issues.
Try increasing your timeout and see if that helps.
I just tried changing the timeout in increments up to 5000 and down to 10 and didn't seem to help at all.
Ok, i know what is going on. The explanation is a bit esoteric, so i'll give you the solution first: replace your seroUtils.jar file with the attached and restart Mango.
All requests that expect responses go into a "waiting room" while they wait for the thread that listens for reply data to provide the response. A "waiting room key" is used to match up waiting requests with their responses. For I/P comm the transaction id is part of this key, so the two can typically be reliably matched.
Serial comm has no transaction id though; matching can only be done on the slave id and the message type (in this case write-holding-register). What happened to you is that you sent two write-holding-register requests to the same slave before the slave could respond to the first. The waiting room detected a duplicate waiting room key, and denied the request. I've changed the code so that the request waits for its duplicate to complete rather than just failing.
(Note that we could simply synchronize the send method to ensure that only one request can be sent at a time, but that would prevent asynchronous messaging with multiple slaves, which is a nice thing to be able to do.)
Attachment: download link
Thanks for the last update. I did this but something still isn't quite right.
Here is the error I got:
'mainbox': Plug3: com.serotonin.messaging.TimeoutException: request=com.serotonin.modbus4j.serial.rtu.RtuMessageRequest@37cce4
'mainbox': com.serotonin.modbus4j.exception.ModbusTransportException: com.serotonin.messaging.TimeoutException: request=com.serotonin.modbus4j.serial.rtu.RtuMessageRequest@60e7d2
It seems to happen if the write command tries to go out at just the wrong time. Does this mean Mango isn't queuing the commands quite right.
Here is the traffic of my recent test. I set the update rate to 60 seconds on the data source so that the only traffic was me toggling the value.
11:41:10.247: [COM4 19200-N-8-1] On
11:41:57.956: Comm port off.
I'm pretty sure the 3rd last line above is where it messed up.
What would the disadvantage be of synchronizing?
Have you tried just setting your timeout higher? What do you mean "at just the wrong time"?
I tried setting the timeout to 700 and 1000 ms and get this error immediately
I've been using 500 ms which seems to work the best.
'mainbox': Plug3: com.serotonin.messaging.TimeoutException: request=com.serotonin.modbus4j.serial.rtu.RtuMessageRequest@1b58992
"Just the wrong time" may not be relevant any more but I had the data source pulling every 5 seconds and it seemed that if I clicked the toggle button in mango at just the right or wrong time I got the error but other times it was fine. I was thinking that maybe if I sent the write command at the same time as the read command was happening this caused the problem. Now that I did the test where there was not a read command happening but doing a series of write commands (toggling the value) caused the same issue leaves me totally clueless where the conflict is coming in. I'm going to do some testing with another master to the same slave and record the traffic to see if it reveals a problem with my slave.
I just used Modbus Poll to test communication to my slave:
I used a 500ms timout and a 10 ms delay between polls
In the first test where there was no polling happening only toggling the register I noticed that MP just sends the 06 command and gets the response. In Mango it looks like it sends the 06 command and then re-reads the register with a 03 command.
In the second test I set up a poll every 1 second and then toggled the point as fast as a could and did not getting any errors. Attached is the serial traffic from all of my experiments.
Does Mango have a setting for delay between polls?
Attachment: download link
Actually, it's the opposite: there is a read req/res, and then there is a write req/res. The reason for this is that your particular point is a binary within a holding register. Your equipment presumably does not support the write-mask-register message, so a regular write-holding-register must be used. The master doesn't know what should be in the other 15 bits of the register, so it does a read, a local masked write into the value, and then a write. This minimized the possibility that the other values in the register get overwritten.
Not sure how the apparently corruption happened. What is your serial duplexing like?
Interesting. I believe I'm using half duplexing. communication is over RS-485 with one RX and one TX wire with one ground so three wires all together.
I've added some concurrency settings to the modbus stuff. Hopefully this will solve your problems. It will be available in the next version.
That is great. Is there any way I could test this before you release it to see if it will resolve the issue?
For now I can set all my points to numeric rather than binary and it seems like this should work but it's kinds of a bummer as I can't display the information like I really need to.
Thanks for the help,
An update has been posted.
I still get the following error when I use Modbus Serial.
"'Modbus': Exception from modbus master: No recipient was found waiting for response for key com.serotonin.modbus4j.serial.SerialWaitingRoomKeyFactory$TransportSyncWaitingRoomKey@1".
Is this a known bug?