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;
}
}
完成上述步驟後,接下來就可以開始使用接收命令(續…)