LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Modbus Master Write/Read Multiple Coils gives error if Modbus Instance is passed through FGV

Hi,

I am trying to write/read to/from a PLC that allows communication via Modbus protocol. I have encountered a very weird problem and research on NI's forum does not help or provide enough information to get rid of the issue. 

 

Problem Description:
When I run Write Multiple Coils.vi and pass the Modbus master instance using a Functional Global Variable (FGV), I get the following error. I initialize the Modbus Master Instance in a Separate VI, and save the instance reference in an FGV. Following is the screenshot of my VIs as well. However, if I have the Initialize VI within the same main VI, then I don't get the error and I can run the VI. I don't understand why passing the Modbus Master Instance reference through FGV causes the Write Multiple Coils VI to fail.

 

LabView Error:

"Master.lvclass:Protocol Write.vi:6190001->IP Data Unit.lvclass:Write ADU Packet.vi:1820001->Modbus Master.lvclass:Write Multiple Coils.vi:6300001->CLS_Logo_PLC_Test_Exec.vi

Possible reason(s):

LabVIEW: An input parameter is invalid. For example if the input is a path, the path might contain a character not allowed by the OS such as ? or @."

 

RavRav_0-1710805876863.png

 

My Labview version is 2022 and I have attached the 3 VIs: 

 

- CLS_Logo_PLC_Initialize.vi

- CLS_Logo_PLC_Modbus_Serial_Master_Instance_F-GV.vi

- CLS_Logo_PLC_Test_Exec.vi

 

My goal is to avoid opening/closing the Modbus Reference every time I communicate with the PLC. Also, I want to run some VI's in the test stand sequence asynchronously and using the FGV for Instance Reference would simplify my implementation. 

Any help is appreciated.

 

Thanks,
Rav

0 Kudos
Message 1 of 5
(723 Views)

Hi RavRav,

 


@RavRav wrote:

My goal is to avoid opening/closing the Modbus Reference every time I communicate with the PLC. Also, I want to run some VI's in the test stand sequence asynchronously and using the FGV for Instance Reference would simplify my implementation. 

Any help is appreciated.


Do you use TestStand with a sequence calling your VIs?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 5
(670 Views)

There's a general rule in LV where references are owned by the hierarchy of VIs where they were created. The hierarchy is defined by the top level VI and when that VI stops running, the references created under it are closed automatically. I haven't looked at your code beyond the image, but I'm guessing that's what happening and that Master.lvclass:Protocol Write.vi likely has a TCP Write primitive inside it which is now getting a TCP reference which is no longer valid.

 

In general, get-set FGV are not something I would recommend, as they're basically the same as a global variable, but less convenient. If you do want to have a singleton for managing the connection to the PLC, I would suggest having a library for it, where you have a private VI for getting a DVR of your data (which I would suggest can be a cluster or a class which includes the connection parameters as well as the connection reference and possibly some tracking data for error handling). This VI can use the shift register or feedback node to give you your singleton.

 

You then add VIs to the library for your various actions (e.g. the init or open connection VI can include the parameters and you can have wrappers for the Modbus functions or you can have a VI for returning the connection reference and use that).

 

All of this won't solve the basic issue you're having (which is likely that you're initializing the connection in a part of the code that then stops running), but it can allow you to add error handling, which can include reopening the connection if needed.

 

 

As for Teststand, I'm not familiar with how it runs LV VIs, so no comments there from me.


___________________
Try to take over the world!
0 Kudos
Message 3 of 5
(661 Views)

Hi GerdW,

Yes, I use Teststand to call the LabView VIs.

 

One additional detail that may be useful and I forgot to put this in my problem description...I tried to debug the issue in Labview and I put probes in the initialization VI. I put a probe at the output of the CreateTCPMaster.VI (instance reference), and another one at the output of the FGV that I used to store the instance reference. I then put the third probe when I use the Get on the FGV, in my main code. All of the instance IDs (mutex) were the same. See below. I am still not sure why the WriteMultipleCoils.vi give error

 

RavRav_0-1710862428828.png

 

0 Kudos
Message 4 of 5
(630 Views)

@RavRav wrote:


I tried to debug the issue in Labview and I put probes ...
All of the instance IDs (mutex) were the same.

 

RavRav_0-1710862428828.png

 


The value of the wire in the FGV remains the same as long as the FGV is in memory. The issue would be with the TCP connection reference, which is automatically closed. If you dig down into the hierarchy and get through all the dynamic dispatch VIs (the password for this specific library is "bestbus"), you will eventually get to that TCP connection reference, which is what will be closed (even if its numeric value stays the same. This is a bit like you getting a number for waiting in line, missing your turn and then coming in later expecting it to work. The fact that you have the number is not relevant, since the other side no longer recognizes it).

 

The solution for something like that is either to make sure the hierarchy which created the reference does not go idle (not sure how that will work when calling VIs from TestStand) or to have error handling which can reopen the connection on errors (which is better anyway, since the connection can be closed for all kinds of reasons).


___________________
Try to take over the world!
Message 5 of 5
(597 Views)