From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Industrial Communications

cancel
Showing results for 
Search instead for 
Did you mean: 

Communicating with Gas Analyzer over TCP/IP

Solved!
Go to solution

Overview: I am trying to communicate with several Thermoscientific Gas Analyzers over TCP/IP. I have successfully set up the connections in MAX and think I am pretty close to being able to log this data in real time.

 

Issues: I am not very familiar with Modbus or TCP/IP and clearly am not quite understanding the documentation. I can succesfully open the connection over TCP and do not receive an error. My issue lies with correctly plugging in the right values to the MB Ethernet Master Query Read Holding Registers vi. If anyone could help, that would be fantastic. 

 

What I have so far:

BackendFrontend

 

I am not receiving any errors, but I am not reading any of the holding registers either. I am using a Model 43i Trace Level SO2 analyzer from ThermoScientific. According to the manual, the register numbers I am interested in are 40001&40002.

 

I have attached the vi. Any help would be greatly appreciated.

 

0 Kudos
Message 1 of 12
(9,621 Views)

Hi Hagan, 

 

I have no idea what the root cause is, except that it likely is an addressing issue as it looks like things are setup right. You may want to use the modbus library here: https://decibel.ni.com/content/docs/DOC-30140 instead of the old one though. 

Jesse Dennis
Engineer
INTP
0 Kudos
Message 2 of 12
(9,611 Views)

Thanks for the reply. I would try the new library; however, the computer this is being run on has Labview 2011 installed, not 2012.

 

I am positive the IP address and Port are correct. The main uncertainties lie with the MBAP header and registers.

0 Kudos
Message 3 of 12
(9,608 Views)

I suppose my main question/concern is: What is supposed to go in the MBAP header? It appears to be a cluster of two items (Transaction ID, Unit ID). What do these mean?

0 Kudos
Message 4 of 12
(9,595 Views)

Hey DHagan,

 

I actually saved the library for previous (2011) and uploaded it to the discussion page. There may be some unknown issues with it, which is why I didn't put it on the main page, but I think it is likely more stable than the older library even so. See reply #3 here:

https://decibel.ni.com/content/thread/17712

 

That having been said, while I would love it if you used and had feedback on the newer library, it looks like you do have everything configured correctly and the old one works well enough for common use cases like yours.The reason you are seeing an issue is because of a misunderstanding (an unfortunately common one) between a modbus address and the identifier of a coil, and the de-facto standard for identifying a coil. If you don't care about why this is, and just want the answer, skip past this section.

 

Specifically:

1) The address as defined by the standard is a value from 0 to 65,535. There are coils, DI, holding registers, and input registers. Each is identified by that same address range. Only the function code determines what the actual data is that is associated with that address. Some devices, which are really awkward to use, actually have different behaviors if you read address 0 as compared to when you write to address 0. As ridiculous as that sounds, it is nominally within the specification.

2) There is the concept of an actual data item. For example, there are 65,536 coils ranging from number 1 to number 65,536. When reading one of these coils you use function code 0x01 and you use an address from 0 to 65,535. In short: data items are referred to with 1-indexed names and are addressed using 0-indexed addresses. But it gets worse...

3) At some point, people decided that the naming conventions for modbus were not confusing enough and assigned the very weird order of:

1-Coils (corresponds to function 0x01)

2-Discrete inputs (function 0x02, still going well)

3-Input registers (nooooo...this one is function 0x04)

4-Holding Registers (you guessed it, this data is accessed by function 0x03)

Normally, this then gives you a number to prepend to your data item. For example, your holding registers will be 400,001 through 465,536. But it gets more confusing still! Some people use 0 indexing here, so you actually get 400,000 to 465,535 (1-indexing is far more common). Some people truncate the number of addresses available and just use 40,001 through 49,999 (pretty common, as you saw).

 

Answer (probably):

The way your code is shown, you are asking for address 40,000 of the holding registers. This means that you are actually asking for register #40,001 or modbus data item #440,001. All these things are totally valid, but probably not what you want.

 

More likely is that your user manual is telling you that you want holding registers 1 & 2 (address 0 & 1) identified as modbus data items #40001 & 40002. As such, you should change your "starting address" to 0 and your "quantity" to 2, and that should work.

 

Good luck.

 

Oh, and re: your specific question. For TCP, unit ID is meaningless unless you are talking to a tcp->serial gateway, because you already have a unique identifier (TCPIPv4 addy). Transaction ID is used if you have a more asynchronous style of master, similar to what we have in the DSC I/O servers but very dissimilar to the modbus library. It is usually an auto-incrementing counter which is used to identify requests, in case your master has multiple outstanding requests.

 

I would guess the reason you are getting no errors but also no data is that error handling is less stringent in the older library. The newer library follows the spec a bit more closely, so I think it would throw an error in this particular case. On the other hand, its not the most useful error since there isn't a whole ton you can do about it--basically the slave is not following the spec.

Message 5 of 12
(9,587 Views)

I googled the manual, which I think is this here:

http://www.thermo.com/eThermo/CMA/PDFs/Product/productPDF_30713.pdf

 

 

very confusing. Apparently reading either input or holding registers has the same effect, but it uses the relatively common 4X,XXX nomenclature for registers while numbering coils 1-20. Honestly I have no idea what its doing. I'd try what I suggested, but it may be that you need to contact the manufacturer to make sure its configured correctly.

 

 

Message 6 of 12
(9,578 Views)

Thank you for the ideas. I have tried that solution but unfortunately it has not worked. I have put in a request with Thermo Scientific to see if the manual is possibly wrong. I will update this thread when I hear back.

0 Kudos
Message 7 of 12
(9,535 Views)

Sorry that didn't help, but hopefully it gives you some ammunition to work with Thermo Scientific. I know those modbus VIs have been around for a long time and work decently well, so I'm confident that it should work once you have the device configured correctly. The main reason for the revision was to make them more easily customizable (LVOOP-based) and to improve their API, performance, and coding standards. There weren't many things explicitly wrong about them. 🙂

 

Thanks,

Daniel

0 Kudos
Message 8 of 12
(9,528 Views)

Thanks Daniel. I have spoken with them and they are supposed to be getting in touch with their "Modbus Guru". Hopefully they figure it out and I can update everyone.

0 Kudos
Message 9 of 12
(9,509 Views)
Solution
Accepted by topic author DHagan

I have a solution! It turns out that the Unit ID must be the same as the numeric part of the model number for a specific analyzer. It doesn't mention this anywhere in the documentation (at least, not that I could find). I have posted my solution (vi's) in case anyone else wants to use them or see what I did to fix the issues. Thanks for the help!

 

Link: https://github.com/dhhagan/ThermoLabVIEW

Message 10 of 12
(9,407 Views)