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

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

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

c# s7,西门子PLC,C#上位机,c#,visualstudio
拉了换一个简单的界面

PLC端设置

c# s7,西门子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库引用

c# s7,西门子PLC,C#上位机,c#,visualstudio
1、右键项目名,选择图中【管理NuGet程序包】
c# s7,西门子PLC,C#上位机,c#,visualstudio2、在搜索框输入【S7netplus】,我安装的是第一个。
c# s7,西门子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-524691.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#通过S7.NET库与西门子PLC数据交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • C++上位软件通过LibModbus开源库和西门子S7-1200/S7-1500/S7-200 PLC进行ModbusTcp 和ModbusRTU 通信

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

    2024年02月03日
    浏览(37)
  • PLC实验—西门子S7 1200读取旋转编码器数据并计算电机转速

    注意PTO控制步进电机实验博途软件需要V14版本,不然没有PTO功能块 软件的下载请点击下方百度网盘的链接 链接:https://pan.baidu.com/s/11mQFVnaQxrUy4W9nGIk8Jw 提取码:6lva 详细的操作指导视频已经放到了B站上 Simens S7-1200读取增量式编码器数据 Simens S7-1200根据编码器数据计算电机转速

    2024年02月05日
    浏览(42)
  • 西门子PLC S7-1500系列CPU与西门子PLC S7-300系列的通讯模块CP343-1进行TCP通讯的方法

    西门子PLC S7-1500系列是西门子新一代PLC产品,它通过多方面的创新,为用户提供了更高性价比的产品,提高了用户的工程实施效率。西门子PLC S7-1500为用户在自动化控制系统中提供了更高的运行能力,而且简单易用,节省了大量的系统开发时间,西门子PLC S7-1500系列有很强的通

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

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

    2024年02月09日
    浏览(49)
  • 西门子PLC S7-1200如何实现远程上下载?

    西门子S7-1200是一款高性能的PLC,具有模块化、结构紧凑、功能全面、编程简单的特点,总工业自动化领域中应用广泛,如贴片系统、传送带系统、污水处理厂、配电站、能源管理系统。 在使用过程,无论是为了减少现场调试的成本时间,还是为了给客户提高更快更强的技术

    2024年02月12日
    浏览(36)
  • 西门子S7-1200与S7-300PLC的九大不同点

    S7-1200作为新推出的紧凑型控制器,其产品定位在原有的SIMATIC S7-200和S7-300之间,它与S7-300的区别主要体现在硬件、通信、工程、存储器、功能块、计数器、定时器、工艺功能等方面。 一、硬件的区别 在硬件扩展方面,S7-300的主机架多支持八个扩展模块,而S7-1200支持扩展多八

    2024年01月25日
    浏览(32)
  • python通过S7协议读取西门子200smart数据

    发现网上很多关于python通过s7协议控制200smart的代码都失败,我猜应该是版本的问题。自己捣鼓了半天,终于测试成功   写PLC 写PLC用到的方法为 write_area(area,dbnumber,start,data) 说明如下:area表示往哪个区去写,如:plc.write_area(client.Areas.DB,1,2,bytes)                 dbnumber:如果是

    2024年01月25日
    浏览(26)
  • 西门子PLC S7-1200程序实例,西门子1200与安川机器人TCP IP通讯

    西门子PLC S7-1200程序实例,博图版本V15 1,西门子1200与安川机器人TCP IP通讯,包含机器人GSD文件; 2,西门子1200控制6轴伺服电机,四台台脉冲控制台达B2伺服,两台PN通讯控制西门子V90伺服电机; 3,两台西门子1200开放式通讯交互数据联动; 4,与4台位移传感器modbus485轮询读取

    2024年04月10日
    浏览(34)
  • 两个西门子S7-1200PLC之间的TCP以太网通讯

    两个西门子S7-1200PLC之间的TCP以太网通讯 西门子S7_1200两个CPU之间的以太网通讯程序,一个做主站一个做从站,可实现两个CPU之间的数据发送和读取,外加两个西门子KTP1200 12寸的触摸屏, 两个西门子S7-1200 PLC之间的TCP以太网通讯 随着工业自动化的发展,越来越多的设备之间需

    2024年02月02日
    浏览(33)
  • C#S7.NET实现西门子PLCDB块数据采集的完整步骤

    前言 本文介绍了如何使用S7.NET库实现对西门子PLC DB块数据的读写,记录了使用计算机仿真,模拟PLC,自至完成测试的详细流程,并重点介绍了在这个过程中的易错点,供参考。   用到的软件: 1.Windows环境下链路层网络访问的行业标准工具(WinPcap_4_1_3.exe)下载链接:https:/

    2024年04月23日
    浏览(21)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包