PLC操作简单示例(读写指定寄存器)

最近写的一个程序要和生产线的PLC连动(特定条件下读写指定寄存器),

查询了一些PLC的操作资料,做了一个测试程序:

PLC操作简单示例(读写指定寄存器)_第1张图片


        private void btnRead_Click(object sender, EventArgs e)
        {
            try
            {

                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = Dns.GetHostEntry(this.txtIP.Text.Trim()).AddressList[0];
                IPEndPoint ipend = new IPEndPoint(ip, int.Parse(this.txtPort.Text.Trim()));
                sock.Connect(ipend);

                byte[] cmd;
                byte[] rec;

                cmd = createCommand("R", int.Parse(this.txtStartAddr.Text), 1);
                sock.Send(cmd);

                Thread.Sleep(1000);

                rec = new byte[sock.Available];
                sock.Receive(rec);
                this.txtRegInfo.Text = this.txtRegInfo.Text + Environment.NewLine + " <读取> " + b2s(rec);

                sock.Shutdown(SocketShutdown.Both);
                sock.Close();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void btnStop_Click(object sender, EventArgs e)
        {

            try
            {
                this.mutexforsocket.WaitOne();
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = Dns.GetHostEntry(this.txtIP.Text.Trim()).AddressList[0];
                IPEndPoint ipend = new IPEndPoint(ip, int.Parse(this.txtPort.Text.Trim()));
                sock.Connect(ipend);

                byte[] cmd;
                byte[] rec;
               
                cmd = createCommand("W", int.Parse(this.txtStartAddr.Text), 0x3130);
                sock.Send(cmd);

                Thread.Sleep(1000);

                rec = new byte[sock.Available];
                sock.Receive(rec);
                this.txtRegInfo.Text = this.txtRegInfo.Text + Environment.NewLine + " <停止> " + b2s(rec);

                sock.Shutdown(SocketShutdown.Both);
                sock.Close();
                this.mutexforsocket.ReleaseMutex();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                this.mutexforsocket.WaitOne();
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = Dns.GetHostEntry(this.txtIP.Text.Trim()).AddressList[0];
                IPEndPoint ipend = new IPEndPoint(ip, int.Parse(this.txtPort.Text.Trim()));
                sock.Connect(ipend);

                byte[] cmd;
                byte[] rec;


                cmd = createCommand("W", int.Parse(this.txtStartAddr.Text), 0x3030);
                sock.Send(cmd);

                Thread.Sleep(1000);

                rec = new byte[sock.Available];
                sock.Receive(rec);
                this.txtRegInfo.Text = this.txtRegInfo.Text + Environment.NewLine + " <启动> " + b2s(rec);

                sock.Shutdown(SocketShutdown.Both);
                sock.Close();
                this.mutexforsocket.ReleaseMutex();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            try
            {
                this.mutexforsocket.WaitOne();
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = Dns.GetHostEntry(this.txtIP.Text.Trim()).AddressList[0];
                IPEndPoint ipend = new IPEndPoint(ip, int.Parse(this.txtPort.Text.Trim()));
                sock.Connect(ipend);

                byte[] cmd;
                byte[] rec;
                cmd = createCommand("W", int.Parse(this.txtStartAddr.Text), 0x0000);
                sock.Send(cmd);

                Thread.Sleep(1000);

                rec = new byte[sock.Available];
                sock.Receive(rec);
                this.txtRegInfo.Text = this.txtRegInfo.Text + Environment.NewLine + " <还原> " + b2s(rec);

                sock.Shutdown(SocketShutdown.Both);
                sock.Close();
                this.mutexforsocket.ReleaseMutex();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }
    }

        private string b2s(byte[] b)
        {
            string s = "寄存器[" + this.cbxRegType.Text + "] 地址[" + this.txtStartAddr.Text.Trim() + "]: ";
            for (int i = 0; i < b.Length; i++)
            {
                s = s + b[i].ToString("X").PadLeft(2, '0') + " ";
            }
            return s;
        }

        /// 生成Socket命令
        /// </summary>
        /// <param name="type">R:读,W:写</param>
        /// <param name="dreg">寄存器地址</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        private byte[] createCommand(string type,int dreg,int data)
        {
            byte[] sendBuf;
            switch (type)
            {
                case "R":
                    {
                        sendBuf = new byte[21];

                        //副标题
                        sendBuf[0] = 0x50;
                        sendBuf[1] = 0x00;
                        //网络号
                        sendBuf[2] = 0x00;
                        //PLC号
                        sendBuf[3] = 0xFF;
                        //IO
                        sendBuf[4] = 0xFF;
                        sendBuf[5] = 0x03;
                        //站号
                        sendBuf[6] = 0x00;
                        //字节数
                        sendBuf[7] = 0x0c;
                        sendBuf[8] = 0x00;
                        //等待长度
                        sendBuf[9] = 0x0A;
                        sendBuf[10] = 0x00;
                        //命令
                        sendBuf[11] = 0x01;
                        sendBuf[12] = 0x04;
                        //子命令
                        sendBuf[13] = 0x00;
                        sendBuf[14] = 0x00;
                        //起始寄存器地址
                        sendBuf[15] = (byte)(dreg & 0xff);
                        sendBuf[16] = (byte)((dreg & 0xff00) >> 8);
                        sendBuf[17] = (byte)((dreg & 0xff0000) >> 16);
                        if(this.cbxRegType.Text.Equals("R"))
                        {
                            //寄存器类型-R类
                            sendBuf[18] = 0xAF;
                        }
                        if (this.cbxRegType.Text.Equals("D"))
                        {
                            //寄存器类型-D类
                            sendBuf[18] = 0xA8;
                        }
                       
                        //寄存器连续长度
                        sendBuf[19] = (byte)(data & 0xff);
                        sendBuf[20] = (byte)((data & 0xff00) >> 8);
                        return sendBuf;
                    }
                case "W":
                    {
                        sendBuf = new byte[23];
                        //副标题
                        sendBuf[0] = 0x50;
                        sendBuf[1] = 0x00;
                        //网络号
                        sendBuf[2] = 0x00;
                        //PLC号
                        sendBuf[3] = 0xFF;
                        //IO
                        sendBuf[4] = 0xFF;
                        sendBuf[5] = 0x03;
                        //站号
                        sendBuf[6] = 0x00;
                        //字节数
                        sendBuf[7] = 0x0E;
                        sendBuf[8] = 0x00;
                        //等待长度
                        sendBuf[9] = 0x0A;
                        sendBuf[10] = 0x00;
                        //命令
                        sendBuf[11] = 0x01;
                        sendBuf[12] = 0x14;
                        //子命令
                        sendBuf[13] = 0x00;
                        sendBuf[14] = 0x00;
                        //起始寄存器地址
                        sendBuf[15] = (byte)(dreg & 0xff);
                        sendBuf[16] = (byte)((dreg & 0xff00) >> 8);
                        sendBuf[17] = (byte)((dreg & 0xff0000) >> 16);
                        if (this.cbxRegType.Text.Equals("R"))
                        {
                            //寄存器类型-R类
                            sendBuf[18] = 0xAF;
                        }
                        if (this.cbxRegType.Text.Equals("D"))
                        {
                            //寄存器类型-D类
                            sendBuf[18] = 0xA8;
                        }
                        //寄存器连续长度
                        sendBuf[19] = 0x01;
                        sendBuf[20] = 0x00;

                        sendBuf[21] = (byte)(data & 0xff);
                        sendBuf[22] = (byte)((data & 0xff00) >> 8);
                        return sendBuf;
                    }
                default: return null ;
            }

        }

 

你可能感兴趣的:(PLC操作简单示例(读写指定寄存器))