I don’t see any issues with your delays, though the ch1_msDelayScan can be a lot shorter, 5-10ms will be fine and your timeout probably needs to be longer based on the behavior I think is happening.
What I suspect is happening is occasionally the slaves are taking longer to respond than the timeout set in ch1_nt03AsIntParameters[2] so when you make the next call, the receive buffer already has data in it.
The good news is, I think your code is fine! The issue is with the Opto22 modbus kit due to two reasons:
@Beno - bug report below
-
The subroutines don’t check if there is already data in the receive buffer before it transmits so that it can clear it out first.
-
The subroutine doesn’t verify the slave Id in the response so it can respond with an error status if there is a mismatch - it just takes whatever comes. The kit already has an error code for this, it just never does the check.
To fix the first issue, change the “Open” block in the subroutine:
if (GetNumCharsWaiting(chCommHandle) < 0 or not IsCommunicationOpen(chCommHandle)) then
nStatus = OpenOutgoingCommunication(chCommHandle);
else
ClearCommunicationReceiveBuffer(chCommHandle);
nStatus = 0;
endif
To fix the second issue and validate the response Slave Id, change the Receive block in the subroutine and replace the code in the case 0 block with the following:
ReceiveNChars(sTempString2, 3, chCommHandle);
//Check for correct slave Id in response
if(ntParameters[1] <> GetNthCharacter(sTempString2, 0)) then
nStatus = -212;//Wrong Slave Address
elseif (3 <> GetNthCharacter(sTempString2, 1)) then //exception code - should really check CRC here too!
nStatus = GetNthCharacter(sTempString2, 2);
ClearCommunicationReceiveBuffer(chCommHandle);
else
ReceiveNChars(sTempString1, GetNthCharacter(sTempString2, 2), chCommHandle);
sTempString2 += sTempString1;
nTemp2 = GenerateReverseCrc16OnString(-1, sTempString2);
ReceiveNChars(sTempString1, 2, chCommHandle);
if (nTemp2 <> (GetNthCharacter(sTempString1, 1) <<8) + GetNthCharacter(sTempString1, 0)) then
nStatus = -211;//CRC Error
endif
endif
It will look like this:
Let me know if that second one works okay, because I back ported my own modbus code to the kit right now to help you and did not test it.
