项目需要用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页,可以看出,M30000~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分别表示从站地址和线圈地址,类型分别为byteushortvlaue为布尔型,其值为trueorfalse。给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通信相关推荐

  1. Modbus 协议从站开发通信西门子 PLC

    文章目录 1. Modbus 协议 1.1 传输模式:单工模式.全双工模式.半双工模式 1.2 广播模式.单播模式 1.3 Modbus 通信模式:ASCII.RTU 1.4 基本数据类型 2. 功能 ...

  2. plc通讯的握手信号_基于Modbus协议实现PLC与智能仪表的通讯

    1 引言 Modbus 协议是法国施耐德公司推出的一个全开放的"主从式(Master/Slave)"通讯协议,其本意在于实现上位机(主设备)对PLC(从设备)内部存储区域的&quo ...

  3. C++ modbus TCP 协议跟PLC通信

    modbus 用的是git上的开源代码,地址:https://github.com/stephane/libmodbus 讲一下基本使用(给指定地址发送 on/off命令以及读取): modbus_t ...

  4. 基于.net 基于ModBus协议的PLC设备数据采集(单片机,研华6017设备)

    1.场景 项目上需要对一些工厂设备状态进行实时状态分析,生成折线图并报警等. 设备外面一般都接入了处理模块(单片机,6017等)(相当于网关设备),对信号进行转化,由网线接出,可进行采集. 2.程序 ...

  5. modbus协议使用【android串口通信】

    modbus协议使用[android串口通信] 本文的目的是android端与上位机之间使用modbus协议进行串口通信.通过串口与其他设备进行通信,传递数据.可以理解为电脑和键盘.鼠标通信. 关于m ...

  6. 纸鸢|工业物联网通讯协议Modbus协议详解

    目录 Modbus简介 格式总览 从机地址 功能码和寄存器 PLC地址和Modbus协议地址 功能码总览 异常分析 Modbus简介 Modbus 是一种串行通信协议,是 Modicon 于 1979 ...

  7. C#上位机与台达PLC通信,modbus TCP协议

    C#上位机与台达PLC通信,modbus TCP协议. 1.真实使用项目,该程序框架完整,适合在此基础上开发项目. 2.使用VS2019开发. 3.项目还涉及到halcon视觉检测功能. YID:76 ...

  8. 基于Modbus协议的KingSCADA-IOserver和仿真PLC通信

    1.获取本机和从机IP地址 设本机192.168.1.1 设从机192.168.1.2 cmd命令ping主从机保证网络连通 2.从机运行仿真PLC软件(ModSim32) 寄存器地址(Adderss ...

  9. 基于MODBUS协议的单片机与(串口屏)触摸屏通信(图文)

    基于MODBUS协议的单片机与(串口屏)触摸屏通信(图文) 导读:触摸屏能够直观.生动地显示运行参数和运行状态,而且通过触摸屏画面可以直接修改系统运行参数,人机交互性好.触摸屏和单片机通信,需要根据触 ...

最新文章

  1. benet 3.0的windows服务视频 第二章DNS
  2. centos远程开机的操作
  3. (六)jQuery选择器
  4. SharePoint无代码工作流设计开发实例——交通费报销流程(二)
  5. 价值6000的信息分类系统源码
  6. Pytest之基本介绍
  7. 记录WIN10下ISE14.7安装和关联modelsim10.1的安装要点
  8. js结束当前循环关键词_干货||什么是事件循环机制
  9. Javascript特效:不断在页面跑的星星
  10. 什么是句柄/底层绘图函数
  11. 2009年SNS社区源码大集合
  12. linux命令中tar什么意思,Linux中tar命令起什么作用呢?
  13. 滑铁卢计算机竞赛福建考点,数学与计算机竞赛界的“四大天王”,你敢来挑战么?...
  14. 全球芯片短缺可能很快变成供过于求的危机
  15. my.ini文件在哪
  16. 给LINUX安装JDK
  17. 讯搜 配置mysql_迅搜创建数据库索引
  18. 国外能够使用替代Google Map 方案调研
  19. Mac 下显示隐藏文件或文件夹
  20. 五彩斑斓的黑,找到了

热门文章

  1. VC6.0(VC++6.0)使用教程(使用VC6.0编写C语言程序)
  2. 新型能力的分解与组合
  3. Java文档注释【自制API】
  4. feign.codec.DecodeException: Error while extracting response for type
  5. 《今日简史》--意义:人生不是虚构的故事
  6. 1.7.3_NandFlash的芯片id读取_P
  7. 镜头跑焦测试软件,[转载]关于如何测试镜头跑焦及测试卡制作
  8. 三极管/达林顿管 管脚定义
  9. 面试:如何用最少的老鼠试出有毒的牛奶?
  10. thinkphp5.1和5.0下的中文分词