ASComm.Net Modbbus TCP / Serial 的使用方式(設定篇)

  • 201
  • 0
  • 2019-02-27

ASComm.Net 提供快速的 modbus 連接與數據擷取,可以加速開發 modbus 的各項協議,
而且本身是 Thread managed,可以自行掃描,不需要自己做額外的處理工作,
也提供完整的範例程式以及快速連接工具可以讓你在寫程式碼前,先測試是否有問題在開始
可以省下很多前置時間,相較其他 modbus 的工具比起來,算很穩定

單一主機授權其實也不貴(TCP $149, Serial $99)

詳細的產品信息可以到官網參考:
https://www.automatedsolutions.com/products/dotnet/default.asp

 

他主要被區分為以下4大類別來使用:

  • Channel : 代表連線類型,如 TCP/IP 還是 modbus RTU/ASCII(RS422,485)
  • Device : 連接的裝置,像是溫控表、真空表、儀器等
  • Group : 掃描項目(item)的一種集合,所有在集合當中項目可以被統一掃描或調節
  • item 最基底的掃描項目,如:取得溫控器單一PV值、取得一個範圍的數值

而完整的關係圖可以參考下方的原廠表示圖:

以下簡單記錄使用方式:

如果是以 TCP 連線,引入以下參考:

using AutomatedSolutions;
using AutomatedSolutions.Win.Comm.MB.Master.Net;
using AutomatedSolutions.Win.Comm.MB.Master;

如果是以Serial 485 連線的話,引入以下參考:

using AutomatedSolutions;
using AutomatedSolutions.Win.Comm.MB.Master.Serial;
using AutomatedSolutions.Win.Comm.MB.Master;

使用前先宣告所要使用的元件:

 //宣告   
 private Channel channel; //連線通道
 private Device device;//裝置
 private Group group; //群組
 private Item[] rwItems; //讀取項目

然後在 new Class 時,進行 AScomm 連線的初始化以及接點等配置
 

首先,先 new 一個 channel,
如果是TCP使用以下宣告

channel = new Channel(Driver.TCP);

如果是 RS485則使用以下宣告

channel = new Channel(ModbusProtocol.RTU, "COM1", "9600,E,8,1");

接下來再對channel加入device,範例如下:

channel.Devices.Add(new Device()
{
  RoutePath = IpAddress, //連接站別(TCP的話就是 IP Address)
  Label = $"Delcom #{DeviceName}", //標籤名稱(顯示用)
  WriteCoilFunction = WriteCoilFunction.FC5, //線圈的輸出命令
  WriteRegisterFunction = WriteRegisterFunction.FC6, //暫存器的輸出命令
  AddressType = AddressType.ZERO_BASED, //資料位置的初始值 0 or 1
  TimeoutConnect = 2000, //連接超時設定(ms)
  TimeoutTransaction = 2000, //擷取資料超時設定(ms)
}); //Add Device to Channel.

然後,新增一個群組,準備用來將接下來要掃描的位址給加入

//新增群組
group = new Group() { Label = "Group", Active = true, UpdateRate = 500, };

/*
 * Group 群組(所有要掃描的位址集合)
 * Label : 名稱(顯示用)
 * Active : 掃描 ON/OFF
 * UpdateRate : 掃描頻率(ms)
 */

開始設定要讀取或寫入的位址所需的參數:

//新增掃描裝置
rwItems = new Item[] {
      new Item(){ Label = "READ DATA", Elements = 12, HWTagType = TagType.INPUT_REGISTER, HWTagName = "1" }, //資料 from 0 ~ 12
      new Item(){ Label = "RANGE", Elements = 1, HWTagType = TagType.COIL, HWTagName = "2" },//RANGE 位置,Register = 2
      new Item(){ Label = "REZERO", Elements = 1, HWTagType = TagType.COIL, HWTagName = "3" },//歸零,Coil Register = 2
      };

/*
 * Item 參數說明:
 *  Label : 名稱(顯示用)
 *  HWTagName : 資料位址(int格式,如果您的modbus裝置是HEX,記得要轉換)
 *  Elements : 取得的資料長度(HWTagName + Elements -1)
 *  HWTagType : 資料類型
 */

將所設定的位置容器依序加入到群組內

 //將Item 加入Group
for (int i = 0; i < rwItems.Length; i++)
   group.Items.Add(rwItems[i]);

最後,再把完整的群組加入到 channel.device.groups 就大功告成了:

//將集合好的group加入device/groups內
channel.Devices[0].Groups.Add(group);

 

完整的程式碼範例如下(TCP)

   /// <summary>
    /// TCP 連線
    /// </summary>
    private bool InitTcpCommunication()
    {

        try
        {
            channel = new Channel(Driver.TCP);

            //新增DEVICE
            channel.Devices.Add(new Device()
            {
                RoutePath = IpAddress, //連接站別(TCP的話就是 IP Address)
                Label = $"Delcom #{DeviceName}", //標籤名稱(顯示用)
                WriteCoilFunction = WriteCoilFunction.FC5, //線圈的輸出命令
                WriteRegisterFunction = WriteRegisterFunction.FC6, //暫存器的輸出命令
                AddressType = AddressType.ZERO_BASED, //資料位置的初始值 0 or 1
                TimeoutConnect = 2000, //連接超時設定(ms)
                TimeoutTransaction = 2000, //擷取資料超時設定(ms)
            }); //Add Device to Channel.

            //新增群組
            group = new Group() { Label = "Group", Active = true, UpdateRate = 500, };

            /*
             * Group 群組(所有要掃描的位址集合)
             * Label : 名稱(顯示用)
             * Active : 掃描 ON/OFF
             * UpdateRate : 掃描頻率(ms)
             */

            //新增掃描裝置
            rwItems = new Item[] {
                new Item(){ Label = "READ DATA", Elements = 12, HWTagType = TagType.INPUT_REGISTER, HWTagName = "1" }, //資料 from 0 ~ 12
                new Item(){ Label = "RANGE", Elements = 1, HWTagType = TagType.COIL, HWTagName = "2" },//RANGE 位置,Register = 2
                new Item(){ Label = "REZERO", Elements = 1, HWTagType = TagType.COIL, HWTagName = "3" },//歸零,Coil Register = 2
            };

            /*
             * Item 參數說明:
             *  Label : 名稱(顯示用)
             *  HWTagName : 資料位址(int格式,如果您的modbus裝置是HEX,記得要轉換)
             *  Elements : 取得的資料長度(HWTagName + Elements -1)
             *  HWTagType : 資料類型
             */

            //將Item 加入Group
            for (int i = 0; i < rwItems.Length; i++)
                group.Items.Add(rwItems[i]);

            //將集合好的group加入device/groups內
            channel.Devices[0].Groups.Add(group);

            Connected = true;
            return true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
            Connected = false;
            return false;
        }
    }

 

完成上述步驟後,接下來就可以開始使用接收命令(續…)