C#实现PC与三菱PLC通讯

搞了很久终于来博客上记录自己的学习笔记;前段时间老板要我做一个项目,就是要写一个上位软件,能与三菱通讯,进行数据交换,查了很多资料研究了几天,自己写通讯协议很麻烦,网上有很多说法,我采取了简便的方法,通过MX Component软件提供的控件来编程实现PC与PLC通讯。

1.准备阶段

在三菱官网上下载MX Component软件,如图:

unity pro xl 怎么连接plc_物联网

unity pro xl 怎么连接plc_c#_02

注意:在安装软件的时候需要序列号,需要大家在官网上注册自己的信息就可以获取;在这里我也可以提供一个免费的序列号:998-598638072。

2.安装软件MX Component

傻瓜式的安装软件直到完成;完成以后在自己电脑开始找到Communication Setup Utility 与PLC Monitor先打开Communication Setup Utility设置通讯事项如图:

unity pro xl 怎么连接plc_控件_03

打开软件后点击Wizard出现设置站点号:

unity pro xl 怎么连接plc_寄存器_04

这里的站点号设置了记清楚,后面程序会用到;设置好以后点击next,设置串口信息:

unity pro xl 怎么连接plc_控件_05

选择自己对应的串口后以后点击Next

unity pro xl 怎么连接plc_c#_06

选择你要通讯的PLC型号,点击Next

unity pro xl 怎么连接plc_物联网_07

点击Next以后就完成了通讯的配置,接着打开PLC Monitor与PLC通讯测试:

unity pro xl 怎么连接plc_寄存器_08

点击OK就完成了测试,读取数据:

unity pro xl 怎么连接plc_控件_09

3.利用C#编写上位软件

打开Visual Studio软件新建C#窗体程序,这里要安装三菱的控件包:

unity pro xl 怎么连接plc_控件_10

安装完成以后会在工具栏底部出现需要调用的控件:

unity pro xl 怎么连接plc_Data_11

然后就可以编写上位代码了:

private void PLC_Connect()
        {
            string szCpuName = "";
            int iCpuType = 0;
            try
            {
                axActUtlType1.ActPassword = "";
                axActUtlType1.ActLogicalStationNumber = Convert.ToInt16(0);//PLC逻辑站点号
                iReturn = axActUtlType1.Open();
            } catch
            {
                MessageBox.Show("PLC连接失败!");
            }
            if (iReturn == 0)
            {
                int CpuType = axActUtlType1.GetCpuType(out szCpuName, out iCpuType);
                MessageBox.Show("PLC连接成功!");
               // button6.Enabled = false;
                button6.BackColor = Color.Red;
            }
            else
            {
                MessageBox.Show("PLC连接失败!");
            }
        }
        /********************************************************
         * 功能:读取PLC寄存器中的值
         * Address:起始地址,如D0
         * Datasize:寄存器大小 16位/32位
         * Databitnum:读取数据的个数
         * DataValue:读取到的数据,以数组输出
         *********************************************************/
        private void Read_PLC_DRegisterValue(string Address, int Datasize, int Databitnum, ref int[] DataValue)
        {
            try
            {
                int iReturnCode;
                String[] arrdata = null;
                short[] arrDeviceValue = null;
                int iNum;
                if (Datasize == 16 || Datasize == 32)
                {
                    if (Datasize == 16)
                    {
                        arrdata = new String[Databitnum];
                        DataValue = new int[Databitnum];
                        arrDeviceValue = new short[Databitnum];
                        iReturnCode = axActUtlType1.ReadDeviceBlock2(Address, Databitnum, out arrDeviceValue[0]);
                        for (iNum = 0; iNum < Databitnum; iNum++)
                        {
                            DataValue[iNum] = arrDeviceValue[iNum];
                        }
                    }
                    else
                    {
                        arrdata = new String[2 * Databitnum];
                        DataValue = new int[Databitnum];
                        Databitnum = 2 * Databitnum;
                        arrDeviceValue = new short[2 * Databitnum];
                        iReturnCode = axActUtlType1.ReadDeviceBlock2(Address, Databitnum, out arrDeviceValue[0]);
                        if (iReturnCode == 0)
                        {
                            for (iNum = 0; iNum < Databitnum; iNum++)
                            {
                                arrdata[iNum] = arrDeviceValue[iNum].ToString();
                            }
                            for (iNum = 0; iNum < Databitnum; iNum = iNum + 2)
                            {
                                if (arrDeviceValue[iNum] < 0 && arrDeviceValue[iNum + 1] <= 0)
                                {
                                    DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1]) + 1) + Convert.ToInt16(arrdata[iNum]);
                                }
                                else if (arrDeviceValue[iNum] > 0 && arrDeviceValue[iNum + 1] <= 0)
                                {
                                    DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1])) + Convert.ToInt16(arrdata[iNum]);
                                }
                                else if (arrDeviceValue[iNum] < 0 && arrDeviceValue[iNum + 1] >= 0)
                                {
                                    DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1])) + 65536 + Convert.ToInt16(arrdata[iNum]);
                                }
                                else
                                {
                                    DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1])) + Convert.ToInt16(arrdata[iNum]);
                                }
                            }
                        }
                    }

                }
                else
                {
                    MessageBox.Show("参数有误!");
                    return;
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /********************************************************
         * 功能:写入PLC寄存器中的值
         * Address:起始地址,如D0
         * Datasize:寄存器大小 16位/32位
         * Data:写入PLC的数据
         *********************************************************/
        private void Write_PLC_DRegister(string Address, int Datasize, string[] Data)
        {
            try
            {
                int iReturnCode;
                short[] arrDeviceValue = null;
                String[] arrdata = null;
                int flagData;
                int iNum;
                if (Datasize == 16 || Datasize == 32)
                {
                    if (Datasize == 16)
                    {
                        arrDeviceValue = new short[Data.Count()];
                        arrdata = new String[Data.Count()];
                        for (iNum = 0; iNum < Data.Count(); iNum++)
                        {
                            arrDeviceValue[iNum] = Convert.ToInt16(Convert.ToInt32(Data[iNum]).ToString());
                            iReturnCode = axActUtlType1.WriteDeviceBlock2(Address, Data.Count(), ref arrDeviceValue[0]);
                        }
                    }
                    else
                    {
                        arrDeviceValue = new short[2 * Data.Count()];
                        arrdata = new String[2 * Data.Count()];
                        for (iNum = 0; iNum < Data.Count(); iNum++)
                        {
                            arrDeviceValue[2 * iNum + 1] = Convert.ToInt16((Convert.ToInt32(Data[2 * iNum]) / 65535 - 1).ToString());
                            flagData = Convert.ToInt32((Convert.ToInt32(Data[iNum]) - arrDeviceValue[2 * iNum + 1] * 65535).ToString());
                            if (flagData % 65535 == 0)
                            {
                                arrDeviceValue[2 * iNum + 1] = Convert.ToInt16(arrDeviceValue[2 * iNum + 1] + 1);
                            }
                            else if (flagData > 32767)
                            {
                                arrDeviceValue[2 * iNum] = Convert.ToInt16(-65535 + flagData);
                            }
                            else
                            {
                                arrDeviceValue[2 * iNum] = Convert.ToInt16(flagData);
                            }
                        }
                        iReturnCode = axActUtlType1.WriteDeviceBlock2(Address, 2 * Data.Count(), ref arrDeviceValue[0]);
                    }
                }
                else
                {
                    MessageBox.Show("输入参数有误,重新输入!");
                    return;
                }

            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }