65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 .NET 进行 PLC 通信

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.60/5 (28投票s)

2015年1月21日

CPOL

3分钟阅读

viewsIcon

372998

downloadIcon

30999

使用 .NET 读取和写入数据到三菱 PLC。

引言

在本文中,我将解释如何与 PLC可编程逻辑控制器)进行通信。我从 2007 年开始使用 .NET 开发 PLC 通信程序。

要基本了解 PLC 是什么,请使用 Google,因为我基本上不是 PLC 工程师或电气工程师。但是,我将向您解释如何使用 .NET 程序连接 PLC,如何从 PLC 读取数据以及如何将数据写入 PLC。我的示例程序都基于使用 TCP/IP 通信的三菱 MELSEC PLC。

有多种可用的 PLC,例如 MELSEC、SIMENS 等。对于每种 PLC 通信,都有不同类型的协议可用。在此演示程序中,我使用了 TCP IP 通信用于 MELSEC PLC。

在这里,我提到了 .NET 程序,而不是 .NET 中的一种语言。在我的文章中,您会找到四个 zip 文件

SPLCSharpConnect.zip 包含 PLC 组件 DLL 源代码。我于 2007 年开始进行 PLC 通信编程。当时,我正在使用 VB.NET 进行编码。我使用 VB.NET 创建了自己的 Winsock 组件。即使现在对于 PLC 通信,我仍在我的项目中使用相同的 Winsock 组件 MelsecPLC.dll。在该组件中,我创建了简单的函数,如 ConnectDisconnectReadWrite 和一个 DataArrival 事件。在附加的示例项目中,我使用了相同的 DLL。

在我们开始 PLC 通信编程之前,我想解释一下 PLC 通信中的读取和写入过程。

从 PLC 读取数据

PLC 读取命令:要从 PLC 读取数据,我们需要向 PLC 发送命令。基本上,我们发送的命令将如下所示:“500000FF03FF000018000A04010000D*0095000001”;

String   cmd = "";
cmd = cmd + "5000" ;  // sub HEAD (NOT)
cmd = cmd + "00"  ;   //   network number (NOT)
cmd = cmd + "FF"  ;   //PLC NUMBER
cmd = cmd + "03FF" ;  // DEMAND OBJECT MUDULE I/O NUMBER
cmd = cmd + "00" ;    //  DEMAND OBJECT MUDULE DEVICE NUMBER
cmd = cmd + "001C"  ; //  Length of demand data
cmd = cmd + "000A";   //  CPU inspector data
cmd = cmd + "0401";   //  Read command (to read the data from PLC we should “0401”
cmd = cmd + "0000" ;  //  Sub command
cmd = cmd +"D*"  ;    //   device code
cmd = cmd + "009500"; //adBase 
cmd = cmd + "0001";
//Device No ,It’s a Address every PLC device will have an address
//we need to send the appropriate address to read the data.

将数据写入 PLC

PLC 写入命令:要将数据写入 PLC,我们需要向 PLC 发送命令。基本上,我们发送的命令将如下所示:“500000FF03FF00001C000A14010000D*0095010002”。

String   cmd = ""; 

cmd = cmd + "5000";   // sub HEAD (NOT)
cmd = cmd + "00";     // network number (NOT)
cmd = cmd + "FF";     // PLC NUMBER
cmd = cmd + "03FF";   // DEMAND OBJECT MUDULE I/O NUMBER
cmd = cmd + "00";     // DEMAND OBJECT MUDULE DEVICE NUMBER
cmd = cmd + "001C";   // Length of demand data
cmd = cmd + "000A";   // CPU inspector data
cmd = cmd + "1401";   // Write command
cmd = cmd + "0000";   // Sub command
cmd = cmd + "D*";     // device code
cmd = cmd + "009501"; // adBase 
cmd = cmd + "0002";   // BASE ADDRESS

您可以看到区别,读取时我们使用“0401”和“009500”,但写入时我们使用“1401”和“009501”。详细代码将在下面列出。

Using the Code

我在本文中附加了 C# PLC 通信示例程序,但为了在此处进行解释,我在测试项目中使用了我自己的组件 MelsecPLC.dll。首先,将 MelsecPLC.dll 添加到您的项目中。

1. 在窗体中声明 MelsecPLC.dll

//
using MelsecPLC;

2. 变量声明

//
public MelsecPLC.Winsock winsock1; // Declare the MelsecPLC Winsock Component
string Jig01;                      // To store the PLC read data.

3. 连接(PLC 连接)

对于连接,我们需要 PLC IP 地址。在这里,我的 PLC IP 地址是“10.126.224.221”。输入本地端口和远程端口。在这里,我将“1027”用于本地端口,将“8000”用于远程端口。在窗体加载时,我们调用 PLC Connect 函数,并创建一个 MelsecPLC DataArrival 事件。当 PLC 向 PC(我们的计算机)发送数据时,将触发 DataArrival 事件。

下面列出了窗体加载中的详细连接函数和 DataArrival 声明

//
private void Form1_Load(object sender, EventArgs e)
{
    winsock1Connect();
    winsock1.DataArrival += 
      new MelsecPLC.Winsock.DataArrivalEventHandler(winsock1_DataArrival);
    timer1.Enabled = true;
    timer1.Start();
}

private void winsock1Connect()
{
    try
    {
        if (winsock1.GetState.ToString() != "Connected")
        {
            winsock1.LocalPort = 1027;
            winsock1.RemoteIP ="10.126.224.221";
            int a = 8000;
            winsock1.RemotePort = 8000;
            winsock1.Connect();
        }
    }
    catch (Exception ex)
    {
    }
}

4. DataArrival 事件

DataArrival 事件中,我们在向 PLC 发送读取信号后,获取 PLC 发送的实际数据。每当 PLC 向 PC 发送数据时,都会触发此事件。要从 PLC 获取数据,我们使用 winsock1.GetData() 方法。

//
private void winsock1_DataArrival(MelsecPLC.Winsock sender, int BytesTotal)
{
    String s = String.Empty;
    winsock1.GetData(ref s);
    Jig01 = s;
}

5. 从 PLC 读取数据

要从 PLC 读取数据,我们需要向 PLC 发送信号以进行数据读取。我在文章介绍中解释了读取函数。要将读取信号发送到 PLC,我们使用 winsock1.Send() 方法。

//
private void btnRead_Click(object sender, EventArgs e)
{
    if (winsock1.GetState.ToString() != "Connected")
    {
        winsock1Connect();
    }
    //String cmd = "500000FF03FF000018000A04010000D*0095000001";
    String cmd = "";
    String OutAddress = "0001";
    cmd = "";
    cmd = cmd + "5000" ;    // sub HEAD (NOT)
    cmd = cmd + "00"  ;     // network number (NOT)
    cmd = cmd + "FF"  ;     // PLC NUMBER
    cmd = cmd + "03FF"   ;  // DEMAND OBJECT MUDULE I/O NUMBER
    cmd = cmd + "00"  ;     // DEMAND OBJECT MUDULE DEVICE NUMBER
    cmd = cmd + "001C"  ;   // Length of demand data
    cmd = cmd + "000A";     // CPU inspector data
    cmd = cmd + "0401";     // Read command
    cmd = cmd + "0000" ;    // Sub command
    cmd = cmd +"D*"  ;      // device code
    cmd = cmd + "009500";   // adBase 
    cmd = cmd + OutAddress; // BASE ADDRESS           
    winsock1.Send(cmd);         
}

6. 将数据写入 PLC

要将数据写入 PLC,我们需要向 PLC 发送信号以进行数据写入。我在文章介绍中解释了 write 函数。要将写入信号发送到 PLC,我们在这里使用 winsock1.Send() 方法。

//
private void btnWrite_Click(object sender, EventArgs e)
{
    if (winsock1.GetState.ToString() != "Connected")
    {
        winsock1Connect();
    }      
    String cmd = "";
    String OutAddress = txtWrite.Text.Trim();
    cmd = "";
    cmd = cmd + "5000";      // sub HEAD (NOT)
    cmd = cmd + "00";        // network number (NOT)
    cmd = cmd + "FF";        // PLC NUMBER
    cmd = cmd + "03FF";      // DEMAND OBJECT MUDULE I/O NUMBER
    cmd = cmd + "00";        // DEMAND OBJECT MUDULE DEVICE NUMBER
    cmd = cmd + "001C";      // Length of demand data
    cmd = cmd + "000A";      // CPU inspector data
    cmd = cmd + "1401";      // Write command
    cmd = cmd + "0000";      // Sub command
    cmd = cmd + "D*";        // device code
    cmd = cmd + "009501";    // adBase 
    cmd = cmd + OutAddress;  // BASE ADDRESS
    winsock1.Send(cmd);
}

关注点

我喜欢使用 HMI(人机界面程序)进行工作和游戏。我使用 C# 处理了多个 HMI 程序,如 PLC、传感器编程和 NutRunner 工具通信程序。我希望读者能从此程序中受益。

历史

  • 2013 年 7 月 5 日:首次发布
  • 2015 年 1 月 21 日:首次发布
© . All rights reserved.