LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

I cannot read and write information using the Modbus API library and the serial port becomes unusable when the program is run.

Solved!
Go to solution

@constructionworker wrote:

What exactly is the correct way to do this.


The answer is as always with such things: it depends.

 

In this specific case you would use a one dimensional array that auto-indexes just as the address array. And to make the single scalar value on the inside of the border match the array input of Write Register function, to place a Build Array Node in between with one element input.

 

As to writing negative values: Again it depends on what you want to write and how that register is defined by your device. If it is defined as a 16 bit signed integer with range -32768 ... 32767 you can create such a control or constant in LabVIEW and then use a ToUInt16 conversion function to convert it to an unsigned 16-bit integer before sending it to the Modbus Write function. If it is designed as a 8-bit signed integer instead with a range of -128 to +127 things are less clear and it depends very much how the device treats the actual 16 bit register internally. The above code may still work or it may not, depending on the device implementation.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 21 of 37
(2,123 Views)

I think the source of the problem is the Modbus API I tried to explain a bit in the picture below. Is there any way to fix this?

0 Kudos
Message 22 of 37
(2,107 Views)

That's the address you are pointing at. There are no negative Modbus addresses.

 

As to data: Modbus only has 16 bit unsigned registers (and coils, which are single booleans). If your device likes to interpret the bits in such a 16 bit register as signed number or not is entirely up to the device but Modbus itself does not have signed integer registers.

 

So the "problem" is that you need to understand how your device likes to interpret that register and then write the correct bit pattern into it so that it understands the data. If your device likes to treat a register as an int16 value, you can in LabVIEW create a signed 16-bit integer control and enter the value as you like it, then convert it to a unsigned 16 bit integer and transfer it through the Modbus VIs and then check that the value is seen correctly in the device. If not you need to investigate where the difference happens. As already mentioned the main issue is simply to understand how your device likes to interpret the register. If it wants to treat it as boolean it still is a 16 bit register but only the first bit of those 16 bits is interesting for it. If it wants to use a 32 bit value it has to use two 16 bit Modbus registers and combine them to a 32 bit register. You have to then know what order the two registers are to be done, as you can either have the first register containing the lower significant 16 bits or the second register. All of this is however entirely independent of LabVIEW as you first have to understand how your device "thinks"! And this is where these exercises often end. Not because LabVIEW can't do it, it certainly can, but because the person doesn't understand about integers and that they are in essence also simply a variable number of bits and that you can perfectly transfer that bunch of bits as an unsinged 16 bit integer and the device will simply treat it as a signed integer then, if it insists on a signed integer.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 23 of 37
(2,103 Views)

If I enter an I32 value in Labview and send a value using Labview modbus, the device always sends a value between 0-65535, the device reads this value and writes it to the parameter as it is.

 

I think the modbus library accepts U16 value within itself. Whatever I write, it always converts the text as U16.


However, the device's own parameter can take a value between -75000 - +75000 and returns the motor as CCW-CW.

0 Kudos
Message 24 of 37
(2,099 Views)

Well, if you need a range of -75000 to + 75000 you obviously have a larger range than what a 16 bit integer can contain, no matter if it is signed or not.

 

So that means that your device really needs a 32 bit signed integer, and since Modbus only has 16 bit registers, it needs to combine two of them to create such a 32 bit register. How to do that?

 

Do you remember the code earlier on where we had register to read that were 32 bit. You read 2 registers and "combined" them into a 32 bit integer.

 

Now you want to write such a register so you have to reverse that operation. You take a 32 -bit number and split it into two 16 bit numbers and send them as that to the device. It's as simple as that, except you need to know the order in which those 2 16-bit registers are to be transmitted. From the earlier example when reading a 32-bit register we saw that the first register was the lowest significant 16-bit and the second register was the highest significant 16-bit, so it is quite safe to assume that that also applies to registers we need to write.

 

Here are a number of possibilities to do this:

 

32-bit integer to Modbus registers.png

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 25 of 37
(2,086 Views)

I corrected it as you said, negative values can be written. But it writes the same value to two different parameters. What is the reason? Normally it was supposed to write only to an address I specified, now it writes the same value to the next address.What is the reason of this ?

 

 

I know I've been keeping you busy with my ignorance. I'm really starting to learn faster by trial and error and doing what you say.

0 Kudos
Message 26 of 37
(2,081 Views)

I think I solved the problem. It was solved by converting a 2 dimensional array. Do you think this method is correct?

0 Kudos
Message 27 of 37
(2,075 Views)

Well if it works it works. It looks a bit like playing around until it seems to do what it should without quite understanding what you did. But if it works it works.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 28 of 37
(2,067 Views)

@constructionworker wrote:

I think I solved the problem. It was solved by converting a 2 dimensional array. Do you think this method is correct?


Since those two locations are directly consecutive - P1-09 and P1-10 are directly behind each other - and you want to write the two registers that make up such a location anyhow, it would be much better to simply create a 1D array that contains the four 16 bit registers and simply write that to the Modbus with start address 0112H. This way you write both locations in one go without needing 2D arrays. If the registers are not directly behind each other, then you would have to separate the two writes of course. 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 29 of 37
(2,044 Views)

Hi,

I am also using the same delta AC servo drive with LabVIEW. Am also facing the same issues. i cant able to sort out it. Could you please share the developed set of VIs for that drive if possible. That will be more useful for me.

Thanks in advance

0 Kudos
Message 30 of 37
(1,937 Views)