NI Labs Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

NI LabVIEW Modbus API Discussion

Hello Smithd,

I start with a disponible Memory of 58.246 MB.

                         After 200 connections (16 minutes) 58.050 MB remain ;

                                1000 connections (1 hour) 57.150 MB remain ;

                                2000 connections (2 hours) 56.150 MB remain ;

                                4200 connections (4 hours and 16 minutes) 54.240 MB remain.

Best regards.

0 Kudos
Message 181 of 527
(1,553 Views)

Thank you, I'll do some investigation on a cRIO target then.

0 Kudos
Message 182 of 527
(1,553 Views)

A few bugs I've seen in the wild that completely break this library in production with actual MODbus/RTU devices. Normal applications are very complex, On average will have 5 devices per bus, with 4-6 bus's per application.

Here is what I've seen:

Multiple serial master instances (in different threads) on the same applciation(seperate com ports) can sometimes randomly result in Error 1556: "???" being thrown, which has no description and just fails. I have no idea what happens.

Multiple serial master istances on the same computer, VERY VERY long block on calls to functions. Actually halts threads in some cases causing error reporting to fail in that thread.

Sometimes write/read functions simply do nothing and do not send data along serial port and just return nothing, and happen instantly.

Complex and conditional calls (putting VI's in if, statements or for statements) sometimes causes them to fail instantly and without error, just silently and intantly return nothing. If your calling something to do what an enqueued item says (after checking if the enqueued item exists) bless your soul its gonna fail, never got this t work. Putting functions in if statement seems to cause them to throw strange error messages, or just do nothing about 75% of the time.

Random Err Code 4: "<Function 4: Failed>" will get thrown. Whole object needs to be re-initalized on this event. Even with communication happening properly. Can't recreate this, need to add a case in every single communication thread to expect it to happen.

:.:.:

All are problems I've ran into using this in production. Which result in this library being almost unusable in production.

0 Kudos
Message 183 of 527
(1,553 Views)

Hi Valarauca,

I wanted to take a few moments to step through your feedback item-by-item. Before I do so, there were  a few things I saw in your blog post that I wanted to comment on.

First, there is no way for one person to perfectly test all the code, let alone perfectly test a network communication protocol that communicates across two physical layers, with three application layers, to the countless modbus devices that have been developed since 1979. That is why the library is posted here--I rely on information from my own use and testing, the use of people I've worked closely with as part of my job, and feedback from people here on the forums in order to improve the quality of the library.

Second, and I cannot stress this enough--this library is in an evaluation stage. This is clearly marked on the download page and outlined in the sample code license included in the package. As noted on the primary download page, a similar library which is supported by one of our alliance partners is readily available here. I, of course, prefer if you use this library and provide feedback, but I am biased as outlined above .

Moving on to more technical topics:

  • I definitely hear your point about the serial unit ID. This issue has been brought up numerous times in this forum thread, and I've provided a few workarounds. However, at least for the use cases I've seen, the value provided by unifying the TCP and serial APIs vastly outweigh the disadvantage of having to change the unit ID using a property node.

  • The timeout has always been setable from the property node, but I agree that 5 seconds was excessive. In a recent release I adjusted serial to calculate the timeout based on maximum packet size, baud rate, and a small fudge factor to allow for processing time on the slave.

Valarauca wrote:

A few bugs I've seen in the wild that completely break this library in production with actual MODbus/RTU devices. Normal applications are very complex, On average will have 5 devices per bus, with 4-6 bus's per application.

Here is what I've seen:

Multiple serial master instances (in different threads) on the same applciation(seperate com ports) can sometimes randomly result in Error 1556: "???" being thrown, which has no description and just fails. I have no idea what happens.

Multiple serial master istances on the same computer, VERY VERY long block on calls to functions. Actually halts threads in some cases causing error reporting to fail in that thread.

Sometimes write/read functions simply do nothing and do not send data along serial port and just return nothing, and happen instantly.

Complex and conditional calls (putting VI's in if, statements or for statements) sometimes causes them to fail instantly and without error, just silently and intantly return nothing. If your calling something to do what an enqueued item says (after checking if the enqueued item exists) bless your soul its gonna fail, never got this t work. Putting functions in if statement seems to cause them to throw strange error messages, or just do nothing about 75% of the time.

Random Err Code 4: "<Function 4: Failed>" will get thrown. Whole object needs to be re-initalized on this event. Even with communication happening properly. Can't recreate this, need to add a case in every single communication thread to expect it to happen.

:.:.:

All are problems I've ran into using this in production. Which result in this library being almost unusable in production.

  • Error code 4 is a Modbus error. As discussed on page 12, I believe, these errors (anything above xxx,x80) indicate that communication with the slave device was successful, but that the request was denied for some reason. This could be that you requested a register that doesn't exist on the slave, or that you requested 50,000 registers in a single read, or any number of other things. Error 4 (ie xxx,x84) is described on page 48 of the spec (http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf) indicates an error on the server. Specifically, each modbus request has a set of checks (in range? supported code? etc.) which must be performed before trying to perform the requested operation. Exception 4 indicates that the request was well-formed but the server failed to perform it correctly. I would recommend consulting your device documentation to determine what would cause this exception to be thrown.

  • Error 1556 is unusal. In order to support threading for the master, I had to wrap the code in a lock (imagine if you sent two serial requests, interleaved, because the master code was able to freely send in two threads). That lock was implemented as a DVR. 1556 indicates the DVR is no longer valid. I just checked through all the code, and I don't see any way the DVR could be invalidated except by calling the Modbus Master.lvclass::Shutdown.vi method. Can you provide code which reproduces the issue?

  • The first thing that comes to mind is that you are sharing a modbus instance across threads. Depending on the timeout (especially if you left it at the default, as described above), the lock I described means that the master functions will block. That is, if you branch the modbus wire and perform a read on each wire, and one of the reads fails...the second read will have to wait the full timeout before it can try again. To my mind this is the correct behavior. If I am misunderstanding, of if you disagree, please provide code which reproduces the issue or your use cases.

  • You mention that in some cases the code just fails with no error. You also mention that is especially likely with conditional code. This may be a result of using LabVIEW objects. In very peculiar situations, the modbus master or slave instance can be replaced with an instance of Modbus API.lvclass. Some time last fall I added an error code to alert users in these situations, because the behavior was rare but extremely bad--as you describe, you would get no data but no error would occur. Does this describe the problem you were having? In either case, could you provide me with your code so that I can understand the issues caused by case statements?

Please review the above and let me know your thoughts. If you are unable to post the sample code here, please consider PMing me. I am very curious to see the code which resulted in these issues with the library. I would also strongly recommend updating to the newest version of the library, if you are not already--there were a number of significant changes in December and January, especially on the serial side.

Thanks,

Daniel

0 Kudos
Message 184 of 527
(1,553 Views)

Bullet Point 1, I'm not refering to the modbus exception. I'm refering to the error I get from a function on call. Sometimes this is thrown when initilzing the class, OR on reads OR on writes. The error code is "Function 4 has failed." not "Modbus exception 4 thrown." I don't know if they mean the same thing, but why would a modbus exception be thrown when creating an object?

Bullet Point 2. The software is closed source and paid for by a client. I'm sorry. I can recreate the thread later this evening. Should be 'close' but not spot on.

Bullet Point 4 is the same.

Also my master serial interface is never shared between threads. If have to have concurrent writes to the same bus I'll likely end up using a consumer/producer loop (with multiple producers if need be), that create objects to be decoded and exect on the actual communication thread. This allows for actual data acquisition to continue at a 'semi-constant' rate, without other other writes getting to 'greedy'.

That's where I normally find my strange errors. I'll provide examples of all of these likely this evening. At the minute I'm on site with customers.

0 Kudos
Message 185 of 527
(1,553 Views)

Hey Valarauca, comments below:

Bullet Point 1, I'm not refering to the modbus exception. I'm refering to the error I get from a function on call. Sometimes this is thrown when initilzing the class, OR on reads OR on writes. The error code is "Function 4 has failed." not "Modbus exception 4 thrown." I don't know if they mean the same thing, but why would a modbus exception be thrown when creating an object?

A modbus exception should not be thrown when creating an object. Can you tell me what actual code comes out? Is it 538184? Based on your statement that it occurs on init, I don't think so. On the other hand, error 4 in LabVIEW is a file I/O error

err4.png

I did a search and looked in the places I would expect, and nothing in the library itself throws any error which states "function 4 has failed". Can you attempt to reproduce this and post the code and source string that are output?

That's where I normally find my strange errors. I'll provide examples of all of these likely this evening. At the minute I'm on site with customers.

Sounds good, I look forward to seeing the code.

Thanks,

Daniel

0 Kudos
Message 186 of 527
(1,553 Views)

Hey arielec,

I've just done a test with the library on my end and I cannot reproduce this. I do see a small loss of memory on occasion, but at nowhere near the rate I would expect for a per-connection issue. I also used a cRIO 9068, which has slightly better memory reporting tools if you know where to look, and with those tools I saw no leak.

I've attached my test. As you can see, I am running the connect/reconnect cycle at a rate of 50 ms, and I don't see any leak at that rate on my end. I'm going to keep investigating to try and figure out what is happening, since memory does still decrease by some reports.

Is there anything your code does when a connection is received that might result in a leak?

Thanks,

Daniel

arielec wrote:

Hello Smithd,

I start with a disponible Memory of 58.246 MB.

                         After 200 connections (16 minutes) 58.050 MB remain ;

                                1000 connections (1 hour) 57.150 MB remain ;

                                2000 connections (2 hours) 56.150 MB remain ;

                                4200 connections (4 hours and 16 minutes) 54.240 MB remain.

Best regards.

0 Kudos
Message 187 of 527
(1,553 Views)

The error 4 I'm having trouble recreating. This will take some dedicated time.

Error 1556 was reached when an un-intialized object reference (the default) is passed to a MODbus/RTU write/read.

0 Kudos
Message 188 of 527
(1,553 Views)

Is there a way to write unsigned 32 bits to the write single holding register function? It seems to only accept 16 bits when i need to write 1,073,741,824 and in between 65535 as an integer.

0 Kudos
Message 189 of 527
(1,554 Views)

Glad to hear it on 1556. Let me know if you get the other error reproducing.

Thanks,

Daniel

Valarauca wrote:

The error 4 I'm having trouble recreating. This will take some dedicated time.

Error 1556 was reached when an un-intialized object reference (the default) is passed to a MODbus/RTU write/read.

0 Kudos
Message 190 of 527
(1,554 Views)