NI Labs Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

NI LabVIEW Modbus API Discussion

If you really need all the registers, there is no workaround, you need to read several packets. But in case you just need a few which are just to far apart, you should check, whether your slave provides a user definable register area, where you can arrange the required variables in a block of 125 registers. I know of several devices implementing such a function in different ways.

Message 371 of 527
(1,371 Views)

Thank you smithd and SKauth for quick replies. I should have read the protocol better.

Maybe the "Read Holding Registers.vi" should have these ranges in the context help.

I've implemented several packages, and it works well.

Thanks

0 Kudos
Message 372 of 527
(1,371 Views)

Hello smithd,

I have just started to implement a ModbusTCP slave on a cRIO and I tried 2 approaches; use Modbus slave I/O server & use the Modbus VIs under Data Communication palette.

Both worked without any issues and I was able to establish communciation with the cRIO uisng a Modbus master application, no problems with that.

But stumbled upon few issues trying to build more functionality, maybe you could help:

  1. I couldn't find an opening to expand the Modbus functionality, like, for example, being able to add user defined function codes.
  2. Modbus standard function codes 20 & 21 (Read & Write file record) are missing.
  3. My application has to cyclically poll the modbus registers to look for write updates from a Modbus master. Is there some kind of notification mechanism available to the application to get rid of the cyclic register polls ?
  4. And a final question; I use Labview 2015 with Real time module, does the Modbus API come bundled along with them or does the library have to be installed separately (assuming the already existing Modbus VIs found under the Data Communication palette & Modbus slave I/O server are something different from the Modbus API or am I wrong !?)

Thanks in advance.

0 Kudos
Message 373 of 527
(1,372 Views)

4. The version included in DSC and Labview rt is the productized version of the code here. The core of its the same, but its better documented and the higher level stuff is cleaned up. You can still override functionality in that version, but the intent was to close it off more. The version here on ni labs was intended to remain the highly customizable version.

2. They are 'missing' because I believe you're the first person who has ever asked for those function codes and I don't remember ever seeing those function codes implemented by any master or slave anywhere ever . I mean I'm sure they are somewhere, but they're not common. Same thing with the fifo. I thought about doing it for completeness but it would have been a waste of time.

1, 3. This is more or less covered elsewhere in this thread, but its sort of mixed in. I skimmed around and found these two:

Post 62 (https://decibel.ni.com/content/message/61104#61104) is the event one which should get you started.

https://decibel.ni.com/content/message/72889#72889 and two posts down from there (posts 197/199) will likely also be helpful.


0 Kudos
Message 374 of 527
(1,372 Views)

Hi, I am using LabVIEW 2013 with version 1.1.5.39 of this library.  I am communicating with a single device using rs-485.  Occasionally I get a 'blip';  Im reading out a float32 by reading a pair of I16 registers.  What is see is the second register sometimes reads zero resulting in the incorrect float value.  Either the instrument is creating the bad value and sending it over MODBUS, or there is a communication glitch.  I would expect a glitch to be detected by the CRC, but i cant get into the password protected VI's to see the CRC implimentation.  Please can you confirm that a CRC fail would result in a a LabVIEW error code being generated by the MODBUS read VI's?

Thank you, Michael.

0 Kudos
Message 375 of 527
(1,371 Views)

For a serial device the API will provide a timeout if the CRC is invalid. However this is not a guarantee of correct information, as the CRC can, in theory, provide a false positive. Essentially the serial code CRCs the entire response, including the sender's CRC. If that resultant CRC = 0, its considered to be a valid packet. It is possible for a partial packet to provide a CRC of 0. To correct for this possible error, the API tries to follow the spec by waiting for a pause in data, but unfortunately VISA and other high level abstractions don't make this easy and there is a chance of an error there, as well. This becomes especially problematic with USB-serial converters, which seem to have significant delays sometimes mid-packet.

However, I think it is highly unlikely that both errors are occuring together, which would have to be the case in order to result in the failure you're seeing.

For debugging I have a few thoughts:

-I can't remember which of these is used, but take a look at the functions in Modbus Library\Serial Shared Components and Transmission Data Unit\RTU and see if you have access to any of those or if they are password protected. If you can debug them, you might be able to catch the raw string.

-If this doesn't work, you can debug using NI spy (its called something like IO trace now) which shows literally every visa call, along with some of the associated data.

-I'm not aware of any, but there may be an OS-level tool for snooping com ports.

-You could create a simple fuction which just writes the single modbus request causing you issues and just reads over and over again until you see a failure (or don't).

-Worst case, you can use a tool called com0com (http://com0com.sourceforge.net/) to create a virtual port. So basically you make a simple VI which reads from the real serial port continuously and writes to the virtual port/reads virtual port and writes to real port. Then point the modbus library at the com0com virtual port instead of the real one, and now you have a little sniffer.

0 Kudos
Message 376 of 527
(1,371 Views)

RE: This is good input. I think I may have found an obvious problem and that is MAX is configured for four wire transiver mode. My current issue is that MAX has that greyed out and I can not change it to two wire auto. Do you know why MAX wont allow me to change it and how to force MAX to allow me to change it?

0 Kudos
Message 377 of 527
(1,371 Views)

RE: I have established 2-wire com link but I am still getting the error. I launched NI I/O Trace and found the read error but frankly I am not sure what I am looking for in hex. I am getting back data but it is nonsense.

0 Kudos
Message 378 of 527
(1,371 Views)

teslac, you could try the "MB_Master Comm Tester.vi" that is included in the Modbus Master library from here: https://lavag.org/files/file/286-plasmionique-modbus-master/

https://lavag.org/screenshots/monthly_04_2016/60cb2c285b820d77a4d0f5caeb58b1fd-comm-tester.png

It displays the last message (ADU) sent and received over the serial port in hex format. You can interpret the message with the help of the Modbus Application Protocol Spec: http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

Message 379 of 527
(1,371 Views)

I'd go with Porter's suggestion. Otherwise, to interpret the data you have to look at the protocol. If you want to go this route, see below...

The response for 'read multiple holding registers' is:

RTU Wrapper { Modbus Packet}

=>A { Modbus Packet} CC where A = address and C = CRC

=> A {FN(VV,VV...*N)} CC where F is function code 0x03, N is number of bytes, V is values which always come in pairs of bytes

So if you requested 2 holding registers (func 0x03) starting at register 10/0xA from address 1, you'd be sending:

0x01{03,000A,0002}CrC

and you'd get back, assuming a stored value of 0x0A0B,0x0C0D:

0x01{03,04,0A,0B,0C,0D}CrC.

Since this pattern is always followed, you can just look at the visa read and look at hex bytes 4-7 and see if there are any zeros.

0 Kudos
Message 380 of 527
(1,371 Views)