C#通過HSLCommunication庫操作PLC用法
你需要掌握 C# 通過 HSLCommunication 庫操作 PLC 的完整流程和實用用法,下面將從環(huán)境搭建、核心操作、資源管理到完整示例進行詳細講解,以主流西門子 S7-1200/1500 PLC 為例,其他品牌(三菱、歐姆龍等)用法可類比替換。
一、環(huán)境準備(前提步驟)
1. 安裝 HSLCommunication 庫
HSLCommunication 以 NuGet 包形式分發(fā),兩種安裝方式任選:
- 圖形界面安裝:Visual Studio 中右鍵項目 → 管理 NuGet 程序包 → 瀏覽 → 搜索
HslCommunication→ 安裝最新穩(wěn)定版 - 命令行安裝:打開程序包管理器控制臺,執(zhí)行以下命令
Install-Package HslCommunication
2. 引入核心命名空間
在 C# 代碼文件頭部引入必要命名空間,針對西門子 PLC 的核心命名空間如下:
using System; using System.Collections.Generic; using HslCommunication; // 核心公共命名空間 using HslCommunication.Profinet; // 工業(yè)總線公共命名空間 using HslCommunication.Profinet.Siemens; // 西門子PLC專屬命名空間 // 三菱PLC替換為:using HslCommunication.Profinet.Mitsubishi; // 歐姆龍PLC替換為:using HslCommunication.Profinet.Omron;
二、核心操作流程
HSLCommunication 操作 PLC 的統(tǒng)一核心流程:創(chuàng)建 PLC 實例 → 建立連接 → 讀寫操作 → 釋放資源
1. 創(chuàng)建 PLC 通信實例
針對不同品牌 PLC,HSLCommunication 提供了專屬實例類,以西門子 S7-1200/1500 為例,創(chuàng)建 TCP/IP 通信實例:
// 構(gòu)造函數(shù)參數(shù)說明: // 1. PLC型號(S71200/S71500/S7300/S7400) // 2. PLC的局域網(wǎng)IP地址(需與電腦在同一網(wǎng)段) // 3. 機架號(默認0,無需修改) // 4. 槽號(S71200/1500默認1;S7300默認2) SiemensS7Net plcClient = new SiemensS7Net(SiemensPLCS.S71200, "192.168.1.100", 0, 1); // 可選配置:設置連接超時和讀寫超時(單位:毫秒,默認3000) plcClient.ConnectTimeOut = 5000; // 連接超時時間 plcClient.ReceiveTimeOut = 5000; // 讀寫超時時間
其他品牌 PLC 實例創(chuàng)建示例:
- 三菱 FX 系列(以太網(wǎng)):
MitsubishiFxNet plcClient = new MitsubishiFxNet("192.168.1.101"); - 歐姆龍 CJ 系列(FINS 協(xié)議):
OmronFinsNet plcClient = new OmronFinsNet("192.168.1.102");
2. 建立 PLC 連接
使用ConnectServer()方法建立連接,該方法返回OperateResult對象(HSL 核心返回類型,用于判斷操作是否成功):
// 建立與PLC的連接
OperateResult connectResult = plcClient.ConnectServer();
// 判斷連接是否成功
if (connectResult.IsSuccess)
{
Console.WriteLine("PLC連接成功!");
// 連接成功后,執(zhí)行讀寫操作
}
else
{
// 連接失敗,輸出錯誤信息
Console.WriteLine($"PLC連接失?。″e誤原因:{connectResult.Message}");
// 連接失敗時,建議釋放資源
plcClient.Dispose();
return;
}3. 核心讀寫操作(最常用)
HSLCommunication 提供了豐富的讀寫方法,核心分為單個地址讀寫和批量地址讀寫,支持 bool、int16、int32、float 等常用數(shù)據(jù)類型。
(1)單個地址讀寫
① 布爾類型(位操作:M0.0、I0.1、Q0.2、DB1.DBX0.0)
布爾類型是 PLC 的位狀態(tài),對應輸入、輸出、中間繼電器等,核心方法:
讀?。?code>ReadBool(string address)
寫入:Write(string address, bool value)
try
{
// 讀取M0.0的狀態(tài)
OperateResult<bool> readBoolResult = plcClient.ReadBool("M0.0");
if (readBoolResult.IsSuccess)
{
bool m00Value = readBoolResult.Content; // 獲取讀取結(jié)果
Console.WriteLine($"M0.0 當前值:{m00Value}");
}
else
{
Console.WriteLine($"讀取M0.0失?。簕readBoolResult.Message}");
}
// 寫入M0.0為true(置1)
OperateResult writeBoolResult = plcClient.Write("M0.0", true);
if (writeBoolResult.IsSuccess)
{
Console.WriteLine("M0.0 寫入true成功!");
}
else
{
Console.WriteLine($"M0.0 寫入失?。簕writeBoolResult.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"布爾類型讀寫異常:{ex.Message}");
}② 數(shù)值類型(int32、float、int16 等)
以工業(yè)場景最常用的int32(雙字,對應 PLC DInt 類型)和float(實數(shù),對應 PLC Real 類型)為例:
讀取:ReadInt32(string address)、ReadFloat(string address)
寫入:Write(string address, int value)、Write(string address, float value)
try
{
// 1. 讀寫int32類型(對應PLC DB1.DBD0,數(shù)據(jù)塊雙字地址)
// 讀取DB1.DBD0的值
OperateResult<int> readInt32Result = plcClient.ReadInt32("DB1.DBD0");
if (readInt32Result.IsSuccess)
{
int db1Dbd0Value = readInt32Result.Content;
Console.WriteLine($"DB1.DBD0(int32):{db1Dbd0Value}");
}
else
{
Console.WriteLine($"讀取DB1.DBD0失?。簕readInt32Result.Message}");
}
// 寫入DB1.DBD0為2025
OperateResult writeInt32Result = plcClient.Write("DB1.DBD0", 2025);
if (writeInt32Result.IsSuccess)
{
Console.WriteLine("DB1.DBD0 寫入2025成功!");
}
else
{
Console.WriteLine($"DB1.DBD0 寫入失?。簕writeInt32Result.Message}");
}
// 2. 讀寫float類型(對應PLC DB1.DBD4,數(shù)據(jù)塊實數(shù)地址)
// 讀取DB1.DBD4的值
OperateResult<float> readFloatResult = plcClient.ReadFloat("DB1.DBD4");
if (readFloatResult.IsSuccess)
{
float db1Dbd4Value = readFloatResult.Content;
Console.WriteLine($"DB1.DBD4(float):{db1Dbd4Value:F2}"); // 保留2位小數(shù)輸出
}
else
{
Console.WriteLine($"讀取DB1.DBD4失敗:{readFloatResult.Message}");
}
// 寫入DB1.DBD4為6.66f
OperateResult writeFloatResult = plcClient.Write("DB1.DBD4", 6.66f);
if (writeFloatResult.IsSuccess)
{
Console.WriteLine("DB1.DBD4 寫入6.66成功!");
}
else
{
Console.WriteLine($"DB1.DBD4 寫入失?。簕writeFloatResult.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"數(shù)值類型讀寫異常:{ex.Message}");
}(2)批量讀寫操作(高效推薦)
當需要讀寫多個 PLC 地址時,批量操作可減少網(wǎng)絡通信次數(shù),提升效率,核心用法如下:
批量讀?。簜魅氲刂窋?shù)組,返回結(jié)果數(shù)組
批量寫入:傳入鍵值對字典(地址為鍵,值為待寫入數(shù)據(jù))
try
{
// 1. 批量讀取布爾類型(M0.0、M0.1、I0.0)
string[] boolAddresses = new string[] { "M0.0", "M0.1", "I0.0" };
OperateResult<bool[]> readBoolBatchResult = plcClient.ReadBool(boolAddresses);
if (readBoolBatchResult.IsSuccess)
{
bool[] boolValues = readBoolBatchResult.Content;
for (int i = 0; i < boolAddresses.Length; i++)
{
Console.WriteLine($"{boolAddresses[i]}:{boolValues[i]}");
}
}
else
{
Console.WriteLine($"批量讀取布爾類型失敗:{readBoolBatchResult.Message}");
}
// 2. 批量寫入(混合布爾、int32、float類型)
Dictionary<string, object> writeDict = new Dictionary<string, object>()
{
{ "M0.1", false }, // 布爾類型
{ "DB1.DBD8", 1000 }, // int32類型
{ "DB1.DBD12", 9.99f } // float類型
};
OperateResult writeBatchResult = plcClient.Write(writeDict);
if (writeBatchResult.IsSuccess)
{
Console.WriteLine("所有地址批量寫入成功!");
}
else
{
Console.WriteLine($"批量寫入失?。簕writeBatchResult.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"批量讀寫異常:{ex.Message}");
}4. 資源釋放(關鍵步驟)
通信完成后,需關閉連接并釋放資源,避免內(nèi)存泄漏,推薦兩種方式:
方式 1:使用using語句(推薦,自動釋放)
using 語句會自動調(diào)用對象的Dispose()方法,無需手動釋放資源:
// using包裹PLC實例,代碼塊執(zhí)行完畢后自動釋放資源
using (SiemensS7Net plcClient = new SiemensS7Net(SiemensPLCS.S71200, "192.168.1.100", 0, 1))
{
// 建立連接、執(zhí)行讀寫操作...
OperateResult connectResult = plcClient.ConnectServer();
if (connectResult.IsSuccess)
{
// 讀寫邏輯
}
} // 此處自動釋放plcClient資源,無需手動調(diào)用Dispose()方式 2:手動釋放資源
若不使用using語句,需在操作完成后手動關閉連接并釋放:
SiemensS7Net plcClient = new SiemensS7Net(SiemensPLCS.S71200, "192.168.1.100", 0, 1);
try
{
// 建立連接、讀寫操作...
}
finally
{
// 關閉連接
plcClient.DisconnectServer();
// 釋放資源
plcClient.Dispose();
Console.WriteLine("PLC連接已關閉,資源已釋放!");
}三、關鍵注意事項
- 地址格式規(guī)范:需使用 PLC 標準地址格式,避免讀寫失敗
- 西門子:M0.0(中間繼電器)、I0.1(輸入)、Q0.2(輸出)、DB1.DBD0(數(shù)據(jù)塊雙字)、DB1.DBX0.0(數(shù)據(jù)塊位)
- 三菱:X0(輸入)、Y0(輸出)、M0(中間繼電器)、D0(數(shù)據(jù)寄存器)
- OperateResult 對象:HSL 所有操作均返回該對象(或泛型
OperateResult<T>)IsSuccess:判斷操作是否成功(bool 類型)Message:操作失敗時,獲取詳細錯誤信息(字符串類型)Content:泛型版本專屬,獲取操作成功后的結(jié)果數(shù)據(jù)(T 類型)
- 數(shù)據(jù)類型匹配:必須保證 C# 數(shù)據(jù)類型與 PLC 數(shù)據(jù)類型一致
- PLC DInt(雙字)→ C# int(int32)
- PLC Real(實數(shù))→ C# float(單精度浮點)
- PLC Int(字)→ C# short(int16)
- PLC Bit(位)→ C# bool
- 異常處理:所有讀寫操作建議包裹在
try-catch塊中,捕獲網(wǎng)絡中斷、地址不存在等異常。
四、完整可運行示例代碼
using System;
using System.Collections.Generic;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
namespace HslPlcOperationDemo
{
class Program
{
static void Main(string[] args)
{
// 使用using語句自動釋放PLC資源
using (SiemensS7Net plcClient = new SiemensS7Net(SiemensPLCS.S71200, "192.168.1.100", 0, 1))
{
try
{
// 1. 建立PLC連接
OperateResult connectResult = plcClient.ConnectServer();
if (!connectResult.IsSuccess)
{
Console.WriteLine($"PLC連接失敗:{connectResult.Message}");
Console.ReadKey();
return;
}
Console.WriteLine("PLC連接成功!\n");
// 2. 單個讀寫布爾類型(M0.0)
SingleReadWriteBool(plcClient);
// 3. 單個讀寫數(shù)值類型(int32 + float)
SingleReadWriteNumber(plcClient);
// 4. 批量讀寫操作
BatchReadWrite(plcClient);
}
catch (Exception ex)
{
Console.WriteLine($"程序異常:{ex.Message}");
}
finally
{
// 手動關閉連接(可選,using會自動釋放)
plcClient.DisconnectServer();
Console.WriteLine("\nPLC連接已關閉!");
}
}
Console.ReadKey();
}
/// <summary>
/// 單個讀寫布爾類型
/// </summary>
private static void SingleReadWriteBool(SiemensS7Net plcClient)
{
// 讀取M0.0
OperateResult<bool> readResult = plcClient.ReadBool("M0.0");
if (readResult.IsSuccess)
{
Console.WriteLine($"M0.0 讀取值:{readResult.Content}");
}
else
{
Console.WriteLine($"M0.0 讀取失敗:{readResult.Message}");
}
// 寫入M0.0為true
OperateResult writeResult = plcClient.Write("M0.0", true);
if (writeResult.IsSuccess)
{
Console.WriteLine("M0.0 寫入true成功!\n");
}
else
{
Console.WriteLine($"M0.0 寫入失?。簕writeResult.Message}\n");
}
}
/// <summary>
/// 單個讀寫數(shù)值類型(int32 + float)
/// </summary>
private static void SingleReadWriteNumber(SiemensS7Net plcClient)
{
// 讀寫int32(DB1.DBD0)
OperateResult<int> readIntResult = plcClient.ReadInt32("DB1.DBD0");
if (readIntResult.IsSuccess)
{
Console.WriteLine($"DB1.DBD0(int32)讀取值:{readIntResult.Content}");
}
else
{
Console.WriteLine($"DB1.DBD0 讀取失?。簕readIntResult.Message}");
}
OperateResult writeIntResult = plcClient.Write("DB1.DBD0", 2025);
if (writeIntResult.IsSuccess)
{
Console.WriteLine("DB1.DBD0 寫入2025成功!");
}
else
{
Console.WriteLine($"DB1.DBD0 寫入失?。簕writeIntResult.Message}");
}
// 讀寫float(DB1.DBD4)
OperateResult<float> readFloatResult = plcClient.ReadFloat("DB1.DBD4");
if (readFloatResult.IsSuccess)
{
Console.WriteLine($"DB1.DBD4(float)讀取值:{readFloatResult.Content:F2}");
}
else
{
Console.WriteLine($"DB1.DBD4 讀取失?。簕readFloatResult.Message}");
}
OperateResult writeFloatResult = plcClient.Write("DB1.DBD4", 6.66f);
if (writeFloatResult.IsSuccess)
{
Console.WriteLine("DB1.DBD4 寫入6.66成功!\n");
}
else
{
Console.WriteLine($"DB1.DBD4 寫入失?。簕writeFloatResult.Message}\n");
}
}
/// <summary>
/// 批量讀寫操作
/// </summary>
private static void BatchReadWrite(SiemensS7Net plcClient)
{
// 批量讀取布爾類型
string[] boolAddrs = new string[] { "M0.0", "M0.1", "I0.0" };
OperateResult<bool[]> batchReadResult = plcClient.ReadBool(boolAddrs);
if (batchReadResult.IsSuccess)
{
Console.WriteLine("批量讀取布爾類型結(jié)果:");
for (int i = 0; i < boolAddrs.Length; i++)
{
Console.WriteLine($"{boolAddrs[i]}:{batchReadResult.Content[i]}");
}
}
else
{
Console.WriteLine($"批量讀取布爾類型失敗:{batchReadResult.Message}");
}
// 批量寫入混合類型
Dictionary<string, object> writeDict = new Dictionary<string, object>()
{
{ "M0.1", false },
{ "DB1.DBD8", 1000 },
{ "DB1.DBD12", 9.99f }
};
OperateResult batchWriteResult = plcClient.Write(writeDict);
if (batchWriteResult.IsSuccess)
{
Console.WriteLine("批量寫入所有地址成功!");
}
else
{
Console.WriteLine($"批量寫入失?。簕batchWriteResult.Message}");
}
}
}
}到此這篇關于C#通過HSLCommunication庫操作PLC用法的文章就介紹到這了,更多相關C#通過HSLCommunication庫操作PLC內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決C# 截取當前程序窗口指定位置截圖的實現(xiàn)方法
本篇文章是對C#中截取當前程序窗口指定位置截圖的實現(xiàn)方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05
C#使用應用RSA和ECC進行數(shù)字簽名和簽名驗證的示例詳解
開發(fā)中需要用到數(shù)字簽名和驗簽,這篇博客提供使用RSA和ECDSA(橢圓曲線數(shù)字簽名算法,也是橢圓曲線加密的常見應用)進行數(shù)字簽名和簽名驗證的C#程序示例,同時,也會包含密鑰生成和保存的例程,需要的朋友可以參考下2025-09-09
詳解WPF如何在Panel中實現(xiàn)設置所有子項間距
這篇文章主要為大家詳細介紹了WPF如何在Panel中實現(xiàn)設置所有子項間距,本文借鑒了 Qt 中的 Spacing 設置方法,感興趣的小伙伴可以跟隨小編一起學習一下2024-10-10
C# wpf Brush轉(zhuǎn)Hex字符串的實例代碼
這篇文章主要介紹了C# wpf Brush轉(zhuǎn)Hex字符串的實例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
C#實現(xiàn)將商品金額小寫轉(zhuǎn)換成大寫的方法
這篇文章主要介紹了C#實現(xiàn)將商品金額小寫轉(zhuǎn)換成大寫的方法,涉及C#數(shù)組與字符串的相關操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-08-08

