有一個項目使用的是西門子的PLC,你開發了一個上位機,現在有一個第三方軟件也想要獲取西門子PLC的數據,希望你能提供一個接口,該如何實現。
我相信你們應該會遇到這種問題,其實解決方案很多,今天跟大家分享一種方式——提供ModbusTCP接口,提供ModbusTCP接口其實就是開發ModbusTCP服務器。
首先我們要清楚ModbusTCP服務器的本質就是Socket服務器,只是創建了4個集合或數組作為4個存儲區,當接收到ModbusTCP客戶端的報文請求時,將對應的存儲區數據返回給客戶端。
雖然原理很容易理解,但是自己開發還是需要一點時間的,今天跟大家分享,如何基於NModbus4這個開源庫來快速實現。
方便起見,這里用控制台應用程序來做。
首先創建一個控制台應用程序,然后通過Nuget添加兩個通信庫,分別是xktComm和NModbus4。
然后創建幾個靜態對象:
//西門子通信
public static SiemensS7 siemensS7 = new SiemensS7();
//ModbusTcpSlave對象
public static ModbusTcpSlave modbusTcpSlave = null;
//TcpListener對象
public static TcpListener tcpListener;
在Main方法里編寫代碼如下:
static void Main(string[] args)
{
//連接西門子PLC
bool siemensconn = siemensS7.Connect("192.168.1.200", CPU_Type.S71200, 0, 0);
if (siemensconn)
{
Console.WriteLine("西門子PLC連接成功");
}
else
{
Console.WriteLine("西門子PLC連接失敗");
}
//創建ModbusTCP服務器
bool slaveconn = false;
try
{
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 502);
modbusTcpSlave = ModbusTcpSlave.CreateTcp(1, tcpListener);
modbusTcpSlave.Listen();
slaveconn = true;
Console.WriteLine("ModbusTCP服務開啟成功");
}
catch (Exception ex)
{
slaveconn = false;
Console.WriteLine("ModbusTCP服務開啟失敗:" + ex.Message);
}
//西門子PLC連接成功且ModbusTCP服務器創建成功
if (siemensconn && slaveconn)
{
while (true)
{
//讀取PLC的數據,寫入到ModbusTCP里
float value = Convert.ToSingle(siemensS7.Read("DB1.DBD0", VarType.Real));
//顯示出來
Console.WriteLine("讀取數據:" + value);
//寫入Modbus服務器
SetFloatValue(1, value);
Thread.Sleep(500);
}
}
Console.ReadLine();
}
其中SetFloatValue方法是往ModbusTCP服務器的保持型寄存器中寫入浮點數據,這里要注意,索引是從1開始的,這里就是將PLC的DB1.DBD0的數據讀取之后,以浮點數的方式寫入到40001和40002兩個寄存器中。