OleObject.Value?

Hi!

The activeX plugin ive been trying to use:
http://www.modbustools.com/modbus_activex.html

I can read registers fine, but writing to them seems to cause problems, or then im not seeing the forest from all of the trees
 :smiley:

Has anyone been successful getting values set to a ActiveX plugin using the .Value when you have to pass parameters to the called function?

Ive noticed that i have to use invoke command at some points, but now im faced with that i have to pass a new value to the invoke command


I got upon the .Value, but i have not been successful in using it with parameters.

In short: I can’t get following to work okay (when i have to pass some things to the Register function to set specific things):

Values has been loaded with

dim values(2) as variant values(1)=Handle values(2)=0

modbus.Value("Register",values)=value2

But this i can get work okay:

modbus.Value("IPAddr4") = 120

Basically all text below this explains the above thing in a long way:

The MBAXP documentation VB example:

MBAXP DOCUMENTATION

Method PresetSingleRegister

Description:
Function 06 (0x06). 4X references.
This function code is used to write a single holding register in a slave device.

Syntax
Visual Basic:
Function PresetSingleRegister (Handle As Integer, SlaveID As Integer, Address As Long, UpdateRate As Long) As Booleean

Visual C++:
BOOL PresetSingleRegister (short Handle, short SlaveID, long Address, long UpdateRate);

Parameters:
Handle: Transaction Handle. 0 to 199.

SlaveID: The slave ID. 0 to 255.

Address: The data address. 0 to 65535.

UpdateRate: 1 to 600000ms

Return:
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.

Example:
Write a incremented value to address 40007 in slave 2 and 3 every 1000ms

Dim e As Integer
Dim v1 As Integer
Dim v2 As Integer

Private Sub Command1_Click()
  v1 = 0
  v2 = 0
  e = Mbaxp1.PresetSingleRegister(1, 2, 7, 1000) 'Use handle 1
  e = Mbaxp1.PresetSingleRegister(2, 3, 7, 1000) 'Use handle 2
  Mbaxp1.Register(1, 0) = v1 'Internal array 1,0 = the value to write
  Mbaxp1.Register(2, 0) = v2 'Internal array 2,0 = the value to write
  Mbaxp1.UpdateEnable (1)   'Continuously update
  Mbaxp1.UpdateEnable (2)   'Continuously update
End Sub

Private Sub Mbaxp1_ResultOk(ByVal Handle As Integer)
  If Handle = 1 Then
    Label1 = "Success 2"  'Preset Single Register success
    v1 = v1 + 1           'increment v1
    Mbaxp1.Register(1, 0) = v1 'The incremented v1 is written next time
  End If                        
  If Handle = 2 Then
    Label2 = "Success 3"  'Preset Single Register success
    v2 = v2 + 3           'increment v2
    Mbaxp1.Register(2, 0) = v2 'The incremented v2 is written next time
  End If                        
End Sub

 

END OF MBAXP DOCUMENTATION

The code i have tried to use as a method:

// METHOD: WriteRegister (Handle as integer, SlaveID as integer,Register as integer,value2 as int16)

dim retu as boolean
dim error as integer
Dim modbus As OLEObject
modbus = Window1.OLEContainer1.Content

dim WriteHRparam(4) as variant
WriteHRparam(1)=Handle //Handle (1-200)
WriteHRparam(2)=SlaveID //SlaveID
WriteHRparam(3)=Register //Register, PLCbase1 (0 is first register)
WriteHRparam(4)=10 //update_rate

modbus.Invoke("PresetSingleRegister",WriteHRparam)

dim values(2) as variant
values(1)=Handle
values(2)=0


//dim values2(1) as variant
//values2(1)=value2

dim valer as variant  // tried this way to set the value too, didnt help.. :(
valer=value2

modbus.Value("Register",values)=value2
if retu <> true then
  msgBox("ERROR set reg.")
end

dim param2(1) as variant  //param  handle for update funktion.
param2(1)=Handle //handle
modbus.Invoke("UpdateOnce", param2)
app.sleepCurrentThread(200)

IP setting works fine:
MBAXP example:*

MBAXP1.IPAddr1 = 235 MBAXP1.IPAddr2 = 12 MBAXP1.IPAddr3 = 134 MBAXP1.IPAddr4 = 6

The code that i use to set IP and i works great:

modbus.Value("IPAddr1") = IP1  // USE THIS WAY TO SET PARAMETERS!!!
modbus.Value("IPAddr2") = IP2
modbus.Value("IPAddr3") = IP3
modbus.Value("IPAddr4") = IP4
modbus.Value("ProtocolMode")=0  // selects modbus TCPIP

If you are passing an array of params, dont you have to use ValueArray not Value ?

The documentation says that you can pass values to OLE like this:

OLEObject.Value(Name of Property as String, params() as Variant)=value

But so much time had passed that i bypassed the problem by calling a extrenal exe that handles the OLE object better.

Finally! Today i got it to work, the trick was to update the handle twice to get the wanted result:

' Setup the modbus IP:s and other things before running this code snippet

dim retu as Boolean
Dim modbus As OLEObject
modbus = Window1.OLEContainer1.Content  // Get the modbus OLE container.


dim ReadHRparam(4) as variant
ReadHRparam(1)=1                                                                            ' Handle (1-200)
ReadHRparam(2)=val(SLAVEID.text)                                                ' SlaveID
ReadHRparam(3)=val(RegisterNum.text)                                        ' Register, PLCbase1 (0 is first register)
ReadHRparam(4)=500                                                                        ' read interval
modbus.invoke("PresetSingleRegister",ReadHRparam)               ' PRESET SINGLE REGISTER

dim WriteParam(2) as variant  
WriteParam(1)=1                   ' select internal array 1
WriteParam(2)=0                   ' place 0
'same as calling  Register(1,0)

modbus.Value("Register",WriteParam)=val(writeval.text)  'write value to array

dim param2(1) as variant
param2(1)=1 

modbus.Invoke("UpdateOnce", param2) 
modbus.Invoke("UpdateOnce", param2) ' <--- THIS PART HELPS TO GET THE DATA TO THE DEVICE

This code has been confirmed to work!