Jump to content
Sign in to follow this  
RichardL

OPC want to use OPCGroup.SyncWrite

Recommended Posts

RichardL

I’m writing values to other equipment via OPC and modbus. I’ve lifted the example from and it works well including the Item.Write. Now I’d like to use OPCGroup.SyncWrite because with .Write the modbus server does individual writes and it's too slow.

I have example in VB from http://forums.mrplc.com/index.php?showtopic=12381

OPCGroup1.SyncWrite NumItems, ServerHandles(), Values(), Errors() 'Perform OPC Write

My attempt in AutoIt:

ReDim $OPCErrs[$iOPCNofItms]
For $iItmIx = 0 To $iOPCNofItms - 1
ConFmtWr("%2d ~%s~ ~%s~ ~%s~\n", $iItmIx, $OPCItmHnds[$iItmIx], $sOPCValues[$iItmIx], $OPCErrs[$iItmIx])
Next

$iOPCNofItms = 1
$OPCGroup1.SyncWrite($iOPCNofItms, $OPCItmHnds, $sOPCValues, $OPCErrs) ; OPC Write

Output:

0 ~24986912~ ~1.100000~ ~~
1 ~24987056~ ~1.100000~ ~~
2 ~24987200~ ~1.100000~ ~~
3 ~24987344~ ~1.100000~ ~~
(178) : ==> The requested action with this object has failed.:
$OPCGroup1.SyncWrite($iOPCNofItms, $OPCItmHnds, $sOPCValues, $OPCErrs)
$OPCGroup1.SyncWrite($iOPCNofItms, $OPCItmHnds, $sOPCValues, $OPCErrs)^ ERROR

I think the group object is right (when I used the ID it said 'not an object'), item handles and values seem right. What could be wrong? Are the format of AutoIt arrays correct for passing to other languages?

Thanks.

Share this post


Link to post
Share on other sites
water

Add a COM error handler to your script and you will get more information about what happens. Check ObjEvent in the Help File.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
RichardL

Thanks (and I needed to learn about error handling anyway).

err.number is : -2147352571
err.windescription : Type mismatch.

err.description is :
err.source is :
err.helpfile is :
err.helpcontext is : 0
err.lastdllerror is: 0
err.scriptline is : 196
err.retcode is : 0

Confirms what I suspected, that the parameters are not the right format. But which one(s) and what to try. I guess we don't want AutoIt variant format, so convert to data-bytes-only? with Binary?

Share this post


Link to post
Share on other sites
water

Is there a docu for OPC automation describing the format of the parameters?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
water

According to the docu "Error" is accessed ByRef. Which means it has to be declared in advance. How did you declare $OPCErrs?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
RichardL

Func OPCWriteTags_02($sOPCValues)

Local $OPCItem
Local $iItmIx

Local $OPCErrs[1]
Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

ReDim $OPCErrs[$iOPCNofItms]
For $iItmIx = 0 To $iOPCNofItms - 1
ConFmtWr("%2d ~%s~ ~%s~ ~%s~\n", $iItmIx, $OPCItmHnds[$iItmIx], $sOPCValues[$iItmIx], $OPCErrs[$iItmIx])
Next

$OPCGroup1.SyncWrite($iOPCNofItms, $OPCItmHnds, $sOPCValues, $OPCErrs) ; OPC Write
EndFunc

$iOPCNumItems is a global, set to 4 during OPCInit (horrible I know, but I'll tidy-up after it's working).

Share this post


Link to post
Share on other sites
RichardL

I tried the call with only the first parameter, $iOPCNofItms, and it said "Invalid number of parameters." So I think that means it checks each parameter as it goes along, and it's happy with $iOPCNofItms.

So I gave it the first two parameters, and it said "Type mismatch." so I think it doesn't like $OPCItmHnds. What type is that? and what does it want?

ReDim $OPCErrs[$iOPCNofItms]

For $iItmIx = 0 To $iOPCNofItms - 1
$OPCErrs[$iItmIx] = Number(0, 1)
$OPCItmHnds[$iItmIx] = Number($OPCItmHnds[$iItmIx], 1)
ConFmtWr("%2d ~%s~ ~%s~ ~%s~\n", $iItmIx, $OPCItmHnds[$iItmIx], $sOPCValues[$iItmIx], $OPCErrs[$iItmIx])
Next

ConFmtWr("T N %s\n", VarGetType($iOPCNofItms))
ConFmtWr("T H %s\n", VarGetType($OPCItmHnds[0]))
ConFmtWr("T V %s\n", VarGetType($sOPCValues[0]))
ConFmtWr("T E %s\n", VarGetType($OPCErrs[0]))

$OPCGroup1.SyncWrite($iOPCNofItms, $OPCItmHnds); , $sOPCValues) ; , $OPCErrs) ; OPC Write

Output:

0 ~24921352~ ~0.13~ ~0~
1 ~24921496~ ~4.31~ ~0~
T N Int32
T H Int32
T V Double
T E Int32
err.number : -2147352571
err.windescription: Type mismatch.

I built and ran the VB example, and printed vartype(serverhandles(1)) which is 3, which is 'Long integer', which is 32-bit, and the same as AutoIt's Int32? So what's wrong? I hope we can fix this, or I'm going to have to do something awful, like passing the numbers to a VB thing that sends them to OPC.

Share this post


Link to post
Share on other sites
water

$OPCItmHnds seems to be an array of server handles. How to fill this array with server handles? I don't know. The example isn't clear about that too.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
RichardL

The ServerHandles come from

For $OPCItem In $OPCItems
$sh = $OPCItem.ServerHandle
ConFmtWr(" %s %s\n", "SH = ", $sh)
$OPCItmHnds[$iItmIx] = $sh
$iItmIx += 1
Next

and I've used one in a single write using that as the reference. As well as that, just before the SyncWrite I used zero for all the handles. It still failed on 'type mismatch' so I don't thing it has gone as far as looking at the values of the handles.

Share this post


Link to post
Share on other sites
water

Sorry, I have run out of ideas :think:


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
trancexx

You can't have array of integers (Longs) in AutoIt. You can have Array of Variants and array of Bytes.

Still, it can be argued that interface you are trying to use doesn't follow Automation guidelines regarding type coercion for input data. It would be reasonable to expect that if you pass array of Variants, the API would accept it and coerce internally to array of Longs, instead giving the error.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
RichardL

Thanks for your help and comments, I've learned a few things. To go around the problem I've put some VB in an ActiveX on the AutoIt GUI. I'll keep the AutoIt + OPC.SyncWrite program ready to test any new ideas.

Thanks again.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×