C#实现Modbus协议与PLC通信 |
您所在的位置:网站首页 › 台达plc › 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加载器量程D422PLC数字量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。 下载后,在相应的处理业务的类中定义成员变量 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函数如下。 翻译自 DELTA DVP系列PLC官方文档 通信数据框架(Communication Data Frame)如下: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |