Results 1 to 19 of 19

Thread: [RESOLVED] OPC-UA client for VB6?

  1. #1

    Thread Starter
    Member
    Join Date
    Oct 2020
    Posts
    53

    Resolved [RESOLVED] OPC-UA client for VB6?

    Hello, I don't know if anyone here is familiar with OPC, I'm looking for how to build an OPC UA client from vb6. If there is anyone with experience in this, your contribution is greatly appreciated, since I need to acquire values ​​from a SCADA software that uses this protocol and for the rest it is very hermetic, since I have tried all kinds of techniques to acquire its data and it is very protected Or it requires a lot of effort.

    Use a QuickOPC SDK that works, but is only a short demo.

    Name:  Sin título.jpg
Views: 756
Size:  21.0 KB

    Thank you so much!

  2. #2
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,552

    Re: OPC-UA client for VB6?

    That seems awfully specific... if you already have an SDK, there should be examples on how to use it though. I've found that when VB samples aren't available, C/C++ is the most easily translated to VB (ironically, far easier than VB.NET).

  3. #3
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: OPC-UA client for VB6?

    Quote Originally Posted by fafalone View Post
    (ironically, far easier than VB.NET).
    Errr...Not really. I wrote quite a few things that was translated from C/C++ code to VB.Net. I found them less problematic. There are more direct translations of C/C++ idioms in VB.Net than there are in VB6. VB6 requires you to be more clever. Unsigned types and delegates are simple examples that come to mind.

    I understand where you're coming from though. If you're not familiar with the .Net platform coming from VB6, it will be a frustrating experience.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  4. #4
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,552

    Re: OPC-UA client for VB6?

    Not really? I don't know what code you're looking at, but everything in VB.NET revolves around .NET framework calls that can't be ported at all or only with great difficulty. Maybe you're talking about pure code, but this subject here is APIs.

  5. #5
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: OPC-UA client for VB6?

    Quote Originally Posted by fafalone View Post
    but everything in VB.NET revolves around .NET framework calls that can't be ported at all or only with great difficulty.
    Oh you mean porting from .Net to VB6? If so, I agree. There are things that are not directly translatable and would require one to roll up their sleeves.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  6. #6
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,552

    Re: OPC-UA client for VB6?

    Yeah I was saying if you have examples for a COM-based or flat API, and there's no VB examples of using it, c++ examples would be more analogous and easier to port to vb6 than VB.nyet.

  7. #7
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: OPC-UA client for VB6?

    Quote Originally Posted by fafalone View Post
    Yeah I was saying if you have examples for a COM-based or flat API, and there's no VB examples of using it, c++ examples would be more analogous and easier to port to vb6 than VB.nyet.
    Hmmmm....I'd say its both yes and no.

    Yes because VB6 uses a lot of the same "default conventions" as C, for example they align structures the same way by default. A lot of translations would be straightforward because of this.

    No because when you run into unions, packed structures, structures passed by value, unsigned types, cdecl functions, these require you to be a little more clever in VB6. .Net handles all of these without any cleverness.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  8. #8
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,629

    Re: OPC-UA client for VB6?

    Truth be told, I agree with Fafalone on this one (in a general sense).

    I've ported far more C/C++ code to VB6 than I've ported .NET code to VB6. Part of that is because I deal with MOCAP issues quite a bit, and there's a prevalence of C/C++ code dealing with this. But, when I find .NET code that does what I want, I often keep searching to see if I can find the answer in a C/C++ format.

    However, I will agree that it does depend on the complexities in the code, and both C/C++ as well as .NET can employ complexities that are difficult to deal with in VB6. But, and this is a generalization, C/C++ programmers do seem to understand the KISS principle better than .NET programmers, so even this complexity (or simplicity) issue tends to favor C/C++.
    Last edited by Elroy; May 10th, 2023 at 11:12 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  9. #9
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: OPC-UA client for VB6?

    Oh wait. It seems I got confused. Porting to VB6 from C/C++ is much easier than porting from .Net. Yes this is 100% true. I thought we were talking about consuming a C/C++/COM based API from VB6 as opposed to consuming them from VB.Net. My apologies for misunderstanding.

    Yes, VB.Net code relies heavily on the Framework which isn't directly translatable to VB6 for the majority of stuff.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  10. #10
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,552

    Re: OPC-UA client for VB6?

    Quote Originally Posted by Niya View Post
    Hmmmm....I'd say its both yes and no.

    Yes because VB6 uses a lot of the same "default conventions" as C, for example they align structures the same way by default. A lot of translations would be straightforward because of this.

    No because when you run into unions, packed structures, structures passed by value, unsigned types, cdecl functions, these require you to be a little more clever in VB6. .Net handles all of these without any cleverness.
    Now that twinBASIC is getting close to being ready for prime time... it supports alternative packing and cdecl already (though VB6 does the latter too with The trick's patch for it), unsigned types are planned, ByVal UDTs and unions are a strong likelihood, based on responses to feature requests for them.

    I've long believed that one of the primary reasons for VB6's longevity is it pairs simplicity and high level capabilities with low level capabilities like nothing else out there like that. So beginners have a direct path to the more advanced stuff without learning a new language, and can easily consume code from very advanced programmers. And for advanced users, it lets you do all the simple stuff for RAD/GUIs without the complexity, while still offering incredible access to go as low as you need to, even right down to asm.

  11. #11
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: OPC-UA client for VB6?

    Quote Originally Posted by fafalone View Post
    Now that twinBASIC is getting close to being ready for prime time... it supports alternative packing and cdecl already (though VB6 does the latter too with The trick's patch for it), unsigned types are planned, ByVal UDTs and unions are a strong likelihood, based on responses to feature requests for them.
    And when TwinBASIC is finally mature and you guys get used to it, you're going to find it hard to go back. This is what happened to me when I touched .Net for the first time. I got used to the new stuff. It was painful to go back to not having them so readily accessible.

    Though in TwinBASIC's case, there would be no reason to go back anyway because it will be 99.99999% compatible with VB6.

    Quote Originally Posted by fafalone View Post
    I've long believed that one of the primary reasons for VB6's longevity is it pairs simplicity and high level capabilities with low level capabilities like nothing else out there like that. So beginners have a direct path to the more advanced stuff without learning a new language, and can easily consume code from very advanced programmers. And for advanced users, it lets you do all the simple stuff for RAD/GUIs without the complexity, while still offering incredible access to go as low as you need to, even right down to asm.
    I'd say it's more because of RAD than it's lower level capabilities. To this day, people still can't stop "fan-boying" over VB6/WinForms drag and drop paradigm. Even me for as much as I champion HTML-like paradigms like WPF, I still default to WinForms when I need to put together something super-fast. You just can't beat it for rapid development. No one has yet come up with a faster way to create simple UIs.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  12. #12
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,552

    Re: OPC-UA client for VB6?

    The low level capabilities are what lets people drop in powerful code from advanced users, so they're not limited to just a form designer with a toy language. Would the form design really be enough if the capability ceiling was too low?

  13. #13

    Thread Starter
    Member
    Join Date
    Oct 2020
    Posts
    53

    Re: OPC-UA client for VB6?

    I managed to find a library for VBA, now when trying to implement it in vb6 I get the following error.

    Name:  EJM1.jpg
Views: 636
Size:  27.1 KB

    Name:  EJM2.jpg
Views: 682
Size:  27.7 KB

    Name:  EJM4.jpg
Views: 665
Size:  15.8 KB

    Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic

    Name:  EJM3.jpg
Views: 674
Size:  30.7 KB

    Is there a way to patch this? any trick? I wouldn't like the need to control excel through vb6 and return the data, hopefully this is straightforward.


    Library

    Thanks!
    Last edited by Maatooh; May 11th, 2023 at 04:41 PM.

  14. #14
    New Member
    Join Date
    Nov 2022
    Posts
    5

    Re: OPC-UA client for VB6?

    Quote Originally Posted by Maatooh View Post
    I managed to find a library for VBA, now when trying to implement it in vb6 I get the following error.

    Name:  EJM1.jpg
Views: 636
Size:  27.1 KB

    Name:  EJM2.jpg
Views: 682
Size:  27.7 KB

    Name:  EJM4.jpg
Views: 665
Size:  15.8 KB

    Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic

    Name:  EJM3.jpg
Views: 674
Size:  30.7 KB

    Is there a way to patch this? any trick? I wouldn't like the need to control excel through vb6 and return the data, hopefully this is straightforward.


    Library

    Thanks!

    The ReadValues and WriteValues require a String() Array as an argument which I don't think VB6 allows, hence the error message.

    I have patched the Opc.Ua.ExcelClient.dll to add ReadValue and WriteValue which use String as their arguments.
    This seams to work ok with VB6.
    (register it as Opc.Ua.ExcelClioent.tlb as per the Siemens and program comment instructions)

    But it is work in progress...
    I need to build a NodeID explorer for the opc. URL's NodeIDItems.

    VB6 Code is here: -

    Name:  VB6 OPC UA Siemens S7-1200 S7-1500.jpg
Views: 416
Size:  32.4 KB

    Code:
    ' Based on Siemens, Excel OPC-UA Example
    ' See, https://support.industry.siemens.com/cs/document/109748892/opc-ua-client-library-for-microsoft-excel
    '
    ' Project, References, Browse, "Opc.Ua.ExcelClient.tlb"
    ' Select "Opc.Ua.ExcelClient.tlb" = OpcUaClient
    '
    ' Use OPC Expert to Browse for S7-1200, S7-1500 Name Spaces
    ' https://opcexpert.com/
    '
    ' Also see, https://www.youtube.com/watch?v=5JB2mVu_Jbk
    '
    ' C:\109748892_OPC_UA_ClientLibrary_CODE_V2_1\OPC_UA_ExcelClient\Application\Opc.Ua.ExcelClient.tlb
    '
    ' cmd in Admin Mode...
    '
    ' 32 bit, System32
    ' C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm C:\109748892_OPC_UA_ClientLibrary_CODE_V2_1\OPC_UA_ExcelClient\Application\Opc.Ua.ExcelClient.dll /tlb /codebase
    '
    ' 64 bit, SysWOW64
    ' C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe C:\109748892_OPC_UA_ClientLibrary_CODE_V2_1\OPC_UA_ExcelClient\Application\Opc.Ua.ExcelClient.dll /tlb /codebase
    '
    Option Explicit
    ' Reference to .dll and .tlb
    Public WithEvents MyOpcUaClient As OpcUaClient
    ' Get Endpoints of OPC UA Server
    Dim EndPoints() As OpcUaEndpoint
    Private Sub Form_Load()
        ' Who, What, Where, When.
        Me.Caption = "OPC UA - Using Siemens Driver, Opc.Ua.ExcelClient.tlb - v1.0 - 2nd Nov 2023"
    End Sub
    Private Sub cmdGetEndPoints_Click()
        ' Create OPC UA Client Instance
        Set MyOpcUaClient = New OpcUaClient
        ' Get End Points from OPC Connection URL
    '   EndPoints = MyOpcUaClient.GetEndpoints("opc.tcp://192.168.0.250")
        EndPoints = MyOpcUaClient.GetEndpoints(txtOPCURL)
        ' Fill List Box
        Dim i As Integer
        ' Add all Returned End Points to List
        For i = 0 To UBound(EndPoints)
            ' Add to List
            lstEndPoints.AddItem EndPoints(i).SecurityPolicyUri
        Next
    End Sub
    Private Sub lstEndPoints_Click()
        ' Connect to End Point
        If MyOpcUaClient.Connect(EndPoints(lstEndPoints.ListIndex), False, "", "") Then
            ' Good
            MsgBox "Connected OK to - " & lstEndPoints.List(lstEndPoints.ListIndex), vbOK
            ' Enable Read/Write
            cmdRead.Enabled = True
            cmdWrite.Enabled = True
        Else
            ' Bad
            MsgBox "Connection Refused to - " & lstEndPoints.List(lstEndPoints.ListIndex), vbCritical
            ' Disable Read/Write
            cmdRead.Enabled = False
            cmdWrite.Enabled = False
        End If
    End Sub
    Private Sub cmdRead_Click()
        ' Read Single Value, VB6 Can't Call String Arrays
        txtReadData = MyOpcUaClient.ReadValue(txtNameSpace)
    End Sub
    Private Sub cmdWrite_Click()
        ' Write Single Value, VB6 Can't Call String Arrays
        Call MyOpcUaClient.WriteValue(txtWriteData, txtNameSpace)
        ' Re Read Data
        cmdRead_Click
    End Sub
    Private Sub cmdDisconnect_Click()
        On Error Resume Next
        ' Disconnect
        MyOpcUaClient.Disconnect
        ' Destroy
        Set MyOpcUaClient = Nothing
        ' Disable Read/Write
        cmdRead.Enabled = False
        cmdWrite.Enabled = False
        ' Clear End Points List
        lstEndPoints.Clear
        ' Error Off
        On Error GoTo 0
    End Sub

    .net modifications to Siemens OPC_UA_ExcelClient.sln is here


    Code:
      /// <summary>
      /// DR, 4th Nov 2023
      /// reads a value.
      /// Uses UAClientHelperAPI
      /// </summary>
      /// <param name="nodeIdString">Array of NodeId as string</param>
      /// <returns>Array of values as string</returns>
      public String ReadValue(String nodeIdString)
      {
          //prepare list of nodeID
          List<String> list = new List<string>();
    
          // Only One Valus
          list.Clear();
          list.Add(nodeIdString);
    
          //read
          String[] Str = m_UAClientHelperAPI.ReadValues(list).ToArray();
    
          // Return
          return(Str[0]);
      }
    
      /// <summary>
      /// reads values.
      /// Uses UAClientHelperAPI
      /// </summary>
      /// <param name="nodeIdStrings">Array of NodeId as string</param>
      /// <returns>Array of values as string</returns>
      public String[] ReadValues(String[] nodeIdStrings)
      {
          //prepare list of nodeID
          List<String> list = new List<string>();
    
          list.AddRange(nodeIdStrings);
    
          //read
          return m_UAClientHelperAPI.ReadValues(list).ToArray();
      }
    
      /// <summary>
      /// DR, 4th Nov 2023
      /// write a value.
      /// Uses UAClientHelperAPI
      /// </summary>
      /// <param name="value">Value as string</param>
      /// <param name="nodeIdString">NodeId as string</param>
      public void WriteValue(String value, String nodeIdString)
      {
          //prepare list of nodeID
          List<String> listValues = new List<string>();
          listValues.Clear(); 
          listValues.Add(value);
    
          //prepare list of values
          List<String> list = new List<string>();
          list.Clear();
          list.Add(nodeIdString);
    
          //write
          m_UAClientHelperAPI.WriteValues(listValues, list);
      }
    
      /// <summary>
      /// writes values.
      /// Uses UAClientHelperAPI
      /// </summary>
      /// <param name="values">Array of values as string</param>
      /// <param name="nodeIdStrings">Array of NodeId as string</param>
      public void WriteValues(String[] values, String[] nodeIdStrings)
      {
          //prepare list of nodeID
          List<String> listValues = new List<string>();
          listValues.AddRange(values);
    
          //prepare list of values
          List<String> list = new List<string>();
          list.AddRange(nodeIdStrings);
    
          //write
          m_UAClientHelperAPI.WriteValues(listValues, list);
      }

    Name:  OPC_UA_ExcelClient.sln.jpg
Views: 408
Size:  20.1 KB

    Files,
    Attached Files Attached Files
    Last edited by daleread; Dec 5th, 2023 at 12:06 PM.

  15. #15
    New Member
    Join Date
    Nov 2023
    Location
    no
    Posts
    7

    Re: [RESOLVED] OPC-UA client for VB6?

    this is pretty radical

  16. #16
    New Member
    Join Date
    Nov 2022
    Posts
    5

    Re: [RESOLVED] OPC-UA client for VB6?

    Quote Originally Posted by Vblover29 View Post
    this is pretty radical
    I have done a bit more work on the program and now have it communication with a Siemens S7-1200 PLC using Winsock and just VB.

    Just now it communicates the the PLC, opens up a OPC UA, "Hello" HEL and "Open" OPN link over the Ethernet and gets the security credentials.

    It the uses the OPC UA "MSG" to get the Endpoints.

    The end points are just displayed on the form just now, I am working to put them into the correct structure and display them on a tree format.

    The program contains the structure for the OPC UA, but they need refining and testing.

    Next step is to establish an endpoint connection and move data across.

    The project is far from finished but I thought I would give you a heads up, and, somebody might pick up from here and get it done.

    Name:  OPC UA - v0.2.jpg
Views: 289
Size:  38.7 KB

    Code is attached,
    Native OPC UA - v0.2.zip

  17. #17
    New Member
    Join Date
    Nov 2022
    Posts
    5

    Re: [RESOLVED] OPC-UA client for VB6?

    The program is now communicating with a S7-1200 PLC at security level 0 using Winsock control

    The OPC UA, functions:
    GetEndPoints, OpenSecureChannel, ActiveSessionRequest, and ReadData, have been added.

    The OPC UA Security:
    SecurityId and IdentifierNumeric , have been implemented.

    The read command uses NameSpaces to point to the PLC DataBlocks and Marker bits.
    Use 'OPC Expert' to browse for the NameSpaces on your own PLC.

    I will add the tree structures for the EndPoints, SecurityCertificates and NodeIds.

    Name:  ScreenShot1.jpg
Views: 262
Size:  36.1 KB

    Name:  ScreenShot2.jpg
Views: 261
Size:  43.8 KB

    Name:  ScreenShot3.jpg
Views: 265
Size:  23.5 KB

    OPC UA Expert Screen Shot

    Code is Here > Winsock OPC UA - v0.5.zip
    Last edited by daleread; Dec 5th, 2023 at 12:15 PM.

  18. #18
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,046

    Re: [RESOLVED] OPC-UA client for VB6?

    This codebase is quickly spinning out of control while the total size is miniscule 1315 LOC as of last post.

    Please, don't couple everything with your master form in the UI. Using frmMain.Control.Method/Property throughout the code is the worst pattern possible, a sure sign of spaghetti code imminent in near future.

    Generally try to keep OPC library code as much encapsulated as possible i.e. each procedure should accept input parameters and either return result or modify local module state only.

    Try to think what would someone else use out of your parsing code if their UI is completely different i.e. no frmMain, no Winsock control, etc.

    cheers,
    </wqw>

  19. #19
    New Member
    Join Date
    Nov 2022
    Posts
    5

    Re: [RESOLVED] OPC-UA client for VB6?

    Quote Originally Posted by wqweto View Post
    This codebase is quickly spinning out of control while the total size is miniscule 1315 LOC as of last post.

    Please, don't couple everything with your master form in the UI. Using frmMain.Control.Method/Property throughout the code is the worst pattern possible, a sure sign of spaghetti code imminent in near future.

    Generally try to keep OPC library code as much encapsulated as possible i.e. each procedure should accept input parameters and either return result or modify local module state only.

    Try to think what would someone else use out of your parsing code if their UI is completely different i.e. no frmMain, no Winsock control, etc.

    cheers,
    </wqw>
    The next step in the development is attached below.

    The code has been cleaned up, the basic read and write methods now work and the first steps in building a tree structure for OPC-UA has started.

    The opcUaClient interface now looks like this;

    Code:
    ' See https://reference.opcfoundation.org/Core/Part6/v104/docs/7.1.2
    Option Explicit
    ' Ethernet Rx Data
    Public WinsockRx As String
    ' Transmit Message Type
    Public txMessageType As String
    ' Tx Message Sequence Number
    Public SequenceNumber As Double
    ' Automation
    Public Function SetUrl(strUrl As String)
        ' Save Url
        OpcUaCore.sUrl = strUrl
        ' Connect to Ethernet
        ReConnect
    End Function
    Public Function ReConnect() As Boolean
        ' Test for Connection
        If OpcUaClient.Winsock1.State <> 7 Then Winsock1.Close
        ' Connect
        Winsock1.Connect OpcUaCore.sUrl, 4840
        ' Check Connection
        Do While Winsock1.State <> 7: DoEvents: Loop
    End Function
    Public Function SendData(Data As String)
        ' Send Winsock Data
        If Winsock1.State <> 7 Then ReConnect
        ' Send Data
        Winsock1.SendData Data
    End Function
    Public Function State() As Integer
        ' Get Winsock Connection State
        State = Winsock1.State
    End Function
    Public Function Hello()
        ' OPCUA Hello
        OpcUaCore.HEL OpcUaCore.sUrl
    End Function
    Public Function OpenConnection() As String
        ' OPCUA Open
        OpcUaCore.OPN
        ' Return Security Id
        OpenConnection = OpcUaCore.GetSecurityId
    End Function
    Public Function GetSecurityId() As String
        ' Return Security Id
        GetSecurityId = OpcUaCore.GetSecurityId
    End Function
    Public Function GetEndPoints() As String()
        ' Send HEL EndPointsRequest
        Hello
        ' Wait for ACK
        DelaymS 50
        ' Send OPN Secure Channel
        OpenConnection
        ' Wait for OPN SecureChannelResponse
        DelaymS 50
        ' Send OPC UA Message, MSG GetEndPoints
        OpcUaMessage.MSGGetEndPoints OpcUaCore.sUrl
        ' Wait for MSG EndPointsResponse
        DelaymS 50
        ' Decode End Point Rx Data
        OpcUaMessage.DecodeMSGGetEndPoints
        ' Return Security Policy Urls
        GetEndPoints = OpcUaMessage.SecurityPolicyUrls
    End Function
    Public Function GetSecurityPolicyUrls() As String()
        ' Get Security Policy Urls from MSG
        GetSecurityPolicyUrls = OpcUaMessage.SecurityPolicyUrls
    End Function
    Public Function GetIdentifierNumeric() As String
        ' Get Security Key
        GetIdentifierNumeric = OpcUaMessage.GetIdentifierNumeric
    End Function
    Public Function GetActiveSession() As String
        ' Get Active Session Status
        GetActiveSession = OpcUaMessage.GetActiveSession
    End Function
    Public Function OpenSecureChannel(ConnectionId As Integer) As String
        ' Clear RxBuffer
        OpcUaClient.WinsockRx = ""
        ' Open Connection
        OpcUaMessage.MSGOpenSecureChannel ConnectionId
        ' and Wait for a connection....
        DelaymS 1000
        ' Decode End Point Rx Data
        OpenSecureChannel = OpcUaMessage.DecodeMSGOpenSecureChannel
    End Function
    Public Function ActiveSessionRequest(ConnectionId As Integer) As String
        ' Clear Rx Buffer
        OpcUaClient.WinsockRx = ""
        ' Active Session Request
        OpcUaMessage.MSGActiveSessionRequest ConnectionId
        ' Wait for Reply
        DelaymS 100
        ' Good Connection
        ActiveSessionRequest = OpcUaMessage.DecodeMSGActiveSessionRequest
    End Function
    Public Function ReadValue(ns As String, i As String) As String
        ' Clear Rx Buffer
        OpcUaClient.WinsockRx = ""
        ' Read From PLC
        ReadValue = OpcUaMessage.MSGReadRequest(ns, i)
        ' Wait for Reply
        DelaymS 100
        ' Decode End Point Rx Data
        OpcUaMessage.DecodeMSGReadData
        ' Decode End Point Rx Data
        ReadValue = OpcUaMessage.DecodeMSGReadData
    End Function
    Public Function WriteValue(ns As String, i As String, Data As String) As String
        ' Write To PLC
        WriteValue = OpcUaMessage.MSGWriteRequest(ns, i, Data)
        ' Wait for Reply
        DelaymS 100
        ' Decode End Point Rx Data
        OpcUaMessage.DecodeMSGWriteData
        ' Decode End Point Rx Data
        WriteValue = OpcUaMessage.DecodeMSGWriteData
    End Function
    Public Function CloseConnection()
        ' Set Message Type
        txMessageType = "CLO"
        ' Close Connection
        OpcUaCore.CLO
    End Function
    Public Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
        ' Ethernet Rx Data
        Dim rxStr As String
        ' Data Arrival
        Winsock1.GetData rxStr
        ' Add to String
        WinsockRx = WinsockRx + rxStr
        ' Dim RxType
        Dim RxType As String
        ' Rx Type
        RxType = Mid(rxStr, 1, 3)
        ' Decode ACK Rx Data
        If RxType = "ACK" Then OpcUaCore.DecodeACK rxStr
        ' Decode OPN Rx Data
        If RxType = "OPN" Then OpcUaCore.DecodeOPN rxStr
        ' Decode MSG Rx Data
        If RxType = "MSG" Then DoEvents
        ' Decode CLO Rx Data
        If RxType = "CLO" Then DoEvents
        ' Decode ERR Rx Data
        If RxType = "ERR" Then DoEvents
    End Sub
    ' Convert to Printable Characters
    Public Function PrintAll(str As String) As String
        ' Print all Function
        Dim i As Integer
        Dim aChr As String
        Dim BuffStr As String
        ' For Length of (Buffer)
        For i = 1 To Len(str)
        ' For Each Character
        aChr = Mid(str, i, 1)
            ' Is Printable?
            If Val(Asc(aChr)) > 31 And Val(Asc(aChr)) < 127 Then
                ' Print Character
                BuffStr = BuffStr + aChr
            Else
                ' or, Print Space
                BuffStr = BuffStr + " "
            End If
        Next
        ' Output
        PrintAll = BuffStr
    End Function
    ' Convert to Hex Characters
    Public Function PrintHex(str As String) As String
        ' Print Hex Function
        Dim i As Integer
        Dim aChr As String
        Dim BuffStr As String
        ' For Length of (Buffer)
        For i = 1 To Len(str)
        ' For Each Character
        aChr = Mid(str, i, 1)
            ' For Each Character
            aChr = Trim(Hex(Asc(Mid(str, i, 1))))
            ' Padding
            If Len(aChr) = 1 Then aChr = "0" & aChr
            ' Buffer
            BuffStr = BuffStr & aChr & "."
        Next
        ' Output
        PrintHex = BuffStr
    End Function
    ' Convert EndPoints
    Public Function PrintEndPoint() As String
        ' Get from opcUaMessage
        PrintEndPoint = OpcUaMessage.PrintEndPoint
    End Function
    Public Function DelaymS(mS As Integer)
        ' Delay Function
        tmrDelay.Interval = mS
        ' Mouse Pointer
        If mS > 100 Then Screen.MousePointer = vbHourglass
        ' Set Delay Time
        tmrDelay.Enabled = True
        ' Wait for Delay
        Do While tmrDelay.Enabled = True: DoEvents: Loop
    End Function
    Private Sub tmrDelay_Timer()
        ' Turn Off
        tmrDelay.Enabled = False
        ' Mouse Cursor
        Screen.MousePointer = vbNormal
    End Sub
    Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
        ' Exit
        Winsock1.Close
    
    End Sub
    Name:  Screen1.jpg
Views: 234
Size:  22.0 KB

    Screen shot showing the first tree structure.

    Name:  Screen2.jpg
Views: 236
Size:  37.5 KB

    Siemens S7-1200 PLC programmed with OPC-UA server.

    OPC-UA MQTT Rx Payload etc is used to transfer the data between UPC-UA and Hive MQTT broker.

    The PLC can communicate to UPC-UA and MQTT as required.

    Name:  Screen3.jpg
Views: 236
Size:  57.7 KB

    Wire Shark packet capture showing Write node packet

    Code:- Winsock OPC UA - v0.6.zip

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width