NI Labs Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

NI LabVIEW Modbus API Discussion

I had a similar problem with the FTDI device and the problem in my case was due to missing pull-up/down resistors on the data lines.

0 Kudos
Message 331 of 529
(2,640 Views)

Thanks for the quick reply.  See my comments below:

smithd wrote:

I generally wouldn't recommend sharing a master between parallel loops. Because modbus is a request-response protocol you can only handle a single request at a time on a given connection (hence the lock inside to prevent accidentally breaking this rule). Its also just strange to me why you'd want to talk to a single slave from multiple loops, I would normally write some sort of intermediary driver to hide how terrible modbus is from the rest of the application (ie you send your modbus loop "please set pressure to 25" and the solitary modbus loop converts this sane and reasonable request into "Write holding registers, 0-2, (uint[])25".

Sorry I should have explained my situation.  I don't want to talk to a single slave from multiple loops.  I want to have multiple RS485 slaves (maybe different mfgs, maybe the same) with separate Unit IDs run asynchronously. The slave(s) code would be independent modules (loops/actors/whatever) that would accept messages to them like you mentioned "please set pressure to 25" and convert the request to their specific registers, and write holding registers using the API.

I was just trying to determine if I could call your code directly in the slave module code but this would only work if the API's "Master Network Read Write.vi" had a semaphore or mutex that would lock even in parallel calls.  But based on your response, it sounds like I should implement your #2 recommendation below and create a separate owner loop (module/actor etc) to wrap the API's master instance.  Then this module could handle messages to it to "write holding registers" etc and setting up the maseter instance connection TCP/IP or Serial, COM parameters,etc.  The slave module code would then send their messages to this loop.

smithd wrote:

If you really do need to have multiple loops talk to one slave:

1-If TCP, just open multiple separate connections. This gets rid of the lock and most slaves will support it

2-If serial, you're more likely to run into issues because of how visa works. You could technically make two masters on the same visa port, but visa won't protect you from accidentally sending two requests simultaneously, which could lead to reading back the responses in the wrong order, which is of course not great. For this, I'd recommend using your own DVR or global variable (have one loop be the 'owner' who has to maintain the connection, but other loops can grab it and attempt to write to it, ignoring any errors or perhaps sending a "hey do your job" to the loop who is supposed to maintain it).

In the past, the way I handled the parallel VISA issue you mentioned in #2  was to create a semaphore locking mechanism (mutex) around visa read/write pairs that looked up the semapore instance by name using the base VISA address.  I never had much luck with VISA Lock/Unlock.

VISA Read Write w Semaphore.png

Thanks for your help!

0 Kudos
Message 332 of 529
(2,640 Views)

Hello Daniel,

We are using the Modbus library to communicate from RS-485 port on cRIO to multiple Modbus Slaves with different Unit ID's. 

I am having communication issues if I try to initiate multiple instances of the "Serial Master API Call" and try to communicate with different devices at the same time in parallel loops.  I am opening the same RS-485 port with different unit ID's.  However, if I use semaphores and try to control the Read/Write between the loops so that only 1 operation occurs at a time, then there are no issues.

Basically, using a single RS-485 Modbus Master can we communicate with Multiple slaves in parallel? or do we need to do them in serial by setting the appropriate Unit ID?

0 Kudos
Message 333 of 529
(2,640 Views)

Basically, using a single RS-485 Modbus Master can we communicate with Multiple slaves in parallel? or do we need to do them in serial by setting the appropriate Unit ID?

Thats what I as asking about in 327 and based on smithd's answer in post 328 (below) it sounds like you need to have a single instance of the Serial Master and store it in a global or DVR or have a single separate helper loop that manages the Serial Master and receives messages from your slave code.  Speculating here but it sounds like the API does not have a "global" semaphore mechanism.

328. Mar 15, 2016 9:04 PM (in response to bean123)

Re: NI LabVIEW Modbus API Discussion

Its by value, but most things internally are references. For example, a Modbus master has a TCP ref and a lock (to stop you from accessing the connection on multiple threads at the same time) and the master has a data model (which contains DVRs of all of the registers, coils, etc which constitute a slave). A few things are values, like which slave ID the master is talking to (handy on multi-drop serial or tcp-to-serial networks).

I generally wouldn't recommend sharing a master between parallel loops. Because modbus is a request-response protocol you can only handle a single request at a time on a given connection (hence the lock inside to prevent accidentally breaking this rule). Its also just strange to me why you'd want to talk to a single slave from multiple loops, I would normally write some sort of intermediary driver to hide how terrible modbus is from the rest of the application (ie you send your modbus loop "please set pressure to 25" and the solitary modbus loop converts this sane and reasonable request into "Write holding registers, 0-2, (uint[])25".

If you really do need to have multiple loops talk to one slave:

1-If TCP, just open multiple separate connections. This gets rid of the lock and most slaves will support it

2-If serial, you're more likely to run into issues because of how visa works. You could technically make two masters on the same visa port, but visa won't protect you from accidentally sending two requests simultaneously, which could lead to reading back the responses in the wrong order, which is of course not great. For this, I'd recommend using your own DVR or global variable (have one loop be the 'owner' who has to maintain the connection, but other loops can grab it and attempt to write to it, ignoring any errors or perhaps sending a "hey do your job" to the loop who is supposed to maintain it).

0 Kudos
Message 334 of 529
(2,640 Views)

https://decibel.ni.com/content/message/58374#58374

^^see my comments here

glennnorberg wrote:

Hi

I am using this driver and it works without any problems.

I am facing a problem though... I need to send user defined funtion codes but as I understand it the driver "only" support standard ones.

Is there a way to send user defined codes or is there a workaround in available?

Best regards, Glenn Norberg

0 Kudos
Message 335 of 529
(2,640 Views)

bean123 wrote:

I was just trying to determine if I could call your code directly in the slave module code but this would only work if the API's "Master Network Read Write.vi" had a semaphore or mutex that would lock even in parallel calls.  But based on your response, it sounds like I should implement your #2 recommendation below and create a separate owner loop (module/actor etc) to wrap the API's master instance.  Then this module could handle messages to it to "write holding registers" etc and setting up the maseter instance connection TCP/IP or Serial, COM parameters,etc.  The slave module code would then send their messages to this loop.

In the past, the way I handled the parallel VISA issue you mentioned in #2  was to create a semaphore locking mechanism (mutex) around visa read/write pairs that looked up the semapore instance by name using the base VISA address.  I never had much luck with VISA Lock/Unlock.

VISA Read Write w Semaphore.png

There is a lock (I use a DVR because it is the fastest lock I know of in labview, much quicker than the semaphore) but it isn't tied to the resource its tied to the master instance. So yeah, you can either make a single master instance for your visa session, fork the wire, and set the unit ID on each wire (thus copying the lock), or you can make your own locking mechanism. The risk of forking the wire is if one loop closes the master instance for some reason every loop gets hosed.

0 Kudos
Message 336 of 529
(2,640 Views)

JaganT wrote:

Hello Daniel,

We are using the Modbus library to communicate from RS-485 port on cRIO to multiple Modbus Slaves with different Unit ID's. 

I am having communication issues if I try to initiate multiple instances of the "Serial Master API Call" and try to communicate with different devices at the same time in parallel loops.  I am opening the same RS-485 port with different unit ID's.  However, if I use semaphores and try to control the Read/Write between the loops so that only 1 operation occurs at a time, then there are no issues.

Basically, using a single RS-485 Modbus Master can we communicate with Multiple slaves in parallel? or do we need to do them in serial by setting the appropriate Unit ID?

Hey Jagan

Bean is basically right. If I recall correctly you're using the cvt or similar to manage data locally and then transmitting data over modbus. In that situation I'd put everything that talks on your 485 interface in a single loop, and have a nested for loop where the first thing you do is set the unit ID (there is a property node) and then within the inner for loop you write all the values for that slave, then change the unit ID again, etc..The challenge with 485 is there is no connection management of any kind, so you have to execute everything in order anyway, so putting it in one loop will be the fastest way to do that.

As with my above post to bean, you can technically fork the wire, but with 485 there is little to no advantage and it opens you up to a lod of headaches.

If you need better loop rates with serial, another option I've seen is using ethernet to serial or usb to serial converters, but I don't know if those will be appropriate for your situation.

0 Kudos
Message 337 of 529
(2,640 Views)

Do you have a "Write X" aswell?

0 Kudos
Message 338 of 529
(2,640 Views)

No but there isn't any real difference. All modbus operations are a request followed by a response. Read X has a small request and a big response to parse back out. Write X has a big request but a small response.

0 Kudos
Message 339 of 529
(2,640 Views)

Hi smithd,

I am having a problem reading Holding Registers with the Modbus API.

I did set up communication and protocolled it via WireShark with a Modubs Master Simulation Tool and my LabView programm to identify the Problem. It appears with my Programm I am sending not the right ID unit....


My Question is:

How can I set up the Unit Device with my Programm?

My Set up is:

-LabView 2015 and Modbus API as Modbus Master

-SMA Inverter as Modbus Slave

Programm:

Programm.jpg

Data sent:

Left side: (LabView Programm with false Unit ID), Right Side: (Modbus Simulator with Unit ID 3)

Vergleich.Daten.Senden.jpg

Data received:

Left Side (False Data through false Unit ID), Right Side (Modbus Simulator with right answer)

Vergleich.Daten.Rückmeldung.jpg

Frontpanel:

Frontpanel.jpg

Thanks in advance for any Answer.

Greetings

0 Kudos
Message 340 of 529
(2,640 Views)