C#上位机与西门子PLC数据交互

这篇具有很好参考价值的文章主要介绍了C#上位机与西门子PLC数据交互。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C#通过S7.NET库实现与西门子PLC数据交互

.net与西门子plc通讯,西门子PLC,C#上位机,c#,visualstudio
拉了换一个简单的界面

PLC端设置

.net与西门子plc通讯,西门子PLC,C#上位机,c#,visualstudio
我新建了一个DB数据块【DB1】,右键【DB1】,点击【属性】项,【优化的块访问】默认是勾选,要想显示数据块中地址偏移量,需要把【优化的块访问】勾选取消

PLC与C#数据类型对应

Bit  	=> 	bool
Byte 	=> 	byte
word 	=> 	ushort
DWord 	=> 	uint
Int 	=> 	short
DInt 	=> 	int
Real 	=> 	float
LReal 	=> 	double
String 	=> 	string

VS2019添加S7.NET库引用

.net与西门子plc通讯,西门子PLC,C#上位机,c#,visualstudio
1、右键项目名,选择图中【管理NuGet程序包】
.net与西门子plc通讯,西门子PLC,C#上位机,c#,visualstudio2、在搜索框输入【S7netplus】,我安装的是第一个。
.net与西门子plc通讯,西门子PLC,C#上位机,c#,visualstudio
3、安装完成引用里面会自动添加【S7.NET】引用,如上图所示。

连接PLC

public void Open();

                this.myPlc.Open();
                if (this.myPlc.PlcObject.IsConnected)
                {
                    this.btnOpen.Enabled = false;
                    this.btnClose.Enabled = true;
                    this.tsslblIsConnected.BackColor = Color.Green;
                    this.tsslblIsConnected.Text = "PLC已连接";

                    this.tsslblIP.Text = this.myPlc.PlcObject.IP.ToString();

                    this.btnRead.Enabled = true;
                    this.btnWrite.Enabled = true;

                    switch (this.myPlc.PlcObject.CPU)
                    {
                        case CpuType.S7300:
                            this.tsslblCpuType.Text = "S7-300";
                            break;
                        case CpuType.S7400:
                            this.tsslblCpuType.Text = "S7-400";
                            break;
                        case CpuType.S71200:
                            this.tsslblCpuType.Text = "S7-1200";
                            break;
                        case CpuType.S71500:
                            this.tsslblCpuType.Text = "S7-1500";
                            break;
                    }
                }

对于S7-1200和S7-1500,默认为机架= 0,槽位= 0;对于S7-300和S7-400是默认的机架= 0,槽位= 2;端口号默认为102。

断开PLC

public void Close();

                this.myPlc.Close();
                if (!this.myPlc.PlcObject.IsConnected)
                {
                    this.btnOpen.Enabled = true;
                    this.btnClose.Enabled = false;
                    this.tsslblIsConnected.BackColor = Color.Red;
                    this.tsslblIsConnected.Text = "PLC未连接";

                    this.tsslblIP.Text = "***********";
                    this.tsslblCpuType.Text = "******";

                    this.btnRead.Enabled = false;
                    this.btnWrite.Enabled = false;
                }

读取单个数据

public object? Read(string variable);

            if (this.tabControlRead.SelectedTab == this.tabControlRead.TabPages[0])  //读取单个数据
            {
                try
                {
                    this.txtReadResult.Text = DateTime.Now.ToString() + ":" + this.myPlc.Read(this.txtReadSingleAdr.Text.Trim().ToUpper()).ToString();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("读取单个数据出现错误!" + ex.Message, "提示信息");
                }
            }

我这里把输入的地址的转换为大写字母;如果不转换,输入小写字母会出现报错。

读取数组数据

public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0);

switch (this.cboReadVarType.Text.Trim())
{
    case "Bit":
        foreach (var item in (System.Collections.BitArray)this.myPlc.Read(dataType, db, startByteAdr, VarType.Bit, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "Byte":
        foreach (var item in (byte[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Byte, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "Word":
        foreach (var item in (ushort[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Word, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "DWord":
        foreach (var item in (uint[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DWord, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "Int":
        foreach (var item in (short[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Int, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "DInt":
        foreach (var item in (int[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DInt, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "Real":
        foreach (var item in (float[])this.myPlc.Read(dataType, db, startByteAdr, VarType.Real, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "LReal":
        foreach (var item in (double[])this.myPlc.Read(dataType, db, startByteAdr, VarType.LReal, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "String":
        foreach (var item in (string)this.myPlc.Read(dataType, db, startByteAdr, VarType.String, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "S7String":
        foreach (var item in (string[])this.myPlc.Read(dataType, db, startByteAdr, VarType.S7String, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "S7WString":
        foreach (var item in (string[])this.myPlc.Read(dataType, db, startByteAdr, VarType.S7WString, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "DateTime":
        foreach (var item in (DateTime[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DateTime, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
    case "DateTimeLong":
        foreach (var item in (DateTime[])this.myPlc.Read(dataType, db, startByteAdr, VarType.DateTimeLong, varCount, bitAdr))
        {
            this.rtxtReadResult.Text += item.ToString() + " ";
        }
        break;
}

读取BIT数组时我这里使用【System.Collections.BitArray】强制转换

读取字节数组

public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count);

var bytes = this.myPlc.PlcObject.ReadBytes(DataType.DataBlock, 1, 0, 120);
string str = string.Empty;

str  = "DB1.DBX0.0:\t" + Convert.ToBoolean(bytes[0].SelectBit(0)).ToString() + "\n";
str += "DB1.DBX0.1:\t" + Convert.ToBoolean(bytes[0].SelectBit(1)).ToString() + "\n";
str += "DB1.DBX0.2:\t" + Convert.ToBoolean(bytes[0].SelectBit(2)).ToString() + "\n";

str += "DB1.DBB1.0:\t" + Convert.ToString(S7.Net.Types.Byte.FromByteArray(bytes.Skip(1).Take(1).ToArray()), 16) + "\n";
str += "DB1.DBB2.0:\t" + Convert.ToString(S7.Net.Types.Byte.FromByteArray(bytes.Skip(2).Take(1).ToArray()), 16) + "\n";
str += "DB1.DBB3.0:\t" + Convert.ToString(S7.Net.Types.Byte.FromByteArray(bytes.Skip(3).Take(1).ToArray()), 16) + "\n";

str += "DB1.DBW4.0:\t" + Convert.ToInt16(S7.Net.Types.Int.FromByteArray(bytes.Skip(4).Take(2).ToArray())) + "\n";
str += "DB1.DBW6.0:\t" + Convert.ToInt16(S7.Net.Types.Int.FromByteArray(bytes.Skip(6).Take(2).ToArray())) + "\n";
str += "DB1.DBW8.0:\t" + Convert.ToInt16(S7.Net.Types.Int.FromByteArray(bytes.Skip(8).Take(2).ToArray())) + "\n";

str += "DB1.DBW10.0\t:" + Convert.ToUInt16(S7.Net.Types.Word.FromByteArray(bytes.Skip(10).Take(2).ToArray())) + "\n";
str += "DB1.DBW12.0\t:" + Convert.ToUInt16(S7.Net.Types.Word.FromByteArray(bytes.Skip(12).Take(2).ToArray())) + "\n";
str += "DB1.DBW14.0\t:" + Convert.ToUInt16(S7.Net.Types.Word.FromByteArray(bytes.Skip(14).Take(2).ToArray())) + "\n";

str += "DB1.DBW16.0:\t" + Convert.ToString(S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray()), 16) + "\n";
str += "DB1.DBW18.0:\t" + Convert.ToString(S7.Net.Types.Word.FromByteArray(bytes.Skip(18).Take(2).ToArray()), 16) + "\n";
str += "DB1.DBW20.0:\t" + Convert.ToString(S7.Net.Types.Word.FromByteArray(bytes.Skip(20).Take(2).ToArray()), 16) + "\n";

str += "DB1.DBD22.0:\t" + Convert.ToString(S7.Net.Types.DWord.FromByteArray(bytes.Skip(22).Take(4).ToArray()), 16) + "\n";
str += "DB1.DBD26.0:\t" + Convert.ToString(S7.Net.Types.DWord.FromByteArray(bytes.Skip(26).Take(4).ToArray()), 16) + "\n";
str += "DB1.DBD30.0:\t" + Convert.ToString(S7.Net.Types.DWord.FromByteArray(bytes.Skip(30).Take(4).ToArray()), 16) + "\n";

str += "DB1.DBD34.0:\t" + Convert.ToInt32(S7.Net.Types.DInt.FromByteArray(bytes.Skip(34).Take(4).ToArray())) + "\n";
str += "DB1.DBD38.0:\t" + Convert.ToInt32(S7.Net.Types.DInt.FromByteArray(bytes.Skip(38).Take(4).ToArray())) + "\n";
str += "DB1.DBD42.0:\t" + Convert.ToInt32(S7.Net.Types.DInt.FromByteArray(bytes.Skip(42).Take(4).ToArray())) + "\n";

str += "DB1.DBD46.0:\t" + Convert.ToUInt32(S7.Net.Types.DWord.FromByteArray(bytes.Skip(46).Take(4).ToArray())) + "\n";
str += "DB1.DBD50.0:\t" + Convert.ToUInt32(S7.Net.Types.DWord.FromByteArray(bytes.Skip(50).Take(4).ToArray())) + "\n";
str += "DB1.DBD54.0:\t" + Convert.ToUInt32(S7.Net.Types.DWord.FromByteArray(bytes.Skip(54).Take(4).ToArray())) + "\n";

str += "DB1.DBD58.0:\t" + Convert.ToSingle(S7.Net.Types.Real.FromByteArray(bytes.Skip(58).Take(4).ToArray())) + "\n";
str += "DB1.DBD62.0:\t" + Convert.ToSingle(S7.Net.Types.Real.FromByteArray(bytes.Skip(62).Take(4).ToArray())) + "\n";
str += "DB1.DBD66.0:\t" + Convert.ToSingle(S7.Net.Types.Real.FromByteArray(bytes.Skip(66).Take(4).ToArray())) + "\n";

str += "DB1.DBD70.0:\t" + Convert.ToDouble(S7.Net.Types.LReal.FromByteArray(bytes.Skip(70).Take(8).ToArray())) + "\n";
str += "DB1.DBD78.0:\t" + Convert.ToDouble(S7.Net.Types.LReal.FromByteArray(bytes.Skip(78).Take(8).ToArray())) + "\n";
str += "DB1.DBD86.0:\t" + Convert.ToDouble(S7.Net.Types.LReal.FromByteArray(bytes.Skip(86).Take(8).ToArray())) + "\n";

str += "LocalTime:\t" + Convert.ToDateTime(S7.Net.Types.DateTimeLong.FromByteArray(bytes.Skip(96).Take(12).ToArray())) + "\n";
str += "SYSTime: \t\t" + Convert.ToDateTime(S7.Net.Types.DateTimeLong.FromByteArray(bytes.Skip(108).Take(12).ToArray())) + "\n";
str += "----------***********************-----------------\n";

我这里是读取DB1数据块的前120个字节的数据,我这里使用了Skip()和Take()函数,要使用这两个函数需要添加
using System.Linq;文章来源地址https://www.toymoban.com/news/detail-635689.html

修改单个数据

if (this.tabControlWrite.SelectedTab == this.tabControlWrite.TabPages[0])   //写入单个数据
{
    try
    {
        switch (this.cboWriteVarType.Text.Trim())
        {
            case "Bit":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToBoolean(this.rtxtWriteData.Text.Trim()));
                break;
            case "Byte":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToByte(this.rtxtWriteData.Text.Trim()));
                break;
            case "Word":
            case "Int":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToInt16(this.rtxtWriteData.Text.Trim()));
                break;
            case "DWord":
            case "DInt":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToInt32(this.rtxtWriteData.Text.Trim()));
                break;
            case "Real":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToSingle(this.rtxtWriteData.Text.Trim()));
                break;
            case "LReal":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToDouble(this.rtxtWriteData.Text.Trim()));
                break;
            case "String":
            case "S7String":
            case "S7WString":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), this.rtxtWriteData.Text.Trim());
                break;
            case "Timer":
                break;
            case "Counter":
                break;
            case "DateTime":
            case "DateTimeLong":
                this.myPlc.Write(this.txtWriteSingleAdr.Text.Trim(), Convert.ToDateTime(this.rtxtWriteData.Text.Trim()));
                break;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("写入单个数据出现错误!" + ex.Message, "提示信息");
    }

到了这里,关于C#上位机与西门子PLC数据交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#与西门子PLC通讯——手搓S7通讯协议

    本文将尝试从源码角度,使用Tcp/Ip的方式直接与西门子PLC进行交互通讯。 往期博客参考 C#与西门子PLC通讯——新手快速入门 C#与西门子PLC通讯——熟手快速入门 建议先看一下这两篇,了解预设背景。 知其然,知其所以然。 这篇文章,我们就尝试重复造一个轮子。通过对通讯

    2024年02月04日
    浏览(29)
  • C#通过ModbusTcp协议读写西门子PLC中的浮点数

    MODBUS/TCP是简单的、中立厂商的用于管理和控制自动化设备的MODBUS系列通讯协议的派生产品,显而易见,它覆盖了使用TCP/IP协议的“Intranet”和“Internet”环境中MODBUS报文的用途。协议的最通用用途是为诸如PLC,I/O模块,以及连接其它简单域总线或I/O模块的网关服务的。 Modbus

    2024年02月09日
    浏览(49)
  • C#语言使用EasyModbus做客户端和西门子1511PLC通信

    之前一直使用开源库NModbus,它是一个非常优秀的Modbus通信类库,偶然机会下我发现了EasyModbus,发现EasyModbus的代码非常精炼、间接,一两行代码就可以创建一个Modbus TCP Client。 EasyModbus官网:http://easymodbustcp.net/en/ 在官网下载DLL文件,在项目中添加引用。 代码如下(示例):

    2023年04月11日
    浏览(23)
  • C++上位软件通过LibModbus开源库和西门子S7-1200/S7-1500/S7-200 PLC进行ModbusTcp 和ModbusRTU 通信

            一直以来上位软件比如C++等和西门子等其他品牌PLC之间的数据交换都是大家比较头疼的问题,尤其是C++上位软件程序员。传统的方法一般有OPC、Socket 等,直到LibModbus 开源库出现后这种途径对程序袁来说又有了新的选择。           1 )使用简单, 利用MUDBUS库文件

    2024年02月03日
    浏览(37)
  • 编写C#程序实现和西门子1500PLC进行Modbus Tcp通讯仿真

    前言 本文章的主题是介绍Modbus Tcp通讯仿真,其中C#编写的程序充当客户端(Client),西门子1500PLC充当的服务器端(Server),有关Modbus Tcp协议的具体内容在此也不再赘述,大家可以自行阅读官方文档。 注:在实现其基本功能的条件下,本文的代码编写以及软件配置均简化。

    2024年02月11日
    浏览(39)
  • C#与西门子PLC1500的ModbusTcp服务器通信1--项目背景

    最近在一个120万元的项目中,涉及到modbustcp通信,我作为软件总工负责项目的通信程序开发,modbus是一个在工业自动化领域中的通信协议,可以是modbusrtu,modbusascii,modbustcp三个形式,具体来说是三个不同的数据包结构,具体的细节请读者自行熟悉,这里只讲项目中应用过程

    2024年02月12日
    浏览(29)
  • C#与西门子PLC1500的ModbusTcp服务器通信2--ModbusTcp协议

    Modbus TCP是近年来越来越流行的工业控制系统通信协议之一,与其他通信协议相比,Modbus TCP通信速度快、可靠性高、兼容性强、适用于模拟或数字量信号的传输,阅读本文前你必须比较熟悉Modbus协议,了解tcp网络。 Modbus TCP是一种以太网协议,它将Modbus通信协议封装在TCP/IP包内

    2024年02月11日
    浏览(27)
  • C#与西门子PLC1500的ModbusTcp服务器通信3--搭建ModbusTcp服务器

     注意,这个IP地址必须与西门子虚拟网卡的IP地址及虚拟机的网卡IP地址同一网段           找到程序块main,找到右边的指令,找到通信,找到其它,拖到MB_SERVER到程序段1中    重点看mb_hold_reg和connect参数,disconnet为false表示被动连接,意思是说服务器等待客户机来连接,而

    2024年02月11日
    浏览(27)
  • C#与西门子PLC1500的ModbusTcp服务器通信4--搭建ModbusTcp客户端

    客户端可以是一个程序或一个设备,这里我以C#WINFORM程序来实现客户机与PLC的Modbustcp服务器通信,开发环境是VS2019,.NET Framework版本是4.7.2  创建类库   编写C#各种类的转换库,该库由我提供,不用操心,文章最后提供。 项目引入这个类库  找到项目,找到引用,右键“管理

    2024年02月11日
    浏览(27)
  • 西门子plc使用MQTT把数据上传腾讯云端

    使用1500系列的plc仿真接入腾讯云,实现可以上传数据和下放数据,可实现报警微信推送功能,作为笔记在此储存。 1.博图v16 2.S7-PLCSIM Advanced V4.0 3.西门子官方实例库 西门子官方实例库 https://support.industry.siemens.com/cs/document/109748872/use-the-simatic-controller-as-an-mqtt-client?dti=0lc=en-US 注

    2023年04月11日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包