C#实现Modbus协议与PLC通信
项目需要用C#写一个上位机,用Modbus/TCP协议与PLC通信,控制伺服电机的启停、转速等。D:\Code\C#\ConsoleApp1
1. 获取PLC的IP地址
待续。。。
2.
“启动”的代码如下,btn_stop_Click 是“启动”这个按钮对应的响应函数,启动一个新线程,实际的代码在StopEnginer
函数中实现
private void btn_stop_Click(object sender, EventArgs e) //控制电机停止{r_timer.Stop();t_timer.Stop();Thread t = new Thread(StopEnginer) { IsBackground = true };t.Start();}
private void StopEnginer(){string cmd_str = "0105081E0000";//01从站地址salve address//05功能码 写入单个线圈函数WriteSingleCoil(开源通讯库Nmodbus)//Nmodbus 地址https://github.com/NModbus/NModbus//081E是写入单个线圈地址,参考台达PLC应用手册161页DVP装置通讯地址和x工给的excel表//081E = M30是控制启停的地址//0000后四位是写入的值// string cmd_str = (tbx_cmdString.Text).ToUpper();ushort[] returnValues = new ushort[30];//将字符串cmd_str切割成地址、功能码、写入地址、写入值byte address = Convert.ToByte(cmd_str.Substring(0, 2), 16);byte Function = Convert.ToByte(cmd_str.Substring(2, 2), 16);ushort start = Convert.ToUInt16(cmd_str.Substring(4, 4), 16);ushort values = Convert.ToUInt16(cmd_str.Substring(8, 4), 16);Console.WriteLine("这是故障台停止程调用");try{bool value_TrueOrFalse = Convert.ToUInt16(values) == 0xFF00;//调用WriteSingleCoil函数master.WriteSingleCoil(address, start, value_TrueOrFalse);}catch (Exception ex){MessageBox.Show(ex.ToString());}}
代码解释如下,需要Modbus协议、PLC通信协议的相关知识,以及PLC地址表。项目用的PLC型号为台达DELTA DVP系列
1. PLC地址表
名称 | 对应的台达DVP系列PLC地址 |
---|---|
转速设定 | D520 |
扭矩设定 | D502 |
实时转速 | D46 |
实时扭矩 | D26 |
启停 | M30 |
扭力计量程 | D410 |
转速量程 | D414 |
加载器量程 | D422 |
PLC数字量 | D418 |
转速系数 | D426 |
伺服加速时间 | D504 |
伺服减速时间 | D506 |
加减速系数 | D508 |
其中,控制电机启停的PLC地址是M30。台达DVP系列PLC中,S, X, D, M等表示PLC装置(应该与PLC内部结构有关??分别代表不同的线圈区域?不是很确定),总之知道地址M30就OK了。
现在去查M30对应的十六进制编码地址是多少,因为用C给PLC发送信号时,需要以十六进制数形式发送。下表来自台达PLC应用手册(厚达743页)中的第161页,可以看出,M30
在000~255
这一区域,该区域的编码以十六进制08开头,进一步,30
的十六进制为1e
,所以,PLC地址M30的十六进制地址是0x081e
,其中0x
表示十六进制。类似的,256~511
这一区域的地址,其编码以十六进制09开头,256~511分别对应0x00 ~ 0xFF。例如,M267,它的十六进制地址计算方式为 :267-256=11,11的十六进制为0b
,因此M267的十六进制地址为0x090b
。
本项目PLC与上位机的通讯用到了一个开源通讯库NModbus
,下载地址https://github.com/NModbus/NModbus。该通信库官方提供的手册NModbus
在VS2017中,可以通过以下方式下载安装:
下载后,在相应的处理业务的类中定义成员变量
private NModbus.IModbusMaster master;
建立连接,用NModbus.ModbusFactory.CreateMaster
创建主站,返回IModbusMaster
类对象,对PLC地址的读写主要通过该类提供的方法实现
public bool connect(string ip,int port){if (hasConnected) return true;var tcp=new TcpClient();var result=tcp.BeginConnect(ip,port,null,null);result.AsyncWaitHandle.WaitOne(5000);if (result.IsCompleted){var factory = new NModbus.ModbusFactory();master = factory.CreateMaster(tcp);hasConnected = true;}else{throw new TimeoutException("连接超时!");}return hasConnected;}
之后,调用IModbusMaster
的成员函数就可以通信了,可以看到IModbusMaster
的部分常用API函数如下。
本例中,将使用WriteSingleCoil
函数往M30地址中写入数据,控制电机的启动和停止。WriteSingleCoil
的函数原型为void WriteSingleCoil(byte slaveAddress, ushort coilAddress, bool value);
,三个参数,slaveAddress,coilAddress分别表示从站地址和线圈地址,类型分别为byte
和ushort
,vlaue
为布尔型,其值为true
orfalse
。给PLC的M30地址发送信号启动电机的代码如下。
public void start() //给PLC的M30地址发送信号启动电机{check();byte slaveAddress = 1; //单元标识符ushort coilAddress = 0x81e; //起始地址bool value = true;master.WriteSingleCoil(slaveAddress, coilAddress, value);// void WriteSingleCoil(byte slaveAddress, ushort coilAddress, bool value);函数原型}
2. DELTA DVP系列PLC通信协议详解
翻译自 DELTA DVP系列PLC官方文档
通信数据框架(Communication Data Frame)如下:
解释如下:
- STX:起始字符,为 “:”
- ADR1 和 ADR0: 通信地址,由2个ASCII码组成,有效的通信地址范围为0…31。
- CMD1和CMD0:命令码,由2个ASCII码组成,用来告诉PLC该执行什么任务。该系列PLC的命令码取了Modbus协议的部分功能码,Modbus协议如下表所示。完整的Modbus协议见xxxx。表中的Description 是PLC对应的部件
Code | Name | Translation | Function | Description |
---|---|---|---|---|
01 | Read Coil Status | 读取线圈状态 | 取得一组逻辑线圈的当前状态(on/off) | S, Y, M, T, C |
02 | Read Input Status | 读取输入状态 | 取得一组开关输入的当前状态(on/off) | S,X,Y,M,T,C |
03 | Read Holding Registers | 读取保持寄存器 | 在一个或多个保持寄存器中取得当前的二进制值 | T,C,D |
05 | Force Single Coil | 强制单线圈 | 强制一个逻辑线圈的通断状态 | S,Y,M,T,C |
06 | Preset Signle Register | 预置单寄存器 | 把具体二进制装入一个保持器 | T,C,D |
15 | Force Multiple Coils | 强置多线圈 | 强置一串连续逻辑线圈的通断 | S,Y,M,T,C |
16 | Preset Multiple Register | 预置多寄存器 | 把具体的二进制值装入一串连续的保持 | T,C,D |
17 | Report Slave ID | None |
- DATA(0)~DATA(n-1): 所要发送的数据内容,DATA字符的格式取决于功能码。数据的内容包括n个8位数据,由2n个ASCII码组成(一个8-bit的数据由2个ASCII码表示),n<=37,因此DATA最大可包含74个ASCII码
例子
:Reading Coils T20~T27 from slave device 01,从从站设备地址01开始读取线圈T20-T27中的内容,一共8个字节(8 words)
PC发给PLC的代码
PC→PLC “:01 03 06 14 00 08 DA CR LF”
代码解析如下:
Field Name | Example(Hex) |
---|---|
Heading | 3A |
Slave Address | 01 |
Command code | 03 |
Starting Address Hi | 06 |
Starting Address Lo | 14 |
Number of Points Hi | 00 |
Number of points Lo | 08 |
Error Check (LRC) | DA |
End character 1 | CR |
End character 2 | LF |
PLC发送给PC的代码:
:01 03 10 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 B8 CR LF
代码解析如下:
Field Name | Example(Hex) |
---|---|
Slave Address | 01 |
Command code | 03 |
Bytes Count | 10 |
Data Hi(T20) | 00 |
Data Lo (T20) | 01 |
Data Hi (T21) | 00 |
Data Lo (T21) | 02 |
Data Hi (T22) | 00 |
Data Lo (T22) | 03 |
Data Hi (T23) | 00 |
Data Lo (T23) | 04 |
Data Hi (T24) | 00 |
Data Lo (T24) | 05 |
Data Hi (T25) | 00 |
Data Lo (T25) | 06 |
Data Hi (T26) | 00 |
Data Lo (T26) | 07 |
Data Hi (T27) | 00 |
Data Lo (T27) | 08 |
Error Check (LRC) | C8 |
LRC(Longitudinal Redundancy Check)纵向冗余度检查,
DELTA DVP系列的PLC的设备地址
C#实现Modbus协议与PLC通信相关推荐
- Modbus 协议从站开发通信西门子 PLC
文章目录 1. Modbus 协议 1.1 传输模式:单工模式.全双工模式.半双工模式 1.2 广播模式.单播模式 1.3 Modbus 通信模式:ASCII.RTU 1.4 基本数据类型 2. 功能 ...
- plc通讯的握手信号_基于Modbus协议实现PLC与智能仪表的通讯
1 引言 Modbus 协议是法国施耐德公司推出的一个全开放的"主从式(Master/Slave)"通讯协议,其本意在于实现上位机(主设备)对PLC(从设备)内部存储区域的&quo ...
- C++ modbus TCP 协议跟PLC通信
modbus 用的是git上的开源代码,地址:https://github.com/stephane/libmodbus 讲一下基本使用(给指定地址发送 on/off命令以及读取): modbus_t ...
- 基于.net 基于ModBus协议的PLC设备数据采集(单片机,研华6017设备)
1.场景 项目上需要对一些工厂设备状态进行实时状态分析,生成折线图并报警等. 设备外面一般都接入了处理模块(单片机,6017等)(相当于网关设备),对信号进行转化,由网线接出,可进行采集. 2.程序 ...
- modbus协议使用【android串口通信】
modbus协议使用[android串口通信] 本文的目的是android端与上位机之间使用modbus协议进行串口通信.通过串口与其他设备进行通信,传递数据.可以理解为电脑和键盘.鼠标通信. 关于m ...
- 纸鸢|工业物联网通讯协议Modbus协议详解
目录 Modbus简介 格式总览 从机地址 功能码和寄存器 PLC地址和Modbus协议地址 功能码总览 异常分析 Modbus简介 Modbus 是一种串行通信协议,是 Modicon 于 1979 ...
- C#上位机与台达PLC通信,modbus TCP协议
C#上位机与台达PLC通信,modbus TCP协议. 1.真实使用项目,该程序框架完整,适合在此基础上开发项目. 2.使用VS2019开发. 3.项目还涉及到halcon视觉检测功能. YID:76 ...
- 基于Modbus协议的KingSCADA-IOserver和仿真PLC通信
1.获取本机和从机IP地址 设本机192.168.1.1 设从机192.168.1.2 cmd命令ping主从机保证网络连通 2.从机运行仿真PLC软件(ModSim32) 寄存器地址(Adderss ...
- 基于MODBUS协议的单片机与(串口屏)触摸屏通信(图文)
基于MODBUS协议的单片机与(串口屏)触摸屏通信(图文) 导读:触摸屏能够直观.生动地显示运行参数和运行状态,而且通过触摸屏画面可以直接修改系统运行参数,人机交互性好.触摸屏和单片机通信,需要根据触 ...
最新文章
- benet 3.0的windows服务视频 第二章DNS
- centos远程开机的操作
- (六)jQuery选择器
- SharePoint无代码工作流设计开发实例——交通费报销流程(二)
- 价值6000的信息分类系统源码
- Pytest之基本介绍
- 记录WIN10下ISE14.7安装和关联modelsim10.1的安装要点
- js结束当前循环关键词_干货||什么是事件循环机制
- Javascript特效:不断在页面跑的星星
- 什么是句柄/底层绘图函数
- 2009年SNS社区源码大集合
- linux命令中tar什么意思,Linux中tar命令起什么作用呢?
- 滑铁卢计算机竞赛福建考点,数学与计算机竞赛界的“四大天王”,你敢来挑战么?...
- 全球芯片短缺可能很快变成供过于求的危机
- my.ini文件在哪
- 给LINUX安装JDK
- 讯搜 配置mysql_迅搜创建数据库索引
- 国外能够使用替代Google Map 方案调研
- Mac 下显示隐藏文件或文件夹
- 五彩斑斓的黑,找到了
热门文章
- VC6.0(VC++6.0)使用教程(使用VC6.0编写C语言程序)
- 新型能力的分解与组合
- Java文档注释【自制API】
- feign.codec.DecodeException: Error while extracting response for type
- 《今日简史》--意义:人生不是虚构的故事
- 1.7.3_NandFlash的芯片id读取_P
- 镜头跑焦测试软件,[转载]关于如何测试镜头跑焦及测试卡制作
- 三极管/达林顿管 管脚定义
- 面试:如何用最少的老鼠试出有毒的牛奶?
- thinkphp5.1和5.0下的中文分词