【问题标题】:Can I query the list of variables and types我可以查询变量和类型的列表吗
【发布时间】:2019-08-16 12:58:19
【问题描述】:

我可以使用 twincat-ads 查询 Beckhoff PLC 以获取在 ADS 上公开的变量(及其类型)吗?

【问题讨论】:

    标签: twincat-ads


    【解决方案1】:

    是的,你可以。

    此示例直接来自 Beckhoff 广告文档,您应该学习一下以了解广告协议的基础知识。

    /// <summary>
    /// Defines the entry point of the application.
    /// </summary>
    /// <param name="args">The arguments.</param>
    static void Main(string[] args)
    {
        Console.WriteLine("");
        Console.WriteLine("Press [Enter] for start:");
        Console.ReadLine();
    
        // Parse the command-line arguments
        AmsAddress address = ArgParser.Parse(args);
    
        using (TcAdsClient client = new TcAdsClient())
        {
        // Connect the AdsClient to the device target.
        client.Connect(address);
    
        // Load symbolic information
        ISymbolLoader loader = SymbolLoaderFactory.Create(client, SymbolLoaderSettings.Default);
        ReadOnlySymbolCollection allSymbols = loader.Symbols;
    
        ISymbol bVar1 = allSymbols["GVL.bVar1"];
        ISymbol bVar2 = allSymbols["GVL.iCount"];
        ISymbol projectName = allSymbols["TwinCAT_SystemInfoVarList._AppInfo.ProjectName"];
    
        SymbolCollection symbols = new SymbolCollection() {bVar1, bVar2, projectName};
    
        // Sum Command Read
        SumSymbolRead readCommand = new SumSymbolRead(client,symbols);
        object[] values = readCommand.Read();
    
        for (int i = 0; i < symbols.Count; i++)
        {
            Console.WriteLine("Symbol: {0} (Value: {1}, Type: {2})",symbols[i].InstancePath,values[i].ToString(),values[i].GetType().Name);
        }
    
        // Sum Command Write
        SumSymbolWrite writeCommand = new SumSymbolWrite(client,symbols);
        object[] writeValues = new object[] {true, (short) 42, "MyNewProjectName"};
    
        writeCommand.Write(writeValues);
        }
    
        Console.WriteLine("");
        Console.WriteLine("Press [Enter] for leave:");
        Console.ReadLine();
    }
    

    在 C++ 中,您需要使用 AdsSyncReadReq 函数:

    #include <iostream.h>
    #include <windows.h>
    #include <conio.h>
    #include <assert.h>
    
    // ADS headers for TwinCAT 3
    #include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h"
    #include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h"
    
    void main()
    {
      long                  nErr, nPort; 
      char                  *pchSymbols = NULL; 
      UINT                  uiIndex; 
      AmsAddr               Addr; 
      PAmsAddr              pAddr = &Addr; 
      AdsSymbolUploadInfo   tAdsSymbolUploadInfo; 
      PAdsSymbolEntry       pAdsSymbolEntry; 
    
      // Open communication port on the ADS router
      nPort = AdsPortOpen();
      nErr = AdsGetLocalAddress(pAddr);
      if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';
    
      // Select Port: TwinCAT 3 PLC1 = 851
      pAddr->port = 851;
    
      // Read the length of the variable declaration
      nErr = AdsSyncReadReq(pAddr, ADSIGRP_SYM_UPLOADINFO, 0x0, sizeof(tAdsSymbolUploadInfo), &tAdsSymbolUploadInfo);
      if (nErr) cerr << "Error: AdsSyncReadReq: " << nErr << '\n'; 
      pchSymbols = new char[tAdsSymbolUploadInfo.nSymSize]; 
      assert(pchSymbols); 
    
      // Read information about the PLC variables 
      nErr = AdsSyncReadReq(pAddr, ADSIGRP_SYM_UPLOAD, 0, tAdsSymbolUploadInfo.nSymSize, pchSymbols); 
      if (nErr) cerr << "Error: AdsSyncReadReq: " << nErr << '\n'; 
    
      // Output information about the PLC variables 
      pAdsSymbolEntry = (PAdsSymbolEntry)pchSymbols; 
      for (uiIndex = 0; uiIndex < tAdsSymbolUploadInfo.nSymbols; uiIndex++)
      { 
        cout << PADSSYMBOLNAME(pAdsSymbolEntry) << "\t\t" 
             << pAdsSymbolEntry->iGroup << '\t' 
             << pAdsSymbolEntry->iOffs << '\t' 
             << pAdsSymbolEntry->size << '\t' 
             << PADSSYMBOLTYPE(pAdsSymbolEntry) << '\t' 
             << PADSSYMBOLCOMMENT(pAdsSymbolEntry) << '\n'; 
        pAdsSymbolEntry = PADSNEXTSYMBOLENTRY(pAdsSymbolEntry); cout.flush();
      }
      getch();
    
      // Close communication port
      nErr = AdsPortClose(); 
      if (nErr) cerr << "Fehler: AdsPortClose: " << nErr << '\n';
    
      // Release memory
      if (pchSymbols) delete(pchSymbols);
    } 
    

    更多信息:

    https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_ads_intro/9007199370899851.html&id=5869483416056481636

    【讨论】:

    • 谢谢。但这只有在 .Net 接口上才有可能吗?我在 DLL 中没有看到任何类似的函数。
    • Beckhoff 广告文档中的 c++ 示例有点旧,我需要更新广告标题的包含路径
    猜你喜欢
    • 2021-08-13
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多