Opto22 modbus master kit

Hello, I’m using the modbus master kit with the function 3 as int subroutine. problem is that I cant view any of the variables in the subroutine because it just says N/A but I am reading data and its working. is there not a way to monitor values?

Paging @philip who has used the tool kit a ton…

To see the values of a subroutine, you need to set a breakpoint in the subroutine (or in the calling chart and step into it). You can’t see the value of the variables inside the subroutine any other way that I know of.

What values are you trying to see?

that makes sense, i was kinda confused about the error checking inside of it bc the fail points don’t go anywhere but im assuming thats what n03AsIntStatus is for. in one of our charts someone created this chart and we have it everywhere and it works but having trouble with one device thats been reading good data and then failing on the next pole giving us a crc mismatch so i started pulling the slave from the modbus kit and it seems to work and not have any errors but not sure yet

Are you using an old version of the integration kit? The current one doesn’t have an n03AsIntStatus.

A good read, followed by CRC is sometimes from junk being left in the buffer. However, if the CRC is being checked, then I’m not sure how that would be happening since those are the last bytes received. Another scenario is when there isn’t a delay between a receive and the next transmit by the host - modbus over serial requires 3.5 characters of delay between transmissions for transceivers to switch between transmitting and listening - though that usually results in timeouts on every other request.

Is the chart you posted sending a modbus request? What is in the “Set EOM” block? Since the kit is working, I would suspect that there is some bug in the chart you posted that only presents itself in certain scenarios.

theres plenty of delays and still same issue, and i just got this kit its 9.3 from the website. is that old? heres the pictures of the new one that i added yesterday from the kit. also the eom block i believe is for ascii its what ends the message in ascii mode (which im not using, im using RTU) but the chart has tcp ascii and rtu all in one just like the kit. heres the one i got from the website yesterday i just deleted the rest of the functions im not using, but it seems incomplete because the fails dont go anywhere.


also the EOM block is in the kit its just written in script, if you navigate to “build ascii” its at the bottom.

That is the most recent. I understand now, you are looking at the sample Modbus_Master chart that comes with the kit, that is where you are getting the n03AsIntStatus - that value comes from the nStatus parameter of each modbus subroutine.

The subroutines return/exit at the error blocks - there is nothing more for them to do - the calling chart will need to check for the error in nStatus and respond accordingly.

It appears that bits of the kits subroutines were put into the chart that you are using - do you know why this was done rather than just calling the subroutine?

That makes sense so the errors in the sub don’t need to go anywhere but they are calculated and will give out an error to n status which gets transferred to 03intstatus.

And I have no idea why they custom made it but I have another question how do I add more than 1 slave to the modbus kit using the same function code?

On the subroutine parameters, ntParameters[1] holds the slave address. So set ntParameters[1] to the slave Id before you call the subroutine.

I understand that part but how do I write it so it talks to multiple slaves with different registers?

If I wanted to talk to two slaves with function code 3 do I have to have 2 function 3 subroutines and copy paste function 3 general setup and read in the main chart to call out the subroutine for slave number 2? With the same comm handle.

Yes, you would call the subroutine for each slave. You can use the general setup as an example for your own chart.

Something like this:

ntModbusSettings[0] = 0;//Protocol - 0 = Serial RTU, 1 = Serial ASCII, 2 = Modbus/TCP
ntModbusSettings[2] = 1000;//Timeout in ms
ntModbusSettings[3] = 0;//Word Order - 0 = Lower register least significant, 1 = Lower register most significant
nModbusStatus = 0;

//Read register 1 through 10 into ntSlave01Values for Slave 1
ntModbusSettings[1] = 1; //Set slave unit ID
O22Modbus03ReadHoldingRegistersAsInt(chModbusMaster, ntModbusSettings, 0,
        1, ntSlave01Values, 10, nModbusStatus);

DelayMsec(5); //Need 3.5 char delay between response and new request 4.2ms at 9600bps

//Read register 101 through 120 into into ntSlave02Values for Slave 2
ntModbusSettings[1] = 2; //Set slave unit ID
O22Modbus03ReadHoldingRegistersAsInt(chModbusMaster, ntModbusSettings, 0,
        101, ntSlave02Values, 20, nModbusStatus);

The above logic would be run in a looping chart with an appropriate delay.

cool and one last thing. in pac control the error box is filled with -47 errors. the chart keeps trying to open comms but its already open so it throws in this error and in the chart it accounts for it. if “nstatus” is 0 OR -47 it passes but my error box in pac control is filled. anyway to get rid of this?

Which chart is opening the comm handle? You don’t need to open the comm handle in your chart, as the modbus subroutines will open it if it is not open. If you are continuously getting this data you shouldn’t close the comm handle either.

This is what calls the subroutine. i have it set to 1


andle is the master chart. I have variable set to 1 to call the subroutine. That’s it.

also the error tells me this is where its getting its error from because its already open. and to your point, i dont think its closing the session but trying to open it every time it goes through the chart because it says “open session failed because its already opened” its trying to open the session but its already open so it throws an error. “SetCommunicationHandleValue(“ser:0,9600,E,8,1”, chModbusMaster);”

If you’re using the kit as is, then I am not sure - the subroutines have this at the top of them:

if (GetNumCharsWaiting(chCommHandle) < 0) then
    nStatus = OpenOutgoingCommunication(chCommHandle);
else
     nStatus = 0;
endif

which calls the GetNumCharsWaiting which will be 0 or higher if the comm handle is open.

Can you open the O22Modbus03ReadHoldingRegistersAsInt subroutine and modify the “Open” script block to be the following:

if (GetNumCharsWaiting(chCommHandle) < 0  or not IsCommunicationOpen(chCommHandle)) then
    nStatus = OpenOutgoingCommunication(chCommHandle);
else
     nStatus = 0;
endif

I have it like that in my personal modbus subroutines and maybe I added that because of what you are seeing at some point - I don’t remember.

thank you! i’ll let you know how it goes on monday