NI Labs Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

NI LabVIEW Modbus API Discussion


@S1ack wrote:

Read adjacent registers, combine to 32 wide, then run through a type cast to SGL.

Assuming your meter handles these as IEEE 754 floats.

 

 


WOW that was sweet!

 

Certainly a lot easier than what Accuenergy told me to do to make the conversion. They sent me a spreadsheet with a really convoluted conversion formula built in that I was about to try to decipher.

 

 

 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 471 of 529
(3,469 Views)

Hello API Forum,

 

I am hoping to use the modbus VI's to be able to read the PDU. I have found that while the "modbus slave" example does work for writing input registers, coils etc, it is not functioning as a slave. In the example you press a boolean and then it writes to the master. However, I want this to work as a slave so I want to read the incoming request from the master and use the function code and starting address as inputs to the "writing inputs" subVI. I have attached an image of my code however when I run I get the following error at the "Read ADU" subVI. 

 

Error 538179 occurred at Network Protocol.lvclass:Protocol Read.vi:4650001

Possible reason(s):

The object used has been invalidated. A method was called on an interface class.

 

Any help is appreciated we are fine translating the hex but we need to see the master's request which is what I thought all slave devices needed before they sent data so I do not understand why getting this "request packet" is such a challenge. 


Thanks,

Tanille

0 Kudos
Message 472 of 529
(3,409 Views)

Hello API Forum,

 

I am hoping to use the modbus VI's to be able to read the PDU. I have found that while the "modbus slave" example does work for writing input registers, coils etc, it is not functioning as a slave. In the example you press a boolean and then it writes to the master. However, I want this to work as a slave so I want to read the incoming request from the master and use the function code and starting address as inputs to the "writing inputs" subVI. I have attached an image of my code however when I run I get the following error at the "Read ADU" subVI. 

 

Error 538179 occurred at Network Protocol.lvclass:Protocol Read.vi:4650001

Possible reason(s):

The object used has been invalidated. A method was called on an interface class.

 

Any help is appreciated we are fine translating the hex but we need to see the master's request which is what I thought all slave devices needed before they sent data so I do not understand why getting this "request packet" is such a challenge. 


Thanks,

Tanille

Download All
0 Kudos
Message 473 of 529
(3,397 Views)

dunno why you need to see the PDU, or the incoming function code. Create your slave then populate the slave's data where ever you see fit, and it'll serve up the proper response to the client (master). Client (master) being external to whatever target you are running this LabVIEW API on.

 

This would create a slave that has incrementing data available every 500ms in 2 holding register words at whatever starting register. The server (slave) will only return this data if the client (master) requests the appropriate holding register via FC 3.

 

Untitled.png

0 Kudos
Message 474 of 529
(3,406 Views)

The problem I see with this is that you have the "starting address" as the input. The request from the master should specify the starting address. I need the PDU so that I know the function code and starting address that they are requesting. I would expect to see an input being a message from a master that says what is looking for. Does my question make sense? I have thought about just filling in the registers with our arrays but what if we fill them in starting at the 0 address but the PLC is actually expecting it at a starting address of 10? I want this change in starting address to come over automatically based on the PDU and I do not want to change this as a control in labview because it will be changing every second. We are righting 5 different arrays of 10 doubles each every second to different starting registers (of which we don't even know the starting address right now because the PLC will be from our customer so they will just ask for the arrays to be sent wherever works best for them. 

 

Thanks,
Tanille

0 Kudos
Message 475 of 529
(3,393 Views)

With any commercial off the shelf modbus slave, the manufacturer publishes a modbus map. It informs the client (in this case your customer's PLC) where the data they want is. In this case you decide where the data is, document it, and inform your customer. It's up to them to program the client accordingly.

 

0 Kudos
Message 476 of 529
(3,389 Views)

I am working with an Accuenergy Accuvim-L power meter. I am trying to set a register to clear accumulated energy.

 

According to the manual to clear energy:

  1. Set Clear Energy Enable (1=enable 0=disable)
    1. Write address 0x010E with the value 0001
  2. Clear Energy (0xA=clear 0= don't clear)
    1. Write address 0x010F with the value 0x000A

The issue I am having is when I try to write anything besides "0" to ANY address I get the error:

 

Error 538184 occurred at an unidentified location

Possible reason(s):

Modbus Error: Server Device Failure.
Function 16

 

More to add: The manual says to use Function 3 for read and function 16 for write.

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 477 of 529
(3,385 Views)

Serial or TCP?

 


@RTSLVU wrote:

 

More to add: The manual says to use Function 3 for read and function 16 for write.


So we are dealing with holding registers.
Download ModbusPoll and use it to poll your device and get a feel for what the slave allows. ModbusPoll will return illegal address exceptions, and perhaps even tell you if certain function codes are not supported on the slave. I have come across one device in my career that would only accept single register writes (unless you were writing a float it then accepted both words of the float). ModbusPoll allows you to try function code 6 (single HR) or function code 16 (multiple HR) on writes.

 

If there is a mismatch between one-based and zero based addressing LabVIEW - slave, the slave might reject the request ans invalid address. Try changing your poll starting address +/- 1.

 

 

0 Kudos
Message 478 of 529
(3,379 Views)

@S1ack wrote:

Serial or TCP?

 


@RTSLVU wrote:

 

More to add: The manual says to use Function 3 for read and function 16 for write.


So we are dealing with holding registers.
Download ModbusPoll and use it to poll your device and get a feel for what the slave allows. ModbusPoll will return illegal address exceptions, and perhaps even tell you if certain function codes are not supported on the slave. I have come across one device in my career that would only accept single register writes (unless you were writing a float it then accepted both words of the float). ModbusPoll allows you to try function code 6 (single HR) or function code 16 (multiple HR) on writes.

 

If there is a mismatch between one-based and zero based addressing LabVIEW - slave, the slave might reject the request ans invalid address. Try changing your poll starting address +/- 1.

 

 


Serial and it seems to work fine using ModbusPoll

 

I don't understand what I am doing wrong in LabVIEW...

 

 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 479 of 529
(3,375 Views)

@RTSLVU wrote:

@S1ack

I don't understand what I am doing wrong in LabVIEW...

 

 


Now I do.... I  have made a VI with all the Register Set commands for this device. In that I used a Type.def enum to select the command.

 

Anyway I skipped a command so (only some of) the register addresses I was trying to write were off by one. 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 480 of 529
(3,374 Views)