提供给需要学习的同学,C#读取,写入1200控制西门子V90源代码,博途V13C#源代码VS3...

提供给需要学习的同学,C#读取,写入1200控制西门子V90源代码,博途V13C#源代码VS3... 提供给需要学习的同学C#读取写入1200控制西门子V90源代码博途V13C#源代码VS3013版本可以自己编写多步导入后伺服电机根据编写程序自动运行最近帮实验室刚入坑工控的师弟调V90伺服翻出了当年用VS2013写的旧代码那时候博途V13还是主流电脑还跑不动新版本的VS现在整理出来给大家避避坑省得像我当年一样熬到两点才搞定。首先得先把基础的通信组态弄好不然你C#写得再花里胡哨也连不上PLC。咱用的是S7-1200V90 PROFINET通信步骤其实不复杂但新手很容易在GSD文件这里翻车先去西门子官网搜「SINAMICS V90 PROFINET GSD」下载对应你V90固件版本的安装包导入博途V13的设备目录里不然博途找不到V90这个设备。新建博途项目添加S7-1200 PLC配置好PLC的IP地址比如192.168.0.1。双击PLC的PROFINET接口添加新设备找到刚导入的V90给它分配个IP比如192.168.0.2然后组态PZD就是PLC和伺服之间传的实时数据选标准的2字节控制字4字节转速设定2字节状态字4字节实际转速就行博途会自动给你分配外设IO地址比如%QW100开始是输出给伺服的控制字和转速%IW100开始是伺服反馈的状态字和实际转速这个地址一定要记好后面C#代码里要用。接下来是VS2013的环境搭建咱用的是Sharp7这个库轻量又好用而且兼容VS2013和.NET 4.5刚好适配当年的环境去Sharp7的官网下2.0版本的dll别下最新版不然VS2013认不出。新建VS2013控制台应用项目把Sharp7.dll添加到引用里记得把dll的「复制到输出目录」改成「始终复制」不然运行的时候会报错找不到文件。先写个最基础的连接PLC的代码using S7; using System; namespace SiemensV90Control { class Program { static void Main(string[] args) { // 初始化S7客户端参数依次是PLCIP、机架号、槽号 // S7-1200机架号固定0槽号我当年试了1才连上不行就换2试试 S7Client client new S7Client(); int connectStatus client.ConnectTo(192.168.0.1, 0, 1); if (connectStatus ! 0) { Console.WriteLine($连不上PLC啊喂{client.ErrorText(connectStatus)}); return; } Console.WriteLine(PLC连接成功); } } }这段代码里的ConnectTo三个参数第一个是你PLC的IP第二个机架号都是0第三个槽号是坑点我当年换了三次才试对别直接抄别人的不行就1和2来回试。提供给需要学习的同学C#读取写入1200控制西门子V90源代码博途V13C#源代码VS3013版本可以自己编写多步导入后伺服电机根据编写程序自动运行连上线之后就可以读写数据了咱要给伺服发控制字和转速还要读状态和实际转速这里要注意咱操作的是PLC的外设IO不是DB块所以别用DBWrite要用WriteArea当年我就是在这里卡了好久。比如咱要往%QW100控制字和%QW102转速设定写数据代码大概是这样// 控制字0x047E是准备好伺服0x047F是启动具体看V90手册别硬抄 ushort controlWord 0x047E; float setSpeed 1000.0f; // 设定1000转每分钟 // 把控制字和转速转成字节数组 byte[] ctrlBytes BitConverter.GetBytes(controlWord); byte[] speedBytes BitConverter.GetBytes(setSpeed); // 合并成连续的字节从%QW100开始一共6个字节24 byte[] sendData new byte[6]; Array.Copy(ctrlBytes, 0, sendData, 0, 2); Array.Copy(speedBytes, 0, sendData, 2, 4); // 往PLC的外设输出区写数据参数依次是外设输出区、0、起始地址、长度、数据 int writeStatus client.WriteArea(S7Consts.S7AreaPA, 0, 100, 6, sendData); if (writeStatus ! 0) { Console.WriteLine($写失败了{client.ErrorText(writeStatus)}); } else { Console.WriteLine($已发送控制字{controlWord:X4}设定转速{setSpeed} rpm); }这里解释一下S7AreaPA是过程输出区也就是PLC发给外设的信号S7AreaPE是过程输入区用来读伺服反馈的数据比如读状态字和实际转速的话就用ReadArea// 读外设输入区从%IW100开始6个字节状态字2实际转速4 byte[] recvData new byte[6]; int readStatus client.ReadArea(S7Consts.S7AreaPE, 0, 100, 6, recvData); if (readStatus ! 0) { Console.WriteLine($读失败了{client.ErrorText(readStatus)}); } else { ushort statusWord BitConverter.ToUInt16(recvData, 0); float actualSpeed BitConverter.ToSingle(recvData, 2); Console.WriteLine($当前状态字{statusWord:X4}实际转速{actualSpeed:F2} rpm); }接下来就是你要的多步自动运行了伺服不是直接发个启动命令就转的得按状态机来走先准备伺服等伺服反馈使能成功再启动再设定转速。咱写个循环来实现bool isServoRunning false; while (true) { // 先读状态字看伺服当前的状态 byte[] statusBytes new byte[2]; client.ReadArea(S7Consts.S7AreaPE, 0, 100, 2, statusBytes); ushort status BitConverter.ToUInt16(statusBytes, 0); if (!isServoRunning) { // 第一步发送准备命令 ushort prepareCtrl 0x047E; byte[] prepareData BitConverter.GetBytes(prepareCtrl); client.WriteArea(S7Consts.S7AreaPA, 0, 100, 2, prepareData); Console.WriteLine(正在准备伺服...); // 等状态字的使能位bit3为1也就是伺服准备好了 if ((status 0x0008) ! 0) { // 第二步发送启动命令 ushort startCtrl 0x047F; byte[] startData BitConverter.GetBytes(startCtrl); client.WriteArea(S7Consts.S7AreaPA, 0, 100, 2, startData); // 第三步发送设定转速 float speed 1500.0f; byte[] speedData BitConverter.GetBytes(speed); client.WriteArea(S7Consts.S7AreaPA, 0, 102, 4, speedData); isServoRunning true; Console.WriteLine(伺服启动成功开始运转啦); } } else { // 运行中每秒刷新一次实际转速 byte[] speedBytes new byte[4]; client.ReadArea(S7Consts.S7AreaPE, 0, 104, 4, speedBytes); float actual BitConverter.ToSingle(speedBytes, 0); Console.WriteLine($当前实际转速{actual:F2} rpm); System.Threading.Thread.Sleep(1000); } }这里要注意状态字的位定义一定要看V90的手册我这里用的bit3是使能位不同固件版本可能有点不一样别直接抄不然会一直判断失败。最后给大家提几个我当年踩过的坑Sharp7的版本一定要选2.0新版本用了C#6的语法VS2013跑不起来PLC的102端口一定要开放防火墙别挡着不然连不上GSD文件版本要和V90的固件版本对应不然博途组态不上槽号别直接抄1和2都试试我当年就是槽号错了连了半小时控制字和状态字别硬抄一定要看V90的参数手册每个版本的V90可能有点不一样。要是运行的时候伺服不转先去博途里在线诊断看V90的报警比如F7400是电机过载A07400是电源没接好比瞎改代码有用多了。