NI Labs Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

NI LabVIEW Modbus API Discussion

Glad its working out for you guys...

Tarsel wrote:

I am about to create a development GUI externalising data from a low power embedded device. This uses a custom Modbus implementation - the transmission protocol is RTU, but the checksum is the LRC (from the ASCII protocol). I can see that you these are wrapped in their respective transmission units. Would it be possible to generate this functionality using your library? I'm guessing I'd need to create a new type of transmission unit.

Yeah, you'd have to make a new ADU class and unfortuntately the RTU ADU is a beast (it started out pretty but it turns out that modern serial APIs like visa are pretty fundamentally at odds with RTU, since RTU doesn't have a message delimiter or length field). Its been a while so I can't recall which pieces are unlocked there,so it may not even be possible for you to get at it. One suggestion I do have is that if you're doing master-only work, you use this:

https://lavag.org/topic/19544-cr-plasmionique-modbus-master/

He modeled the API off this one, but with the goal of being open source. His RTU implementation is better (if less 'pure') than mine. Unless I'm mistaken, it should be drop in replacement.

Tarsel wrote:

I also want to give my thanks for developing this useful library. I'm developing an application now where I'm using it to talk to two SureServo drives from Automation Direct with Modbus ASCII, and in the case of writing one particular parameter in the drive, the Modbus Master.lvclass:Write Single Holding Register.vi is returning error 538189 with the source showing as "<APPEND>Function 6" (which is the "write one register" function). Delving into that vi, it looks like the source is the Master Function Definition.lvclass:Write Single Register Response.vi, which returns the error along with zeroes for "Address" and "Number of coils". I'm taking this to mean that the drive's response to the register write is incorrect, but can you tell anything more from the error code 538189? I'm writing other parameters using the same function without problems. I'm going to try using some other software to write that register and see if I have any better luck.

Thank you,

Aaron T.

Thats pretty weird. Ok, so errors are generated from the modbus spec. If the number is above 538180 its a modbus error (pg 47: http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf). All the code does is takes the returned exception code (for example modbus exception 1) and adds 538180 to it to give you 538181 (Modbus Error: Illegal Function. This function is not implemented on the server.). The issue is of course that, as you can see in the spec, modbus exception 9 is not a valid exception. I honestly couldn't tell you what this means. I'd suggest trying to get hold of a rep from the manufacturer (or search through their documentation for a reference to exception code 9).

Message 361 of 529
(5,570 Views)

Yeah, you'd have to make a new ADU class and unfortuntately the RTU ADU is a beast (it started out pretty but it turns out that modern serial APIs like visa are pretty fundamentally at odds with RTU, since RTU doesn't have a message delimiter or length field). Its been a while so I can't recall which pieces are unlocked there,so it may not even be possible for you to get at it. One suggestion I do have is that if you're doing master-only work, you use this:

https://lavag.org/topic/19544-cr-plasmionique-modbus-master/

He modeled the API off this one, but with the goal of being open source. His RTU implementation is better (if less 'pure') than mine. Unless I'm mistaken, it should be drop in replacement.

Thanks for the steer - I'll check it out.

Message 362 of 529
(5,570 Views)

smithd wrote:

Thats pretty weird. Ok, so errors are generated from the modbus spec. If the number is above 538180 its a modbus error (pg 47: http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf). All the code does is takes the returned exception code (for example modbus exception 1) and adds 538180 to it to give you 538181 (Modbus Error: Illegal Function. This function is not implemented on the server.). The issue is of course that, as you can see in the spec, modbus exception 9 is not a valid exception. I honestly couldn't tell you what this means. I'd suggest trying to get hold of a rep from the manufacturer (or search through their documentation for a reference to exception code 9).

That's very interesting, thank you for the information. I have two SureServo drives that both behave the same way using both ASCII and RTU: I can read a particular register just fine (parameter 1-02, if anyone cares), but even if I try to write back the same value, both return exception 9. I've tried another Modbus tool just to make sure. There's no indication in the drive's documentation that there are any limitations on writing this particular parameter, and also no explanation of what exception 9 might mean. That's the only register I've had any trouble with. Guess it's time for an email to the manufacturer.

Added: Wait a sec, there is a note in the documentation that this parameter can't be written while the servo drive is enabled, but I didn't think I had it enabled. Just watch, that'll turn out to be the cause...

Sure enough, I was accidentally enabling the drive before performing this write, and the drive didn't like it, and now that it's fixed it works fine. Thanks again for your help.

Message 363 of 529
(5,570 Views)

Hi,

I apologize if this has been answered already. It is difficult (at best) to search this thread. I have two issues. The first is that I have a MBRTU master that needs to communicate with up to 25 slaves on one bus, each with a unique ID. Some of those slaves have different purposes, so I would like to call this library from multiple loops (actors) within my application.

1. I see that there is a mutex for a master class instance, but not one for the serial port itself. Is it true that I would need to write my own arbiter for the serial port to prevent a conflict on the port?

1a. If that is true, is it ok to use a single master instance and set the unit ID before each call?

The second issue is that I need to write a simulator for these slave devices. I see that the unit ID is set for each daemon on the slave side, thus preventing the use of multiple slave instances for the same serial port.

2. How would you recommend implementing this? Can I use this library at all for this purpose, or am I looking at having to write my own MBRTU handler that can accomodate multiple slave unit IDs?

Thanks

Eric

0 Kudos
Message 364 of 529
(5,570 Views)

The Plasmionique Modbus Master library would help you with issue #1. You can open multiple instances on a single serial port. The library uses VISA locks to prevent conflicts.

You can download it from LAVA: https://lavag.org/files/file/286-plasmionique-modbus-master/

0 Kudos
Message 365 of 529
(5,570 Views)

Hello Daniel,

Can the Modbus Slave instance of the driver detect/restrict which Master it can allow communication?

We have an application with multiple Masters and we want the Slave to respond to only 1 Master at any given time.

Regards,

Jagan

0 Kudos
Message 366 of 529
(5,570 Views)

EricLM wrote:

1. I see that there is a mutex for a master class instance, but not one for the serial port itself. Is it true that I would need to write my own arbiter for the serial port to prevent a conflict on the port?

1a. If that is true, is it ok to use a single master instance and set the unit ID before each call?

The second issue is that I need to write a simulator for these slave devices. I see that the unit ID is set for each daemon on the slave side, thus preventing the use of multiple slave instances for the same serial port.

2. How would you recommend implementing this? Can I use this library at all for this purpose, or am I looking at having to write my own MBRTU handler that can accomodate multiple slave unit IDs?

Thanks

Eric

1a. yes, thats the appropriate way forward. The master represents the bus, you can talk to multiple items on the bus by setting the unit ID. You can also copy the ref x25 with your different IDs, but I'm guessing the unit id property node call isn't slow enough to be worth it.


Porter's suggestion is also good. If you just were doing master work I'd recommend going with his.

2. This isn't really possible with the library, each modbus instance is, in fact, a unit and so yes there is one unit id.

One tool I used for testing is com0com. http://com0com.sourceforge.net/

You could technically use it to create 25x virtual pairs which would each have their own slave instance attached. Then you have a single (de)mux loop which just reads the unit ID (first byte) and forwards it to the appropriate slave. For the reverse, you forward responses directly from the slave instance. Technically, since the library ignores requests for slaves which are not it, you could just forward all the data back and forth. 1 parallel for loop (or copy pasted loop) and you're done.

Hello Daniel,

Can the Modbus Slave instance of the driver detect/restrict which Master it can allow communication?

We have an application with multiple Masters and we want the Slave to respond to only 1 Master at any given time.

Regards,

Jagan

If its TCP you can configure it to only listen on a specific port, but I'm 95% sure that won't help. For all the other situations (rtu, or TCP all on the same network port) the modbus specification has no real way of identifying the master. Note the frame data listed here:

https://en.wikipedia.org/wiki/Modbus#Frame_format

Because its master slave, the focus is on the master (client) identifying the slave (server) it wants to talk to rather than the reverse.

With TCP it would technically be possible to do, but would require customizing the code. Plus, you'd have to figure out some way for slave to figure out which master it should be talking to, and if that changes on the fly then how to tell multiple connections to the different masters which one is the primary and which is/are secondary. It could easily become quite a mess.

Message 367 of 529
(5,570 Views)

Hi everybody  I'm using Unsupported free ni modbus library 1.2.1 for a long time. I never use opc server or modbus IO server or share variable or something like these, Also CRIO or any RT target HW. I just use a PC as a modbus Master and Communicate via it thourgh a network of modbus Slaves.  so what I need to know is:  I can use this NI Modbus API in 2015 DSC toolbox such as old unsupported Free NI Modbus Lib just with a PC and without need to any matters like RT module or Specific HWs or something like it!!!?  thank you and best regards

0 Kudos
Message 368 of 529
(5,571 Views)

Hello! This seems to be the place to ask questions about this great API.

I'm trying to read several hundrer holding registers from a Modbus slave.

I can successfully read registers 0-100, or 100-200, but if I try 0-200 I get:

LabVIEW error 538182

Modbus Error: Illegal Data Address. The specified data address is not an allowable address for the server.

Function 3

Edit - Some more information:

It seems that reading 125 registers is the limit. When attempting to read 126 I sometimes also get the error:

LabVIEW error 56

IP Data Unit.lvclass:Read ADU Packet.vi:5030001<APPEND>

<b>Complete call chain:</b>

     IP Data Unit.lvclass:Read ADU Packet.vi:5030001

     Modbus Master.lvclass:Read Holding Registers.vi:2420001

     MMC Modbus.lvlib:MMC Modbus.lvclass:Test Modbus.vi

or error "Function 3" above.

I can work around this by only reading 100 registers at a time, but it should work, so I would like to figure it out.

Any ideas?

Thank you in advance!

0 Kudos
Message 369 of 529
(5,571 Views)

Unfortunately there is no workaround, the 125-register limit is part of the protocol. (see pg 15 : http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf)

Message 370 of 529
(5,571 Views)