Sign in to follow this  
Followers 0
Datman

RSLinx DDE Comms Problem

43 posts in this topic

OK, plot thickens... I seem to be able to do all my OPC comms ok with the processor type set to SLC500 or 503, but in this instance the Ispresent or status tags will not work... ispresent tag will work when i change type to PLC-5. BUT then none of my other OPC comms will work, RSLINX appears to perform the write, but the data just does not get to the PLC... its driving me mad!! im going to resort to writing to a bit in the plc every loop, getting the plc to clear this bit, then read it back, if the bit didnt change between when i wrote it and read it then assume a comms error? grrr!!!

Share this post


Link to post
Share on other sites
When doing these block writes, im getting very weird stuff happen with my arrays in VB. this is my write block routine Public Sub OPC_Write_Block(index As Integer, value() As Integer) On Error GoTo errorhandler ' Write a block of items ItemCount = 1 ' Create some local scope variables to hold the value to be sent. ' These arrays could just as easily contain all of the item we have added. Dim SyncItemValues(1) As Variant Dim SyncItemServerHandles(1) As Long Dim SyncItemServerErrors() As Long ' Get the Servers handle for the desired item SyncItemServerHandles(1) = ItemServerHandles(index) ' Load the value to be written SyncItemValues(1) = CVar(value) ' Invoke the AsyncWrite operation. Remember this call will wait until completion ConnectedGroup.AsyncWrite ItemCount, SyncItemServerHandles, SyncItemValues, SyncItemServerErrors, 0, 0 Exit Sub This item has been defined as following: OPCItemIDs(22) = "[TEST_PLC]N14:0,L30,C30" 'Item22 = Block 1 PLC Run Information I have test code running below to write to the above item. i have an array of dimension 30. Now if i make the first value in the array a number above 18, or below 9 it will write the block of data fine. However if the first element in the array is between 9 and 18, i get garbage written down to the PLC. ie the first value in the block on the PLC is something like -2040. Alternatively, it seems if i write the LAST value in the array as a "1" and no other number, then everything else in the block will write correctly. Very weird and extremely fustrating, any ideas??? I dont know if you guys deal with VB much, or is it an issue with the DLL... maybe i have to stop being greedy and write to all my integers individually, and not as a block Dim temparray2(1 To 30) As Integer For i = 1 To 30 temparray2(i) = 0 Next i temparray2(1) = 18 Call frmOPC_Comms.OPC_Write_Block(22, temparray2)

Share this post


Link to post
Share on other sites
That explains it. One of the techs at AB said something about opening a second OPC connection and ONLY using it for checking the @IsPresent bit. That explains why he said not to use the channel for anything else (real data pulls). My PLC count is 1 CLX, 18 PLC-5's, 1 SLC 5/05, and 4 or 5 Micrologix (2 1500's, rest are 1100's). I don't normally do anything fancy with the SLC 5/05 and until recently I didn't bother doing anything much with the Micrologix. So that explains why I never saw the problems you are referring to.

Share this post


Link to post
Share on other sites
This is just an idea but I see a potential problem here. You are using arrays with user defined base index addresses instead of just the default. The base address for VB is normally 0. I'm not sure what the binary format of the array looks like when you define it this way and pass it over the COM/DCOM wire but it makes me nervous nonetheless because most OPC drivers are written in C which doesn't allow for user defined base index addresses and uses 0 as the base address. So the OPC driver could be thrown off by the funky array that is being passed to it, especially if the array comes across in some sort of "alternative" format that the OPC driver doesn't recognize or if the COM/DCOM wire format translation is doing something screwy with the data as it copies and translates the data from one COM object to another (although methinks it will just pass a memory reference in this case which is even worse!). Try this instead: dim temparray2(29) as Integer dim i as Integer for i = 0 to 29 temparray2(i) = 0 next i temparray2(0)=10 call frmOPC_Comms.OPC_Write_Block(22, temparray2)

Share this post


Link to post
Share on other sites
Are you using a Multi Dimension Array?? Unless I am missing something....? This address you are using is a length of 30 with a index of 30... OPCItemIDs(22) = "[TEST_PLC]N14:0,L30,C30" If you are only writing to a single array .. elements N14:0 to n14:29 then it should not be "C30" it SHOULD BE "C1".. like this... OPCItemIDs(22) = "[TEST_PLC]N14:0,L30,C1" This may be causing the strange results you are seeing. For reference I usually do my writes as follows. Note this is in VB.NET not sure what you are using, I also have in VB6 if you are using that. Public Sub SyncWrite() Dim ItemCount As Integer Dim i As Integer ' Get Number of Items in Group From Server ItemCount = LinxOPCGroup.OPCItems.Count ' Dim Arrays for SyncWrite Dim SyncServerHandles(ItemCount) As Integer Dim Values(ItemCount) As Object Dim WriteData(ItemCount) As Object Dim SyncErrors As System.Array = Nothing ' Write values 1 to 10 to N63:500 to N63:509 and N63:510 to N63:519 Dim WriteValues() As Short = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ' Copy Array Data to System Object WriteData(1) = WriteValues 'Data to First Item in Group -- [TopicName]N63:500,L10,C1 WriteData(2) = WriteValues 'Data to Second Item in Group -- [TopicName]N63:510,L10,C1 ' Pass in the ServerHandles and Values for the items active in Linx For i = 1 To ItemCount ' Pass in ServerHandles SyncServerHandles(i) = LinxOPCGroup.OPCItems.Item(i).ServerHandle ' Pass in ClientHandles Values(i) = WriteData(LinxOPCGroup.OPCItems.Item(i).ClientHandle) Next ' Write data to server LinxOPCGroup.SyncWrite(ItemCount, SyncServerHandles, Values, SyncErrors) End Sub Edited by TechJunki

Share this post


Link to post
Share on other sites
do you have an example using vb6? that is what im using. In reply to paulengr - I tried your suggest, same results

Share this post


Link to post
Share on other sites
For VB6...almost the same Public Sub SyncWrite() ' Dim Arrays for SyncWrite Dim SyncServerHandles() As Long Dim Values() As Variant Dim WriteData Dim SyncErrors() As Long Dim ItemCount As Integer Dim WriteValues() As Integer ' Get Number of Items in Group From Server ItemCount = LinxOPCGroup.OPCItems.Count ' Redim Arrays for Item Count ReDim SyncServerHandles(ItemCount) ReDim Values(ItemCount) ReDim WriteData(ItemCount) ' Write values 1 to 10 to N63:500 to N63:509 and N63:510 to N63:519 ReDim WriteValues(9) ' Fill with Data For i = 0 To 9 WriteValues(i) = i + 1 Next ' Copy Array Data WriteData(1) = WriteValues 'Data to First Item in Group -- [TopicName]N63:500,L10,C1 WriteData(2) = WriteValues 'Data to Second Item in Group -- [TopicName]N63:510,L10,C1 ' Pass in the ServerHandles and Values for the items active in Linx For i = 1 To ItemCount ' Pass in ServerHandles SyncServerHandles(i) = LinxOPCGroup.OPCItems.Item(i).ServerHandle ' Pass in ClientHandles Values(i) = WriteData(LinxOPCGroup.OPCItems.Item(i).ClientHandle) Next ' Write data to server LinxOPCGroup.SyncWrite ItemCount, SyncServerHandles, Values, SyncErrors End Sub Edited by TechJunki

Share this post


Link to post
Share on other sites
ok now i just tried that, exact same result. with the first value in the array to be written as a value 9, vb just crashes out... It must be something to do with my topic setup in rslinx...?? Im using 1msec polled message, using maximum ethernet packet size, and optimising poke packets. Are these wrong, or any other topic settings that should be set???

Share this post


Link to post
Share on other sites
I doubt it has anything to do with the setup in linx... Are you adding the items something like this....here is the rest of the code to add the items Edited by TechJunki

Share this post


Link to post
Share on other sites
yes exactly as that except i make the opc items directly, instead of passing the tagname from a variable string as you do with TagName. eg OPCItemIDs(1) = "[TopicName]N13:0,L10,C1"

Share this post


Link to post
Share on other sites
You could try posting or e-mailing your project file and I could take a look at it to see if it acts the same on my end. Not sure why it won't work correctly.

Share this post


Link to post
Share on other sites
easiest if i just post my code here. these are my declarations: Dim WithEvents AnOPCServer As OPCServer Dim WithEvents ConnectedOPCServer As OPCServer Dim ConnectedServerGroup As OPCGroups Dim WithEvents ConnectedGroup As OPCGroup Dim Groupname As String Dim OPCItemCollection As OPCItems Dim ItemCount As Long Dim OPCItemIDs() As String Dim ItemServerHandles() As Long Dim ItemServerErrors() As Long Dim ClientHandles() As Long Public Function OPC_Connect() 'Call OPC_Connect("BOARD_GRADER") Dim ConnectedServerName As String Dim ConnectedServerName2 As String Dim i As Integer Dim test As Variant 'Create a new OPC Server object Set ConnectedOPCServer = New OPCServer 'Load the selected server name to start the interface ConnectedServerName = "RSLinx OPC Server" 'Attempt to connect with the server (Local only) ConnectedOPCServer.Connect (ConnectedServerName) 'Prepare to add a group to the current OPC Server ' Get the group interface from the server object Set ConnectedServerGroup = ConnectedOPCServer.OPCGroups ' Set the desire active state for the group ConnectedServerGroup.DefaultGroupIsActive = True 'Set the desired percent deadband ConnectedServerGroup.DefaultGroupDeadband = 0 ' Add the group and set its update rate Groupname = "GRADER" Set ConnectedGroup = ConnectedServerGroup.Add(Groupname) ' Set the update rate for the group ConnectedGroup.UpdateRate = 500 ConnectedGroup.IsSubscribed = True 'create the items in the group ItemCount = 1 OPCItemIDs(1) = "[BOARD_GRADER]N13:0,L10,C1" 'Item1 = Primary PLC Control Word ClientHandles(1) = 1 Set OPCItemCollection = ConnectedGroup.OPCItems 'Gets an items collection from the current Group OPCItemCollection.DefaultIsActive = True 'Sets the items collection to active 'This line adds the items we’ve chosen to the items collection and in turn to the group in the OPC Server OPCItemCollection.AddItems ItemCount, OPCItemIDs, ClientHandles, ItemServerHandles, ItemServerErrors End Function this is my test function for performing the write. taken from your function above and modified slightly. if you increase the value that the array WriteValues is written as, (WriteValues(i) = i + 2) so that the first element is 9, you should see the error occur.. Public Sub TestWrite() ' Dim Arrays for SyncWrite Dim SyncServerHandles() As Long Dim Values() As Variant Dim WriteData Dim SyncErrors() As Long Dim ItemCount As Integer Dim WriteValues() As Integer Dim i As Long ' Get Number of Items in Group From Server ItemCount = ConnectedGroup.OPCItems.Count ItemCount = 1 ' Redim Arrays for Item Count ReDim SyncServerHandles(ItemCount) ReDim Values(ItemCount) ReDim WriteData(ItemCount) ' Write values 1 to 10 to N63:500 to N63:509 and N63:510 to N63:519 ReDim WriteValues(9) ' Fill with Data For i = 0 To 9 WriteValues(i) = i + 2 Next ' Copy Array Data WriteData(1) = WriteValues 'Data to First Item in Group -- [TopicName]N63:500,L10,C1 'WriteData(2) = WriteValues 'Data to Second Item in Group -- [TopicName]N63:510,L10,C1 ' Pass in the ServerHandles and Values for the items active in Linx For i = 1 To ItemCount ' Pass in ServerHandles SyncServerHandles(i) = ConnectedGroup.OPCItems.Item(i).ServerHandle ' Pass in ClientHandles Values(i) = WriteData(ConnectedGroup.OPCItems.Item(i).ClientHandle) Next ' Write data to server ConnectedGroup.SyncWrite ItemCount, SyncServerHandles, Values, SyncErrors End Sub Edited by Datman

Share this post


Link to post
Share on other sites
That is really strange, I was able to reproduce the problem, with a nine in the first element of the array it will "bomb" out VB6. I found that changing the Declaration datatype in the "Write" sub to a Variant seems to eliminate the problem. I tryed a few other datatypes all with out any success, either same thing or it just plain old didn't work. Must have something to do with how VB stores and sends the data in its memory. Anyway by changing the following line I have gotten this to work with a "9" as the first element of the array. let me know if you have the same result.. Dim WriteValues() As Integer --> Dim WriteValues() As Variant Edited by TechJunki

Share this post


Link to post
Share on other sites
you are right... whats even weirder, is i cant pass my array into this fucntion as an integer, then cast it as a variant by doing writevalues = cvar(temparray)... the array must be declared and passed into this function as variant... i suspect maybe something to do with the size, a variant is 16bytes, an integer 2 bytes? why we only see it with the value 9 is beyond me though... anyway, thanks very much for your help!!!

Share this post


Link to post
Share on other sites
Glad you got it working... Sometimes better not to question if it works...

Share this post


Link to post
Share on other sites
just one more question on this... is OPC slow to write? I have just a single write, which seems to take RSLinx 1 - 1.5seconds to write the data down to the PLC after the syncwrite call has finished. Is this normal? My updaterate in VB is set to something like 20, polled messages setting in RSLinx is set to 1msec. It is causing me some timing issue in my program, can i expect any faster?

Share this post


Link to post
Share on other sites
also whats the difference between asyncwrite and syncwrite, same with the read??

Share this post


Link to post
Share on other sites
Not 100% sure with this, but Async can happen at any time, but Sync happens immediately after the call.

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  
Followers 0