精华内容
下载资源
问答
  • C#PLC modbus WPF 换热站组态演示

    热门讨论 2013-03-20 18:45:43
    C#PLC modbus WPF 换热站组态演示
  • C# PLC与网口通讯

    2019-04-03 11:41:57
    C#程序 主要是用于 PLC与网口通讯,可进行写入,和读取PLC寄存器值,需安装MX Component软件
  • C#PLC采集.rar

    2020-12-02 13:34:52
    winform直接采集PLC数据并存入数据库
  • C# PLC控制界面

    2013-12-03 15:03:16
    C#编写的PLC界面,包括操作界面,使用功能等等,可供参考编写PLC与工控机连接控制界面
  • c# PLC控制警灯

    2010-03-19 13:07:29
    c# 写的控制PLC plc采用mobuls协议, 发送16进制代码,
  • 3,跟PLC通讯方面,checksoft作为伺服器,PLC作为客服端,我们便让checksoft 不断读取PLC某一软原件(备注:软元件相当于一个变量16BIT 或者32bit,这里是16bit的某一位,如MR402),当该位变成true,则置位标志...
  • <p>PLC坐主站,上位机是从站,上位机和云服务器连接,云服务器上能正常接受到PLC发来的指令,但是从云服务器往从站该怎么发? 我就想知道modbus主站发来的指令存放在什么地方,...
  • C#PLC对接(涵盖各厂区)

    千次阅读 2019-10-16 15:10:23
  • PLC软件每天大概处理50万笔数据,请问各位大神对于这么大的数据有什么样的解决方案
  • C#倍福PLC.zip

    2020-07-30 23:15:37
    C#读写倍福PLC.C#读写倍福PLC.C#读写倍福PLC.C#读写倍福PLC.C#读写倍福PLC.C#读写倍福PLC.
  • C# 链接PLC

    2018-10-07 16:16:47
    通过C# 的WPF链接PLC,并且能够正常收发数据,主要是链接三菱PLC的MX
  • APP S7 PLC C# Siemens PLC Communication Driver APP S7 PLC C# Siemens PLC Communication Driver APP S7 PLC C# Siemens PLC Communication Driver
  • C#PLC通信

    2018-10-11 08:31:18
    可以正常用(C#写的欧姆龙PLC通讯程序)
  • C# 西门子PLC DLL

    2018-01-10 12:59:52
    C#,c++ 第三方DLL 实现西门子PLC 连接、采集DLL,通过IP、端口、DB块,读写西门子PLC
  • C#PLC通讯Demo

    2020-06-09 09:39:24
    C#PLC通讯实现Demo和源代码,其中包括1个原生Demo和1个读取PLC数据的可视化程序(含源代码)。绝对能用!
  • c#PLC的交互代码

    2018-11-04 12:33:36
    c#PLC的交互代码
  • C#三菱PLC操作类

    2020-10-06 13:30:42
    MC协议操作三菱PLC类,MC协议的目的是开放PLC内部寄存器给外部设备,实现外部设备和PLC的数据交互。简单说就是允许外部设备通过MC协议来读/写PLC里面的寄存器.
  • C#欧姆龙PLC_COM实例

    2021-02-20 17:44:25
    C#通过串口读取欧姆龙plc内存。实现上位机操控plc。制作APP安全性稳定性高于组态跟触摸屏。适合自动化开发。
  • c# 操作plc

    2012-06-28 14:51:00
    說明:使用c#程式,通過串口操作plc,在此例子中,使用西門子的plc,程式是winform。 1.引用AxInterop.MSCommLib控件,操作串口,此控件需要註冊。 2.設置AxInterop.MSCommLib控件的參數: commport:1 端口號 ...

    說明:使用c#程式,通過串口操作plc,在此例子中,使用西門子的plc,程式是winform。

    1.引用AxInterop.MSCommLib控件,操作串口,此控件需要註冊。

    2.設置AxInterop.MSCommLib控件的參數:

    commport:1 端口號 sttting:9600,e,7,2波特率等   inbuffersize:1024 緩存大小

    3.由於直接採用和plc通信,中間沒有採用通信模塊,直接用rs232接口,因此需要循環讀取串口的數據。

    如果使用一個通信模塊,那麼plc可以主動發送數據,並且可以直接用字符串進行通信。自定義通信規則,在plc

    那邊進行解析,然後處理。

    4.通信之前要打開串口:

            isSerialPort = System.Configuration.ConfigurationSettings.AppSettings["isSerialPort"].ToString();
                if (isSerialPort != "0") {
                    this.axMSCommTeco.PortOpen = true;
                }

    5.開啟一個線程,讀取plc中的數據。讀取plc的數據,其實,就是發一個命令,然後,一直讀取串口,等待plc數據返回此地址的數據。

           private void GetData() {
    
               while (true)
               {
                   axMSCommTeco.Output = SendmessageReadplcNumber;
                   if (IsDataComplete())
                   {
                       updateText("1");
                   }
                   System.Threading.Thread.Sleep(iTimeout);
                   IsCountion = false;
                   if (IsStop) {
                       break;
                   }
               }
           }

    6.給plc發送數據:

    axMSCommTeco.Output = SendmessageReadplcNumber;

    SendmessageReadplcNumber是要發送的字符串,發送之前要進行編碼。

    7.寫plc地址:

            public static string WriteAddrData(string Sadd, string Dadd, string Sdadd)
            {
    
                string strReturn = "@" + Sadd + "WD" + Dadd + Sdadd;
                return strReturn + FCS(strReturn) + "*\r\n";
            }

    8.讀取plc地址的數據

            public static   string ReadAddrData(string Sadd, string Dadd, string Sdadd)
            {
    
                string strReturn = "@" + Sadd + "RD" + Dadd + Sdadd;
                return strReturn + FCS(strReturn) + "*\r\n";
            }

    9.數據校驗

              private static  string FCS(String Value)
              {
                  int i, f;
                  byte[] x;
                  f = 0;
                  for (i = 0; i < Value.Length; i++)
                  {
                      x = ASCIIEncoding.ASCII.GetBytes(Value.Substring(i, 1));
                      f = f ^ (int)x[0];
                  }
    
                  return f.ToString("X");
              }

    10.代碼使用寫串口數據

                   string message = TecoPlc.WriteAddrData("00", "0316", EfficiencySops.Target.ToString("X").PadLeft(4,'0'));//標準工時
                 axMSCommTeco.Output = message;

    給地址316,寫入數據,數據 要求 4位,不夠位數補o。

    11.讀取地址上的數據

       message = TecoPlc.ReadAddrData("00", "0010", "0001");
                       System.Threading.Thread.Sleep(1000);
                       axMSCommTeco.Output = message;

    先發送讀取命令,然後 循環讀取串口數據。

           private string DataComplete()
           {
    
               string message = "";
               while (true)
               {
    
                   message += TypeUtil.toString(axMSCommTeco.Input);
                   if (message.Length > 2 && message.Substring(message.Length - 1, 1) == "\r")
                   {
    
                       break;
                   }
                   if (IsStop) {
                       break;
                   }
    
               }
               return message;
           }

    要注意,在發送命令后,要停止一段時間,如果連續發送 ,會達不到你要求的效果。我這裡設置每一條命令發送完成后,停止

     System.Threading.Thread.Sleep(1000);

    12.程式停止,不要關閉串口,除非關閉此窗口,才關閉串口。

     

     

    转载于:https://www.cnblogs.com/Teco/archive/2012/06/28/2567603.html

    展开全文
  • c#三菱plc通讯demo

    2018-09-14 01:01:41
    c#开发的一个与三菱plc型号fx3u通讯的一个demo,网口通讯,支持多连接。
  • C#PLC通讯.rar

    2019-08-31 17:40:04
    C#与三菱、松下PLC串口通讯实例经过测试了。能够读取写入PLC各种类型的寄存器和IO
  • C#PLC通讯

    2021-02-02 11:39:03
    最近因为工作的原因用到了西门子PLC,在使用过程中一直在思考上位机和PLC的通讯问题,后来上网查了一下,找到了一个专门针对S7开发的一个.net库–《S7netPlus》,PLC通讯方法比较多,所以也是在不断地学习中,以下...

    最近因为工作的原因用到了西门子PLC,在使用过程中一直在思考上位机和PLC的通讯问题,后来上网查了一下,找到了一个专门针对S7开发的一个.net库–《S7netPlus》,PLC通讯方法比较多,所以也是在不断地学习中,以下内容如有不足之处,望大神予以指教。

    公司设备一直都用的PLC做下端设备的控制,但是目前都没有专职做上位机的,而我之前对PLC又接触的比较少,做起来还是比较难的。。

    查找了一堆资料后,终于找到了这个.net库,在大致学习了一下之后,总结了一下,当作自己的学习笔记。

    一、开发环境准备

    最近因为疫情的影响,只能呆在总公司混日子,手里没有设备,只能用博图的仿真器来测试通讯,需要安装的软件包括:

    TIA Protal(博图)&S7-PLCSIM

    西门子针对于PLC专门开发的一款编程软件,相信各位肯定比我熟悉这个软件了,这里就不作过多介绍了,同时提供了S7系列的仿真软件S7-PLCSIM,这里我们就用这两个设备仿真PLC设备来测试S7NETPlus库的通讯。
    在这里插入图片描述

    博图V15.1

    在这里插入图片描述

    S7-PLCSIM

    NetToPLCSIM

    在这里插入图片描述

    这个软件是用于将西门子的PLCsim映射到网络内,如果之前没有用过这个软件,建议按照后面的操作来,否则很容易出现Start server之后还是连不上仿真器。

    二、开发测试

    PLC配置

    1、在组态好的PLC设备属性中,找到“防护与安全”–>“连接机制”中,勾选“允许来自远程对象的PUT/GET通信访问”;

    在这里插入图片描述

    2、新建DB块,同时将该DB快属性中的“优化块的访问取消”;

    在这里插入图片描述

    3、在新建的DB块中新增一些数据,完成后点击编译计算偏移量。

    在这里插入图片描述

    4、以上步骤完成后,点击开始仿真,将工程下载到仿真器中;

    在这里插入图片描述

    NetToPLCSIM配置

    1、打开软件后,点击Add增加设备

    2、在弹出的窗口中,Network IP Address中填入本地回环IP“127.0.0.1”(如果你是在两台设备中测试,首先保证两台设备在同一个内网中,该处IP就可以设置为运行仿真环境的IP了)

    在这里插入图片描述

    3、Plcsim IP Address中,点击后面两个点,选择软件自己识别出来的仿真器地址;

    在这里插入图片描述

    4、Plcsim Rack/Slot中Rack为机架号,Slot为插槽号,这两个可以在PLC的设备组态属性->项目信息中找到

    配置完成后点击完成,这时候就可以点击Start Server开启服务了。

    在这里插入图片描述

    上面的操作一定要按照以上的步骤一步一步完成,否则很容易出现即使点Start Server显示状态为running,但是实际连接仍然连不上的情况。

    另外需要注意的是,可能在打开NetToPLCSim的时候,会弹出“Port 102 is in use!”的警告,如果遇到这个情况,点击是,之后在将PLCSIM关掉重新启动一下就可以了。
    在这里插入图片描述

    创建连接

    配置连接

    这里使用的是S7-1215的模块,所以CpuType选择S71200,IP地址使用回环地址“127.0.0.1”,机架号和插槽号在PLC工程中查。

    using S7.Net;
    
    Plc plc = new Plc(CpuType.S71200, "127.0.0.1", 0, 1);		
    

    配置完成后,使用Open()来打开,在最早的一个版本中,Open有返回值,可以通过返回值获取 ErrorCode 和 ErrorMessage,我目前使用的是最新版0.8.1.0,没有返回值,所以用try…catch来接收异常

    try
    {
    	plc.Open();
    }
    catch(Exception)
    {
    	Console.WriteLine($"连接到PLC设备失败:IsConnect = {plc.IsConnected},IsAvailable={plc.IsAvailable}");
    	return;
    }
    

    连接是否成功,可以用IsConnected去判断一下。

    访问数据块

    连接成功后,我们就可以去访问PLC的数据块了,访问数据块,我们先尝试一下读取数据块

    读取单个数据–Read

    这里主要用到了DBX,DBW,DBD读取数据,其他的各位可以在查一下PLC的资料

    /*
    方法:public object Read(string variable)
    入参:读取数据地址
    出参:Object类型数据,可强制类型转换
    */
    var db1Bool1 = plc.Read("DB1.DBX0.0");
    Console.WriteLine("DB1.DBX0.0:" + db1Bool1);
    
    bool db1Bool2 = (bool)plc.Read("DB1.DBX0.1");
    Console.WriteLine("DB1.DBX0.1:" + db1Bool2);
    
    int IntVariable = (ushort)plc.Read("DB1.DBW2.0");
    Console.WriteLine("DB1.DBW2.0:" + IntVariable);
    
    float RealVariable = ((uint)plc.Read("DB1.DBD4.0")).ConvertToFloat();
    Console.WriteLine("DB1.DBD4.0:" + RealVariable);
    
    var dIntVariable = (uint)plc.Read("DB1.DBD8.0");
    Console.WriteLine("DB1.DBD8.0: " + dIntVariable);
    
    var dWordVariable = (uint)plc.Read("DB1.DBD12.0");
    Console.WriteLine("DB1.DBD12.0: " + Convert.ToString(dWordVariable, 16));
    
    var wordVariable = (ushort)plc.Read("DB1.DBW16.0");
    Console.WriteLine("DB1.DBW16.0: " + Convert.ToString(wordVariable,16));
    

    在这里插入图片描述

    读取批量数据块–ReadBytes
    /*
    方法:public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
    入参:
    	1、DataType数据类型,可选择从DB块或者Memory中读取;
    	2、db:1:DataBlock=1,Memory=0;
    	3、startByteAdr:起始地址,即DB块的起始偏移量;
    	4、count:读取大小,该大小由读取的DB块的最后一个数据的偏移量和大小决定,这里最后一个字节WordVariable偏移量为16,数据类型为word,2个字节,因此此次读取为16+2=18个字节。
    出参:Byte[],这里Byte[]的大小必然和count的大小是相同的,
    */
    //读取数据选择从DB块中读取,db设置为1,起始地址为0,读取18个字节
    var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 18);
    //取字节0中的第0位
    var db1Bool1 = bytes[0].SelectBit(0);
    Console.WriteLine("DB1.DBX0.0:" + db1Bool1);
    //取字节0中的第1位
    bool db1Bool2 = bytes[0].SelectBit(1); ;
    Console.WriteLine("DB1.DBX0.1:" + db1Bool2);
    //跳到字节2并连续取两个字节数据
    int IntVariable = S7.Net.Types.Int.FromByteArray(bytes.Skip(2).Take(2).ToArray());
    Console.WriteLine("DB1.DBW2.0:" + IntVariable);
    //...
    double RealVariable = S7.Net.Types.Real.FromByteArray(bytes.Skip(4).Take(4).ToArray());
    Console.WriteLine("DB1.DBD4.0:" + RealVariable);
    //...
    int dIntVariable = S7.Net.Types.DInt.FromByteArray(bytes.Skip(8).Take(4).ToArray());
    Console.WriteLine("DB1.DBD8.0: " + dIntVariable);
    //...
    uint dWordVariable = S7.Net.Types.DWord.FromByteArray(bytes.Skip(12).Take(4).ToArray());
    Console.WriteLine("DB1.DBD12.0: " + Convert.ToString(dWordVariable, 16));
    //...
    ushort wordVariable = S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray());
    Console.WriteLine("DB1.DBW16.0: " + Convert.ToString(wordVariable, 16));
    

    在这里插入图片描述

    写入单个数据–Write
    /*
    方法:public void Write(string variable, object value)
    入参:
    	1、string variable:写入地址
    	2、object value,写入数据
    */
    plc.Write("DB1.DBX0.0", true);
    plc.Write("DB1.DBD12.0", 123457);
    

    在这里插入图片描述

    写入多个数据–WriteBytes
    /*
    public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
    用法如同ReadBytes,这里就不在写例程了,有兴趣的可以自己研究一下
    */
    

    关闭连接

    在通讯完之后,千万不要忘了关闭通讯链路哈,这里使用Close来关闭。

     plc.Close();
    

    以上内容都是在学习中,中间有很多内容还不完善,后续的内容在学习过程中会不断增加,如有更好的解决方案,欢迎留言一起探讨。

    展开全文
  • C#.net PLC通讯

    2017-11-09 11:10:25
    byte[] dd = { 0x10, 0x02, 0x00, 0x5C, 0x5E, 0x16 }; // serialPort1.Write(dd, 0, dd.Length); axMSComm1.Output = dd; System.Threading.Thread.Sleep(100); string q = q8 + q7 + q6 + q5 + q4+ q3 + q2+...
  • C#PLC通讯读写.rar

    2019-12-17 15:00:23
    c#通过MX component连接三菱PLC源代码,实际测试过了,运行OK C#程序读取三菱PLC内部寄存器的值和写入寄存器的值 输出端的读写,输入端的读取
  • c#和四门子plc通讯

    2020-03-11 14:42:49
    c#和四门子plc通讯程序,含源代码,完全免费。
  • C#PLC通信开发之三菱FX系列PLC 版权归作者本人所有,如需转载,请注明出处,谢谢! 如有项目合作,请联系:18635729543 前言 本文讲解的是上位机如何与三菱FX系列PLC进行通信,开发语言使用的是C#语言,代码不多,...

    C#与PLC通信开发之三菱FX系列PLC

    前言

    本文讲解的是上位机如何与三菱FX系列PLC进行通信,开发语言使用的是C#语言,代码不多,主要是讲解通信协议。

    刚做了一个转盘式翻斗分拣机项目,采用的是三菱PLC,之前没有接触过三菱的PLC,查看了一些资料,但是这些资料要么不完整,或者写的不够清楚,导致自己实际开发的时候,还是碰到一些问题,所以想花点时间总结一下,写一篇比较完整而且得到实际项目验证的文章记录下来。

    简单介绍一下项目:项目的功能是按波次分拣订单,订单的特点是:每个订单的数量较多,商品的尺寸较小,大部分是胶带,小部分是很轻很薄的纸片式的商品,还有部分是比较大的比如记事本啊什么的。

    订单商品
    订单商品
    分拣机由51个分拣口(含一个异常口),每个波次可以分拣50个订单,每个波次2000-3500件商品。由于商品的特殊性,没办法采用相机顶扫的方式,所以采用人工扫码,这台分拣机两个熟练的操作员操作的话,可以达到每秒1件商品的分拣速度,一小时能分拣3000多件商品,效率还是杠杠的。
    分拣机

    好了,闲话少说,下面切入正题。

    三菱FX系列PLC

    通信接口

    三菱FX系列PLC,采用串口与PC机进行通信,使用 SC-09 编程电缆作为计算机与 PLC 通信的连线。电缆的 9 芯 D 形插头连接在计算机串口上,另一端连接 PLC 的 RS-422 编程口。

    FX-PLC
    FX-PLC

    SC-09-DB9线
    SC-09-DB9线

    串口参数设置如下:

    波特率:9600

    奇偶校验:Even(偶校验)

    数据位:7位

    停止位:1位

    串口参数设置好了以后,连接PLC,使用串口调试助手,按16进制发送05给PLC,如果连接正常的话,PLC会返回06。

    通信测试

    通信协议

    三菱FX系列PLC的通信协议有三个特点:

    1. 上位机(我们的PC机)和PLC之间的通信是应答式的,也就是说,上位机给PLC发送指令,PLC作出相应的应答,PLC不会主动给上位机发送任何指令。注意:每次给PLC发送指令后,必须等待PLC的应答完成才能发送下一条指令,否则下一条指令将会失败!
    2. 指令都是ASCII码的形式,而且都是十六进制的。比如你要往某个地址写入数值100,如果用二进制表示,那么只需要一个字节就行了,但是用ASCII码表示,就需要3个字节,在内存里面分别是:31H、30H、30H。整条指令,包括起始符、终止符、地址、值、校验都是使用ASCII码。
    3. 指令简单。除了上文所说的05H通信测试指令之外,还有另外4条指令:

    指令
    我在项目中,主要用到的就是读写这两个指令,置位和复位这两个指令没有用到,不过下面将会逐一的讲解这4个指令(置位和复位这两个指令的内容从别人的文章里复制~)

    校验

    这4条指令都涉及到校验,所以在逐一讲解这4条指令之前,先说一下校验。三菱FX系列PLC的指令校验方式,采用的是和校验方式,也就是累加求和,然后取最后两位。很简单,直接上代码吧:

            public string CheckSum(byte[] cmd)
            {
                byte sum = 0;
                
                for (int i = 0; i < cmd.Length; i++)
                {
                    sum = (byte)(sum + cmd[i]);
                }
    
                return sum.ToString("X2");
            }
    

    地址

    地址需要进行转换,转算算法为:

    address = address*2 + 1000H

    比如要往D134这个地址写入数据,那么地址为:

    address = 134*2 + 4096

    值得注意的是,FX系列PLC,读写的基本单元是字,也就是说每个地址对应的是两个字节,如图所示:
    地址

    读指令

    上位机指令

    先来看看读指令的指令格式,一条完整的读指令,包含起始符(ASCII码里面的STX)、命令(30H)、首地址、读取的字节数、终止符(ASCII码里面的ETX)、校验这6个部分。下面的图示里,我们以读取首地址为D123为例,读取2个字节,也就是读一个short数据出来:
    读指令
    下面逐一讲解各个部分:

    • STX:起始符,ASCII码里面的STX,值为02H。一个字节。

    • CMD:指令,读指令为ASCII码的’0’,值为30H。一个字节。

    • 首地址:读取数据的起始地址,4个字节表示。地址的计算方式,上文有讲解,这个图里我们读取的是D123的地址,根据计算公式address=123*2 + 4096 = 10F6H,转换成ASCII码,就是31H,30H,46H,36H。

    • 字节数:要去读的字节数,2个字节表示。需要注意的是,一条读指令,最多能读取64个字节

    • ETX:指令终止符,ASCII码里面的ETX,值为03H。一个字节。

    • 校验:2个字节表示。校验在前面也讲解过,采用的是累加求和,取最后两个字节。从CMD到ETX这部分参与运算:

    读指令校验

    PLC响应

    如果一切正常的话,那么PLC会对读指令进行响应,返回要读取的数据,我们假设PLC返回的short值是30,那么响应格式为:
    读指令响应
    基本上,PLC响应的各部分和指令是相同的。需要注意的是这个部分,我们的指令是读取2个字节,但是这个部分有4个字节,是因为FX系列通信协议里,指令和响应都是ASCII码表示的,每个字节用两个ASCII码字符表示,所以一共有4个字节。如果我们是按字读取值的话,也就是读取一个short的值,那么有两个地方需要注意:

    1. 字节顺序是:低位在前,高位在后,解析的时候需要调整顺序。
    2. 里面存储的是ASCII码,需要进行转换。

    如何把这4个字节,还原成一个short呢?

    首先,将31H45H30H30H,高低位调整顺序变成30H30H31H45H,然后把ASCII码转换成值001EH,也就是1*16 + 14 = 30。

    其中,ASCII码转换成数值的代码如下:

            public static int AsciiToInt(byte ascVal)
            {
                if (ascVal >= 0x30 && ascVal <= 0x39) // ASCII字符0-9之间
                {
                    return (ascVal - 0x30);
                }
                else if (ascVal >= 0x41 && ascVal <= 0x46) // ASCII字符A-F之间
                {
                    return (ascVal - 0x41 + 10);
                }
                else if (ascVal >= 0x61 && ascVal <= 0x66) // ASCII字符a-f之间
                {
                    return (ascVal - 0x61 + 10);
                }
                else
                {
                    return -1;
                }
            }
    

    完整的转换一个short值的代码如下:

        public static short TranslateToShortValue(byte[] buf)
        {
            int lowByte = AsciiToInt(buf[0]) * 16 + AsciiToInt(buf[1]);
            int highByte = AsciiToInt(buf[2]) * 16 + AsciiToInt(buf[3]);
            int intVal = highByte * 256 + lowByte;
            return (short)intVal;
        }
    

    其中,buf数组里面,存储的就是从PLC里面读取的数据31H45H30H30H。

    写指令

    上位机指令

    假设我们往地址D123里写入一个short值98(注意,不是16进制),指令格式为:

    写指令
    大体上和读指令的格式是一样的,只是有两个地方需要注意:

    1. 字节数:这里我们是按short类型写入,也就是写入一个字,所以字节数是2个。但是在数据部分,却占了4个字节,是因为指令全部由ASCII码组成。
    2. 数据部分:首先数值98要转换成16进制0063H,然后低位在前,高位在后,然后再转换成ASCII码。

    PLC响应

    写指令因为不需要返回数据,所以PLC的响应很简单,只返回一个字节。

    • 如果写入正确,则返回ACK(06H)
    • 如果写入错误,则返回NAK(15H)

    完整的代码如下:

            private static string STX = "\x02";
            private static string ETX = "\x03";
            private SerialPort _serialPort;
    
            public bool WriteData(int addr, short value)
            {
                if (null == _serialPort || !_serialPort.IsOpen)
                {
                    return false;
                }
    
                StringBuilder sb = new StringBuilder();
    
                sb.Append("1"); // CMD
    
                addr = addr * 2 + 4096;
                sb.Append(addr.ToString("X4")); // 首地址
    
                sb.Append("02");    //字节数
    
                string strValue = value.ToString("X4"); // 数据
                sb.Append(strValue.Substring(2, 2));    // 低字节在先
                sb.Append(strValue.Substring(0, 2));    // 高字节在后
    
                sb.Append(ETX);   // 结束符
    
                // 计算SUM
                byte[] cmd = System.Text.Encoding.ASCII.GetBytes(sb.ToString());
                string sum = CheckSum(cmd);
                sb.Append(sum); // SUM
    
                sb.Insert(0, STX);  // 插入起始符
    
                try
                {
                    // 转换成字节并写入串口
                    byte[] cmdArr = System.Text.Encoding.ASCII.GetBytes(sb.ToString());
                    _serialPort.Write(cmdArr, 0, cmdArr.Length);
                }
                catch (System.ServiceProcess.TimeoutException ex)
                {
                    Logger.WriteLog("写入plc超时");
                    return false;
                }
                catch (Exception ex)
                {
                    Logger.WriteLog("写入plc失败,异常:" + ex.Message);
                    return false;
                }
    
                try
                {
                    // 读取PLC响应
                    int ret = _serialPort.ReadByte();
                    if (ret == 6)
                    {
                        // 正确应答
                        return true;
                    }
                }
                catch (System.ServiceProcess.TimeoutException ex)
                {
                    Logger.WriteLog("读取plc应答超时");
                }
                catch (InvalidOperationException ex)
                {
                    Logger.WriteLog("读取plc应答失败,串口未打开");
                }
                catch (Exception ex)
                {
                    Logger.WriteLog("读取plc应答失败,异常:" + ex.Message);
                }
    
                return false;
            }
    

    置位指令

    上位机指令

    置位指令
    这里需要注意的就是:地址计算方式,address = address / 8 + 100H

    PLC响应

    PLC的响应很简单,只返回一个字节。

    • 如果写入正确,则返回ACK(06H)
    • 如果写入错误,则返回NAK(15H)

    复位指令

    上位机指令
    复位指令
    这里需要注意的就是:地址计算方式,address = address / 8 + 100H

    PLC响应

    PLC的响应很简单,只返回一个字节。

    • 如果写入正确,则返回ACK(06H)
      是:地址计算方式,address = address / 8 + 100H

    PLC响应

    PLC的响应很简单,只返回一个字节。

    • 如果写入正确,则返回ACK(06H)
    • 如果写入错误,则返回NAK(15H)

    复位指令

    上位机指令

    [外链图片转存中…(img-9eSEcDCT-1603044910210)]

    这里需要注意的就是:地址计算方式,address = address / 8 + 100H

    PLC响应

    PLC的响应很简单,只返回一个字节。

    • 如果写入正确,则返回ACK(06H)
    • 如果写入错误,则返回NAK(15H)
    展开全文
  • C#PLC通讯,modbus-RTU,c#做从站,比如我想用PLCC#中D0的值,怎么在C#中把值赋进D0
  • C#与欧姆龙PLC-FINS

    2020-12-30 11:56:24
    C#与欧姆龙PLC-FINS通信
  • C#PLC-OPC完美教程

    2018-10-24 19:05:45
    完美解释C#PLC-OPC的完美代码,有完整的例子,可以参考内部例子实现所想功能

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,045
精华内容 418
关键字:

c#plc

c# 订阅