Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

C# Calling external ActiveX method - array parameter wrong type

Posted on 2012-03-20
8
Medium Priority
?
1,624 Views
Last Modified: 2012-08-22
Good day,

I am building a C# application that writes values to a Siemens PLC.
Using the Siemens' ActiveX control and are following their example of VB.NET code but I get the following error:
"Specified array was not of the expected type".

This is my C# code:
        private const string PROG_ID = "OPC.SimaticNet.1";
        private OPCSiemensDAAutomation.OPCServer opcServer;
        private OPCSiemensDAAutomation.OPCGroup opcGroup;
        private OPCSiemensDAAutomation.OPCItem[] opcItems = new OPCSiemensDAAutomation.OPCItem[1];

        public frmMain()
        {
            InitializeComponent();
            connectOPCServer();
        }

        private void connectOPCServer() 
        {
            try
            {
                opcServer = new OPCSiemensDAAutomation.OPCServer();
                opcServer.Connect(PROG_ID);

                opcGroup = opcServer.OPCGroups.Add("Gruppe1");
                opcGroup.IsSubscribed = true;
                opcGroup.UpdateRate = 500;

                opcItems[0] = opcGroup.OPCItems.AddItem("S7:[S7 connection_1]DB700, STRING8.50", 1);
            }
            catch(Exception ex)
            {
                MessageBox.Show("Exception: " + ex.Message);
            }
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            try
            {
                var lstHandles = new List<long>();
                lstHandles.Add(opcItems[0].ServerHandle);
                Array arrHandles = lstHandles.ToArray();

                var lstValues = new List<string>();
                lstValues.Add("Toets");
                Array arrValues = lstValues.ToArray();

                //var lstErrors = new List<int>();
                //Array arrErrors = lstErrors.ToArray();
                Array arrErrors = new List<long>().ToArray();

                MessageBox.Show("Value: " + arrValues.GetValue(0).ToString());

                opcGroup.SyncWrite(1, ref arrHandles, ref arrValues, out arrErrors);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Exception: " + ex.Message);
            }
        }

Open in new window


I understand or believe that my array parameter parsing to the method is of wrong type but I can not see which one as I am using identical types to their VB.NET example which is working.


This is a snipped from the Siemens documentation and also the VB example:

7.4.2.2 SyncWrite
Description
This method writes values for one or more items of a group. The function is executed
completely. The values are written to DEVICE; this means that the function should not be
returned until it is certain that the device has accepted the data (or rejected the data).
Syntax
SyncWrite (NumItems As Long,
ServerHandles() As Long,
Values() As Variant,
ByRef Errors() As Long)
NumItems
NumItems specifies the number of items to be written.
ServerHandles
ServerHandles is an array of server handles for the items to be written.
Reference Automation Interface
7.4 The OPCGroup object
Industrial Communication with PG/PC Volume 2 - Interfaces
722 Programming Manual, Release 06/2011, C79000-G8976-C197-10
Values
Values is an array of values.
Errors
Errors is an array of long values that specify whether the items were written successfully.
Remarks
The status of the group or item (active/inactive) has no influence on the write method.
Example
Private Sub WriteButton_Click()
Dim Source As Integer
Dim NumItems As Long
Dim ServerIndex As Long
Dim ServerHandles() As Long
Dim Values() As Variant
Dim Errors() As Long
NumItems = 10
For ServerIndex = 1 to NumItems
' specifies which item will be written
ServerHandles(ServerIndex) = AnOPCItemServerHandles(ServerIndex)
Values(ServerIndex) = ServerIndex * 2
' the value of the item can be any value here
Next ServerIndex
OneGroup.SyncWrite NumItems, ServerHandles, Values, Errors
For ServerIndex = 1 to NumItems
' processes the errors
TextBox(ServerIndex).Text = Errors(ServerIndex)
Next ServerIndex
End Sub

Open in new window


Please assist, thanks all :)
0
Comment
Question by:Marius0188
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
8 Comments
 

Author Comment

by:Marius0188
ID: 37740989
I might add:
The error I received is when writing the value when calling sycnwrite() method.

:)
0
 

Author Comment

by:Marius0188
ID: 37741001
And this is a working VB script example as provided by Siemens:

Private Sub cmdWrite_Click()

    Dim SHandles(2) As Long  'parameter value
    Dim Values(2) As Variant 'parameter value
    Dim Errors() As Long     'return value
    Dim i As Integer

        
    'save ServerHandles
    SHandles(1) = MyOPCItems(3).ServerHandle
    SHandles(2) = MyOPCItems(4).ServerHandle
    
    'find out the values which are written into the following cells (line 11+12, column F)
    'this values should be writen into PLC
    
    For i = 1 To 2
          Values(i) = Cells(10 + i, 6)
          If Values(i) = "" Then Values(i) = 0
    Next i
    
    Call MyOPCGroup.SyncWrite(2, SHandles, Values, Errors)
    
End Sub

Open in new window


Could it be C# does not support Variant types?
What is the work around?

I have tried declaring my Values list<object> but still complaining about wrong array type for parameter.

Please help :)
0
 
LVL 42

Expert Comment

by:Meir Rivkin
ID: 37741167
where in the C# code the error triggered?
which line?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:Marius0188
ID: 37741375
Okay I got the code to run without errors but the value that gets write doenst get updated on the PLC (see bold)

Code that fix the error:
var lstHandles = new List<int>();
                lstHandles.Add(opcItems[0].ServerHandle);
                Array arrHandles = lstHandles.ToArray();

                var lstValues = new List<object>();
                lstValues.Add("Toets");
                Array arrValues = lstValues.ToArray();
0
 

Author Comment

by:Marius0188
ID: 37741381
The documentation is so misleading as they define different types for example: LongInt whereas it should be Int...

Okay next issue is.
Would it be a problem because the working VB script (Excel sheet) that does update the value on PLC uses Option Base 1 iow: all arrays start at ONE (1).

Whereas in C# the arrays are zero based index.
How can I mimic the same in C# if this could be the problem.

Any other suggestions as to what could be causing the problem are welcome :)
0
 
LVL 42

Expert Comment

by:Meir Rivkin
ID: 37741398
i didn't understand what is the problem now that u overcome the type error.
i don't see a problem in regards to zero based arrays.
i'll just try with a single entry array and see how's it runs.
0
 

Accepted Solution

by:
Marius0188 earned 0 total points
ID: 37741417
Okay for future reference only.
I solved the issue myself.

Maybe not clean but it works.
I simply filled the first two indexes of the array with same value and make the PLC believe I am only sending one value (element) array.

Array[0] = "SameValue" -> This will not be read
Array[1] = "SameValue" -> but this index will be read.

As I am always sending only one value in my array this will work for now.

Will leave this open for day or two for some better cleaner solutions.

Thanks...
0
 

Author Closing Comment

by:Marius0188
ID: 38319620
No other real solution that exactly solved my problem :)
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

609 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question