当前位置: 首页 > web >正文

C#与西门子PLC通信:S7NetPlus和HslCommunication使用指南

西门子S7协议是用来和PLC进行通讯的一个协议,默认端口是102,数据会保存在一个个DB块中,比较经典的用法是一个DB块专门用来读取,一个用来写入。

DB(数据块)+ {块号}.DBX/DBD/DBW+{字节地址}.{位偏移}

1、数据块是存放全局变量的内存区域,类似数据库的表.

2、三种类型的字节地址是共用的,所以要特别注意不同数据类型占用的长度是不同的,否则会出现异常数据的情形。

提到字节排列就得提到不同的通信设备的排列方式是有区别的,像是C#,三菱PLC就是小端排列类似于ABCD,4个字母表示4个字节;西门子PLC是大端排列,顺序是DCBA,modbus等协议是不规则排列,顺序有BADC,CDAB。

DBX(data block bit) 按位访问,用于访问数据块中的单个位即Bool类型,例如: DB1.DBX0.1 表示数据块1的第0字节的第0位。

每个字节有8位,所以偏移量的范围是0~7.

DBW(Data Block Word)数据块字,用于访问16位的数据,例如:Word,int类型。由于1个字 = 16位也就是2个字节,所以地址必须是偶数,无需使用位偏移

例如:DB1.DBW0表示数据块1的第0个字节开始的16位数据

DBD(data block double word)数据块双字,用于访问32位的数据,例如:DWord,Dint,Real类型。由于1个双字 = 32位也就是4个字节,所以地址必须是4的整数,无需使用位偏移

例如:DB1.DBD0表示数据块1的第0个字节开始的32位数据

使用C#实现西门子S7通讯可以通过S7NetPlus,HslCommunication类库来实现

1、使用S7NetPlus实现读写数据

    // 第一个参数是CPU的型号// 第三个参数是PLC的机架(Rank)// 第四个参数是CPU的插槽(Slot)using (var plc = new Plc(CpuType.S71200, "127.0.0.1", 0, 1)){try{plc.Open();if (plc.IsConnected == false){this.textBox1.Text = this.textBox1 + "连接失败" + Environment.NewLine;}#region 写入数据// 写入一个bool类型plc.Write("DB1.DBX0.0", true);// 写入一个无符号整数ushort ushortValue = 3600;plc.Write("DB1.DBW2.0", ushortValue);// 写入一个浮点数float floatValue = 3.14f;plc.Write("DB1.DBD4", floatValue);// 写入一个有符号整数int intValue = 2025;plc.Write("DB1.DBD8", intValue);#endregion#region 读取数据// 读取一个bool类型var is_am = (bool)plc.Read("DB1.DBX0.0");this.textBox1.Text = this.textBox1.Text + "is_am=" + is_am + Environment.NewLine;// 读取一个无符号的整数类型 - word 对应c#的就是ushort类型var second = (ushort)plc.Read("DB1.DBW2.0");this.textBox1.Text = this.textBox1.Text + "second=" + second + Environment.NewLine;// 读取一个浮点数var pie = ((uint)plc.Read("DB1.DBD4")).ConvertToFloat();this.textBox1.Text = this.textBox1.Text + "pie=" + pie + Environment.NewLine;// 读取一个有符号的整数var year = ((uint)plc.Read("DB1.DBD8")).ConvertToInt();this.textBox1.Text = this.textBox1.Text + "year=" + year + Environment.NewLine;#endregion}catch (Exception ex){this.textBox1.Text = this.textBox1 + ex.Message + Environment.NewLine;}}

2、使用HslCommunication实现读写功能

写入:

        plc = new SiemensS7Net(SiemensPLCS.S1200, "127.0.0.1");Random random = new Random();var flag = await plc.WriteAsync("DB1.DBX0", random.Next(0, 2) == 0 ? false : true);var int_value = await plc.WriteAsync("DB1.DBW2", (short)random.Next(0, 1000));var float_value = await plc.WriteAsync("DB1.DBD4", (float)random.Next(0, 10) / 10.0f);// 中文不能使用默认的Ascii编码,需要使用UTF8编码var arr = new string[3] { "中", "美", "日" };var string_value = await plc.WriteAsync("DB1.DBD8", arr[random.Next(0, 3)], Encoding.UTF8);await Task.Delay(1000, cts.Token);if (int_value.IsSuccess == false){this.Invoke(new Action(() => {this.textBox1.Text = "通讯失败" + Environment.NewLine + this.textBox1.Text;}));continue;}

读取:

    plc = new SiemensS7Net(SiemensPLCS.S1200, "127.0.0.1");var flag = await plc.ReadBoolAsync("DB1.DBX0");var int_value = await plc.ReadInt16Async("DB1.DBW2");var float_value = await plc.ReadFloatAsync("DB1.DBD4");// 读取中文不能使用默认的Ascii编码,需要使用UTF8编码var string_value = await plc.ReadStringAsync("DB1.DBD8", Encoding.UTF8);await Task.Delay(1000, cts.Token);if (int_value.IsSuccess == false){this.Invoke(new Action(() => {this.textBox1.Text = "通讯失败" + Environment.NewLine + this.textBox1.Text;}));continue;}this.Invoke(new Action(() =>{this.textBox1.Text = "flag:" + flag.Content.ToString() + Environment.NewLine + this.textBox1.Text;this.textBox1.Text = "float_value:" + float_value.Content.ToString() + Environment.NewLine + this.textBox1.Text;this.textBox1.Text = "int_value:" + int_value.Content.ToString() + Environment.NewLine + this.textBox1.Text;this.textBox1.Text = "string_value:" + string_value.Content.ToString() + Environment.NewLine + this.textBox1.Text;}));
http://www.xdnf.cn/news/3877.html

相关文章:

  • JavaWeb:SpringBootWeb快速入门
  • 五、shell脚本--函数与脚本结构:搭积木,让脚本更有条理
  • JavaScript 中的 Proxy 与 Reflect 教程
  • 比特、字节与布尔逻辑:计算机数据存储与逻辑运算的底层基石
  • PMP-第四章 项目整合管理(一)
  • 享元模式(Flyweight Pattern)
  • MOS管极间电容参数学习
  • spring中的@ComponentScan注解详解
  • stm32week14
  • 主机电路安全防护系统哪个厂家做
  • 招聘绩效效果评估方案与优化路径
  • 35、C# 中的反射(Reflection)
  • 深入理解 Spring MVC:DispatcherServlet 与视图解析机制​
  • 快速弄懂POM设计模式
  • 1991年-2023年 上市公司-重污染企业数据 -社科数据
  • GitHub 趋势日报 (2025年05月03日)
  • 多模态大语言模型arxiv论文略读(五十九)
  • STM32教程:ADC原理及程序(基于STM32F103C8T6最小系统板标准库开发)*详细教程*
  • 数电填空题整理(适用期末考试)
  • Linux网络编程:套接字
  • C++类_匿名类
  • 从入门到登峰-嵌入式Tracker定位算法全景之旅 Part 2 |蜂窝 LBS on Tracker:从 AT 命令到定位结果
  • 今天python练习题
  • MYSQL-联合查询
  • 【前端】【总复习】HTML
  • 基于 ESP32 和 GC9D01 0.71寸TFT屏幕的逼真眼睛与写轮眼动态显示
  • Spring Boot Jpa封装快速构建Specification、OrderBy、Pageable的查询条件
  • 【Python】一直没搞懂生成器是什么。。
  • 【25软考网工】第五章(5)ICMP和ICMPv6、NDP、IP组播技术和MPLS
  • JavaScript基础-分支流程控制