LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple slaves

I have gotten good support from this forum to get a program to communicate over modbus rtu with a sensor (four-wire), which interface is modbus rs485. The sensor is connected to a Rs485/Usb converter and is connected to a PC. 

 

I want to add two or three sensors of the same type to this program. The slaves have different IDs and I want to read the same registers of slaves at the same time.

How do I add a slave? And can I read the registers of for example the temperature with the same sample time?

 

 

0 Kudos
Message 1 of 41
(4,254 Views)

Since you have a shared Modbus bus with more than one slave, you can only poll a single slave with a single message at any one time. So when you write the code to communicate to multiple slaves (irrespective of what registers you are reading) you need to take into account that you can only perform each "message" one at a time serially.

 

Your "sample rate" may have to decrease since you can only active communicate to one device at a time. I see that your current sample rate is about 1s, and you are running at 9600 baud rate so it seems reasonable that a few extra messages could be done within this time.

 

The Query VI you are using for the Read (Read Input Registers) needs to be replicated for each "message" you want to send, be it to a different slave address or for a different set of registers. The Slave Address is part of the Serial Parameters cluster which is an input to this VI. You can set this value to the address of the slave in question for that instance of the Read VI. Also don't forget about data flow and use the error wires to help you control the timing of each node in the sequence.

 

 

Armed with this information, try making these changes yourself and come back to us with your progress.

0 Kudos
Message 2 of 41
(4,239 Views)

@tyk007 wrote:

Since you have a shared Modbus bus with more than one slave, you can only poll a single slave with a single message at any one time. So when you write the code to communicate to multiple slaves (irrespective of what registers you are reading) you need to take into account that you can only perform each "message" one at a time serially.

 

Your "sample rate" may have to decrease since you can only active communicate to one device at a time. I see that your current sample rate is about 1s, and you are running at 9600 baud rate so it seems reasonable that a few extra messages could be done within this time.

 

The Query VI you are using for the Read (Read Input Registers) needs to be replicated for each "message" you want to send, be it to a different slave address or for a different set of registers. The Slave Address is part of the Serial Parameters cluster which is an input to this VI. You can set this value to the address of the slave in question for that instance of the Read VI. Also don't forget about data flow and use the error wires to help you control the timing of each node in the sequence.

 

 

Armed with this information, try making these changes yourself and come back to us with your progress.


Thanks for your reply tyk007!


I have just played around with Labview the last week. I started by adding another Read
Input in serial with the first one, is that correct? And does the wiring work?

 

I have some additional questions regarding functions that I would like my program to do:
1.Since I want to read the same registers of the slaves, can I do this automatically? I
want to do each reading during a fixed amount of seconds and in one sequence with just one
click.

 

2. Should the 2nd slave have a loop that checks if the first slave reading was OK and
without errors. And if everything is OK, the reading from the 2nd slave can start?

 

3. For the 2nd slave, can I connect it to the same wiring for the typecasting that I've
used for the first slave? Not like I have done in the program now..

0 Kudos
Message 3 of 41
(4,199 Views)

@dotis10 wrote:
1.Since I want to read the same registers of the slaves, can I do this automatically? I

want to do each reading during a fixed amount of seconds and in one sequence with just one
click.


Sounds like a simple FOR loop to me, which each iteration reading from a different slave.  All of the other inputs will remain the same.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 4 of 41
(4,193 Views)

@crossrulz wrote:

@dotis10 wrote:
1.Since I want to read the same registers of the slaves, can I do this automatically? I

want to do each reading during a fixed amount of seconds and in one sequence with just one
click.


Sounds like a simple FOR loop to me, which each iteration reading from a different slave.  All of the other inputs will remain the same.


Should I replace my While-loop with a for-loop? Or a For-loop for each slave?

 

0 Kudos
Message 5 of 41
(4,182 Views)

What you have (v1) is a workable solution.

 

As you describe you have duplicated the logic of piecing together the single data from the individual words. Since LabVIEW is a dataflow language you cannot simply just link up two sources to the same point - you actually need two things to execute, not just one.

In LabVIEW the best way of encapsulating common logic is through a VI (called a function in other languages). Since you are using it inside another VI we often call that a SubVI. Its controls and indicators are linked to its connector pane. The LabVIEW help manual contains a lot of information about how to create your own SubVIs and putting the common logic you have in one is a good idea to improve readability and maintainability. 

 

Since you are reading the same registers from each slave, and you might add another slave in the future, you could consider adding a FOR loop inside your While loop. The FOR loop would repeat the same logic of calling the Read node (and your single conversion logic) but would alter the slave address on each iteration. The data from each iteration could pass the boundary of the FOR loop via an indexing tunnel which turns it into an array. Outside the FOR loop you could pick out the items of the array (via Index) for further use. 

 

Have a try at these ideas and come back to us if you are having problems.

0 Kudos
Message 6 of 41
(4,162 Views)

@tyk007 wrote:

What you have (v1) is a workable solution.

 

As you describe you have duplicated the logic of piecing together the single data from the individual words. Since LabVIEW is a dataflow language you cannot simply just link up two sources to the same point - you actually need two things to execute, not just one.

In LabVIEW the best way of encapsulating common logic is through a VI (called a function in other languages). Since you are using it inside another VI we often call that a SubVI. Its controls and indicators are linked to its connector pane. The LabVIEW help manual contains a lot of information about how to create your own SubVIs and putting the common logic you have in one is a good idea to improve readability and maintainability. 

 

Since you are reading the same registers from each slave, and you might add another slave in the future, you could consider adding a FOR loop inside your While loop. The FOR loop would repeat the same logic of calling the Read node (and your single conversion logic) but would alter the slave address on each iteration. The data from each iteration could pass the boundary of the FOR loop via an indexing tunnel which turns it into an array. Outside the FOR loop you could pick out the items of the array (via Index) for further use. 

 

Have a try at these ideas and come back to us if you are having problems.


Thank you!

Okay, do you mean I should create a subVI for the slave config. + typecasting?

 

I added a FOR-loop around the Read node and the typecasting. Should everything connecting to the node be inside like that? How do I change the slave ID for each iteration?

 

I want to save a couple of sample readings from each slave in a column in a excel file in the end. And the same thing for the second slave but in another column. Right now it is just an 1D array.. Or do I have to create a multi dimensional array and save all the read data?

0 Kudos
Message 7 of 41
(4,154 Views)

I wonder if I can have the slave ID as a constant like I have now in order to increment it?


0 Kudos
Message 8 of 41
(4,109 Views)

@dotis10 wrote:

I wonder if I can have the slave ID as a constant like I have now in order to increment it?



No.  You need to think more about LabVIEW basics like how loops work, arrays work,  auto-indexing.

 

Like this.

mb_comm_multi_v1_3_BD

Message 9 of 41
(4,101 Views)

Thank you RavensFan!

Okay, so with the auto-indexing the count terminal is not needed.
What decides how many readings the slave will do/save during each loop?

0 Kudos
Message 10 of 41
(4,093 Views)