C#--通过Modbus TCP与西门子1200PLC通讯

以下是学习笔记:

学习参考:https://www.bilibili.com/video/BV1LV41127M1?p=5&t=2752

一,回顾:上位机与PLC通信方式

1,S7,

2,ModbusTCP

3,TCP

4,UDP

5,OPC

二,Modbus协议基础知识介绍存储区:

1,输入线圈 0区 --》I点

2,输出线圈 1区--》Q点

3,输入寄存器 3区--》PIW

4,输出寄存器 4区--》DB存储区 ,M区 0=40001  7=40008 起始地址都是从0开始的,

输出寄存器的好处:可读可写,既可以表示布尔,又可以表示寄存器

所以输出寄存器 4区 用的是最多的。

比如:

一个寄存器16个位

40001.0来表示布尔  读取是方便的  但是写入布尔比较麻烦,因为Modbus不支持寄存器布尔量的直接写入

如果要写入布尔量:要先读取再偏移再写入

如果是三菱PLC 比如D0.0 想写入true或false也是比较麻烦的,因为三菱PLC也不支持寄存器布尔

写入bool的方法:一个寄存器代表一个位,变true写1,变flase写0

三,硬件接线和PLC程序编写

1,,硬件接线部分:

 2,在博图中写好PLC程序

3,Modbus地址与PLC地址映射

3.1,布尔量的映射:

 3.2 浮点型的映射

 3.3,这里DB1是跟Modbus通讯的

  例如:下面这个实例有19个寄存器

 4,最后还要写一个PLC作为ModbusTCP服务器的程序:

  这里把DB1开始的38个字节映射PLC中了

 5,

知识:

C#中:

float 单精度浮点 32bit,
double 双精度浮点64bit,
decimal是高精度 128bit,浮点型。
float double 是 基本类型(primitive type),decimal不是。
float 有效数字7位,范围 ±1.5 × 10E−45 to ±3.4 × 10E38
double 有效数字15/16 位,范围 ±5.0 × 10 E−324 to ±1.7 × 10E308
decimal 有效数字 28/29 位,范围 ±1.0 × 10E−28 to ±7.9 × 10E28
( E -- 下接几次方)

decimal的有效位数很大,达到了28位,但是表示的数据范围却比float和double类型小。
使用的时候会对计算时的性能有影响。
常数写法:
float f = 12.3F; (带F)
double x=12.3; (不带就是double)
decimal d = 12.30M; (带M)

一个英文字母,无论大写和小写都是一个字符、一个字节,8位。
一个汉字是一个字符、两个字节,16位

PLC中:

位(bit):是计算机 内部数据 储存的最小单位,11001100是一个八位二进制数。

字节(byte):是计算机中 数据处理 的基本单位,习惯上用大写  B  来表示,1B(byte,字节)= 8bit(位)

字符:是指计算机中使用的字母、数字、字和符号

B是字节(8位)

W是字(16位)

DW是双字(32位)

V是变量存储器

M是内部 存储器

VB代表1个字节,即8位

VD代表4个字节,32位

VW代表2个字节,16位

MB代表内部存储器1个字节,8位

一个浮点数4个字节32位,必须要占用两个连续的寄存器

1个寄存器2个字节

比如:

  读40001浮点数,就是读取40001和40002数据

  读40004浮点数,就是读取40004和40005数据

(1)1个字节=8个位,用B(byte)表示

(2)1个字=16个位,用W(word)表示

(3)1个双字=32个位,用D(double word)表示

(1)DB0.DBX0.0:表示一个位,不是0就是1

(2)DB0.DBB0:字节,里面只能是255以内的正数

(3)DB0.DBW0:字,里面可能是0-65535的正数,也可能是-32767到+32768之间的整数(有正负之分的数)

(4)DB0.DBD0:双字,里面存放的类型比较多,分别是

(a)0-4294967295之间的正数

(b)-2147483648到2147483647的双整数

(c)浮点数,即带小数点的数

先用Modbus Poll来测试下:

 1,连接

 2,设置读取19个寄存器,因为上面设置的PLC就是19个寄存器

 3,这里就能看到PLC的数据了

 4,监控PLC的实际值,跟Modbus Poll读取的值不一样。

 5,修改Modbus Poll-->Display的数据类型就可以

 6,现在就可以调试了,对PLC点位控制

四,C#程序

1,界面

 2,手写ModbusTCP通讯。也可以使用开源库 NModbus4,这里我们使用开源库

工具--》NuGet包管理器--》管理解决方案的NuGet程序包--》浏览--》搜索

 备注:安装好了之后,其实就是一个这样一个dll文件,以后的项目如果没有下载,可以直接用这个NModbus4.dll这文件

 3,连接和断开代码编写:

 4,实时读取PLC浮点型的数据 40008后面的12个寄存器是浮点型的数据

注意参数的地址,是相对地址还是绝对地址。

任意1个区都是从0开始的。0对应的是40001

正常的使用ushort[] res = master,ReadHoldingRegisters(4008,12),

如果是绝对地址就是7,相对地址就是4001+7=4008。

 解析方法:把每两个ushort类型转换成一个float数据

 解析思路:一共是6个数据12个ushort类型,把每两个ushort类型转换成一个float数据。

BitConverter.Tosingle:把字节数组转换float数据。

注意:使用这个方法的时候注意大小端。

 连接成功后开启定时器

5,点动功能:

 6,相对运动,绝对运动,会原点

 7,更改速度,更改浮点型数据

        /// <summary>
        /// float[]转ushort
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        private ushort[] GetUshortArrayFromFloat(float[] val)
        {
            ushort[] uintData = new ushort[val.Length*2];
            Buffer.BlockCopy(val,0,uintData,0,uintData.Length*2);
            return uintData;
        }

  

 8,让小车动起来,其实就是修改控件的Location坐标,Y轴不变,X轴变化

9,效果:

原文地址:https://www.cnblogs.com/baozi789654/p/14050967.html