Exemple #1
0
        /// <summary>
        /// 处理数据
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="count"></param>
        /// <param name="msg"></param>
        private void ProcessData(SiemensMessage msg)
        {
            switch (msg.Type)
            {
            case CommandType.Head1:
                response.Type = CommandType.Head2;
                SendData(headData.plcHead2);
                //Console.WriteLine("Head1");
                break;

            case CommandType.Head2:
                Connected = true;
                //Console.WriteLine("Head2");
                break;

            case CommandType.Read:
            case CommandType.Write:
                response.Success   = msg.Success;
                response.Message   = msg.Message;
                response.DataValue = msg.DataValue;
                //Console.WriteLine("Read | Write  " + Common.BytesToShort(msg.DataValue).ToString());
                break;

            default:
                break;
            }
        }
Exemple #2
0
        /// <summary>
        /// 解码
        /// </summary>
        /// <param name="buffer">报文</param>
        /// <param name="length">报文长度</param>
        /// <returns></returns>
        public SiemensMessage Decode(byte[] buffer, int length)
        {
            SiemensMessage msg = null;

            if (buffer[0] == 3 && buffer[1] == 0)
            {
                short messageLength = Common.BytesToShort(buffer, 2);      //2-3 是报文长度
                if (messageLength == length)
                {
                    int type = buffer[11];
                    msg = new SiemensMessage();
                    switch (type)
                    {
                    case 0xC0:
                        msg.Type = CommandType.Head1;
                        break;

                    case 0x04:
                        msg.Type = CommandType.Head2;
                        break;

                    default:
                        ReadOrWrite(buffer, msg);
                        break;
                    }
                }
            }
            return(msg);
        }
Exemple #3
0
        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="type"></param>
        /// <param name="host"></param>
        public void Connect(SiemensPLCS type, string host)
        {
            if (start)
            {
                return;
            }
            plcType = type;
            plcIP   = host;
            headData.SetPlcType(type);

            try
            {
                tcpsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                {
                    NoDelay = true
                };
                tcpsend.ReceiveTimeout = timeOut * 1000;
                tcpsend.SendTimeout    = timeOut * 1000;
                var remotepoint = new IPEndPoint(IPAddress.Parse(host), plcPort);
                tcpsend.Connect(remotepoint);
                response = new SiemensMessage();
                start    = true;
                Active();
            }
            catch (Exception ex)
            {
                Connected = false;
                start     = false;
                ErrorMsg("Connect:" + ex.Message);
            }
        }
Exemple #4
0
        /// <summary>
        /// 读取PLC数据
        /// </summary>
        /// <param name="address"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public ResultData ReadBytes(string address, int count)
        {
            ResultData rd = new ResultData
            {
                Connected = false,
                Message   = "当前与PLC通信断开!",
                Success   = false
            };

            if (this.Connected)
            {
                SiemensMessage msg = Common.GetAddress(address);
                if (msg == null)
                {
                    rd.Message = "请输入正确的PLC地址!";
                    return(rd);
                }

                try
                {
                    msg.Type = CommandType.Read;
                    if (count > 0)
                    {
                        if (msg.DataType != DataType.Byte)
                        {
                            rd.Success = false;
                            rd.Message = "对不起,请输入Byte类型地址!";
                            return(rd);
                        }
                        msg.DataType   = DataType.Bytes;
                        msg.DataLength = count;
                    }
                    else
                    {
                        msg.DataLength = (int)msg.DataType;
                    }

                    SiemensMessage result = plc.Send(msg);
                    if (result.Success)
                    {
                        var value = GetValue(result.DataValue, result.DataType, result.DataLength);
                        rd.Value = value;
                    }
                    rd.Success = result.Success;
                    if (Connected)
                    {
                        rd.Message = result.Message;
                    }
                    rd.Connected = Connected;
                }
                catch (Exception e)
                {
                    rd.Message = e.Message;
                }
            }
            return(rd);
        }
Exemple #5
0
        /// <summary>
        /// 第一次连接
        /// </summary>
        private void Active()
        {
            var msg = new SiemensMessage
            {
                Type      = CommandType.Head1,
                DataValue = headData.plcHead1
            };

            Send(msg);
        }
Exemple #6
0
        /// <summary>
        /// 读写数据
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="msg"></param>
        private void ReadOrWrite(byte[] buffer, SiemensMessage msg)
        {
            int endLength = buffer[16]; //获取结尾报文长度
            int type      = buffer[19]; //结果类型  05写入返回   04 读取返回
            int code      = buffer[21]; //返回结果   0xFF 代表无错

            byte[] value    = null;
            var    errorMsg = type == 4 ? "读取数据失败!" : "写入数据失败!";

            if (code == 0xFF)
            {
                //0x05 是写入返回   0x04 是读取返回
                switch (type)
                {
                case 0x04:
                    msg.Type = CommandType.Read;
                    int bType      = buffer[22];
                    int dataLength = Common.BytesToShort(buffer, 23);        //结果数据长度
                    if (bType == 4)                                          //03 代表返回是bit     04代表byte
                    {
                        dataLength = dataLength / 8;                         //结果数据长度 / 8 bit
                    }
                    byte[] buf = new byte[dataLength];
                    Array.Copy(buffer, 25, buf, 0, dataLength);
                    value = buf;
                    break;

                case 0x05:
                    msg.Type = CommandType.Write;
                    break;

                default:
                    errorMsg = "发现错误读写类型:" + type;
                    break;
                }
                errorMsg = null;
            }

            msg.Success   = string.IsNullOrEmpty(errorMsg);
            msg.Message   = errorMsg;
            msg.DataValue = value;
        }
Exemple #7
0
        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public ResultData Write(string address, byte[] value)
        {
            ResultData rd = new ResultData
            {
                Connected = false,
                Success   = false,
                Message   = "当前与PLC通信断开!"
            };

            if (this.Connected)
            {
                rd.Connected = true;
                SiemensMessage msg = Common.GetAddress(address);

                if (msg == null)
                {
                    rd.Message = "当前PLC地址不正确!";
                    return(rd);
                }

                msg.Type       = CommandType.Write;
                msg.DataValue  = value;
                msg.DataLength = value.Length;

                try
                {
                    SiemensMessage result = plc.Send(msg);
                    if (Connected)
                    {
                        rd.Message = result.Message;
                    }
                    rd.Success   = result.Success;
                    rd.Value     = result.DataValue;
                    rd.Connected = Connected;
                }
                catch (Exception e)
                {
                    rd.Message = e.Message;
                }
            }
            return(rd);
        }
Exemple #8
0
 /// <summary>
 /// 发送数据
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public SiemensMessage Send(SiemensMessage message)
 {
     lock (objLock)
     {
         response = new SiemensMessage
         {
             Type        = message.Type,
             IsByte      = message.IsByte,
             DataValue   = message.DataValue,
             DataLength  = message.DataLength,
             DataAddress = message.DataAddress,
             DataType    = message.DataType,
             DbBlockNo   = message.DbBlockNo,
             FnCode      = message.FnCode
         };
         var data = plcEncoder.Encode(message);
         SendData(data);
         return(response);
     }
 }
Exemple #9
0
        /// <summary>
        /// 获取PLC地址信息
        /// </summary>
        /// <param name="addr"></param>
        /// <returns></returns>
        public static SiemensMessage GetAddress(string addr)
        {
            SiemensMessage msg     = null;
            string         address = addr.ToUpper();

            //地址不能为空,并且字符串长度不能少于2位
            if (!string.IsNullOrEmpty(address) && address.Length > 2)
            {
                address = address.Replace("DBX", ""); // DB1.DBX0.0  =>  DB1.0.0
                address = address.Replace("DB", "E"); // DB1.DBB0 =>  E1.EB0
                address = address.Replace("DW", "L"); // MDW0  => ML0    IDW0  =>  IL0

                var arr       = address.Split('.');   //DB1.DBX0.0   M0.0   I0.0
                int arrLength = arr.Length;

                FnCode   fnCode       = GetFnCode(arr[0]); //获取功能码
                DataType dataType     = DataType.None;
                int      addressStart = 0;
                int      dbNumber     = 0;
                bool     isByte       = true;


                if (arrLength == 1)
                {  //IB0  QW0   MD0
                    dataType     = GetDataType(arr[0]);
                    addressStart = GetAddressStart(arr[0]);
                }
                else if (arrLength == 2)
                {  //I0.0  Q0.0  DB1.DBB0    DB1.DBB20
                    if (fnCode != FnCode.DB)
                    {
                        isByte       = false;
                        dataType     = DataType.Bit;
                        addressStart = GetBitStart(arr[0], arr[1]);
                    }
                    else
                    {
                        dataType     = GetDataType(arr[1]);
                        addressStart = GetAddressStart(arr[1]);
                        dbNumber     = GetDBNumber(arr[0]);
                    }
                }
                else if (arrLength == 3 && fnCode == FnCode.DB)
                {  //DB1.0.0
                    isByte       = false;
                    dbNumber     = GetDBNumber(arr[0]);
                    addressStart = GetBitStart(arr[1], arr[2]);  //有问题
                    dataType     = DataType.Bit;
                }

                if (FnCode.None != fnCode && dataType != DataType.None && addressStart >= 0 && dbNumber >= 0)
                {
                    msg = new SiemensMessage
                    {
                        FnCode      = fnCode,
                        DbBlockNo   = dbNumber,
                        DataType    = dataType,
                        DataAddress = addressStart,
                        IsByte      = isByte
                    };
                }
            }
            return(msg);
        }
Exemple #10
0
        /// <summary>
        /// 编码
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public byte[] Encode(SiemensMessage msg)
        {
            int dataAddress = 0;

            sendData.Clear();
            switch (msg.Type)
            {
            case CommandType.Head1:
            case CommandType.Head2:
                sendData.AddRange(msg.DataValue);
                break;

            case CommandType.Read:
                sendData.Add(3);
                sendData.Add(0);
                sendData.Add(0);
                sendData.Add(0x1F);      //长度
                sendData.Add(0x02);
                sendData.Add(0xF0);
                sendData.Add(0x80);
                sendData.Add(0x32);
                sendData.Add(0x01);
                sendData.Add(0);
                sendData.Add(0);
                sendData.Add(0);
                sendData.Add(0x01);
                sendData.Add(0);
                sendData.Add(0x0E);
                sendData.Add(0);
                sendData.Add(0);
                sendData.Add(0x04);
                sendData.Add(0x01);
                sendData.Add(0x12);
                sendData.Add(0x0A);
                sendData.Add(0x10);
                //---------------------------
                sendData.Add(msg.IsByte ? (byte)2 : (byte)1);           //1 为bool 2为byte
                //读取类型长度  byte =1 , shot = 2  int = 4;  string 先读前2位,获取字符串长度,然后在读
                sendData.Add((byte)(msg.DataLength >> 8 & 0xFF));
                sendData.Add((byte)(msg.DataLength & 0xFF));
                //DB块编号
                sendData.Add((byte)(msg.DbBlockNo >> 8 & 0xFF));
                sendData.Add((byte)(msg.DbBlockNo & 0xFF));
                //I/Q/M/DB  功能代码
                sendData.Add((byte)msg.FnCode);

                if (msg.DataType == DataType.Bit)
                {
                    dataAddress = msg.DataAddress;
                }
                else
                {
                    dataAddress = msg.DataAddress * 8;     //长度   byte * 8
                }
                sendData.Add((byte)(dataAddress >> 16 & 0xFF));
                sendData.Add((byte)(dataAddress >> 8 & 0xFF));
                sendData.Add((byte)(dataAddress & 0xFF));
                break;

            case CommandType.Write:
                int dataLength = msg.DataLength;
                sendData.Add(3);
                sendData.Add(0);
                //数据长度
                sendData.Add((byte)(0x23 + dataLength >> 8 & 0xFF));
                sendData.Add((byte)(0x23 + dataLength & 0xFF));
                sendData.Add(0x02);
                sendData.Add(0xF0);
                sendData.Add(0x80);
                sendData.Add(0x32);
                sendData.Add(0x01);
                sendData.Add(0);
                sendData.Add(0);
                sendData.Add(0);
                sendData.Add(0x01);
                sendData.Add(0);
                sendData.Add(0x0E);
                sendData.Add(0);
                sendData.Add((byte)(4 + dataLength));
                sendData.Add(0x05);
                sendData.Add(0x01);
                sendData.Add(0x12);
                sendData.Add(0x0A);
                sendData.Add(0x10);
                //---------------------------
                sendData.Add(msg.IsByte ? (byte)2 : (byte)1);        //1 为bool 2为byte
                //数据长度
                sendData.Add((byte)(dataLength >> 8 & 0xFF));
                sendData.Add((byte)(dataLength & 0xFF));
                //DB块编号
                sendData.Add((byte)(msg.DbBlockNo >> 8 & 0xFF));
                sendData.Add((byte)(msg.DbBlockNo & 0xFF));
                //I/Q/M/DB  功能代码
                sendData.Add((byte)msg.FnCode);

                if (msg.DataType == DataType.Bit)
                {
                    dataAddress = msg.DataAddress;
                }
                else
                {
                    dataAddress = msg.DataAddress * 8;     //长度   byte * 8
                }
                sendData.Add((byte)(dataAddress >> 16 & 0xFF));
                sendData.Add((byte)(dataAddress >> 8 & 0xFF));
                sendData.Add((byte)(dataAddress & 0xFF));

                sendData.Add(0);
                sendData.Add(msg.IsByte ? (byte)4 : (byte)3);            //bit 为3    byte 为 4
                //类型长度
                var dtl = msg.DataType == DataType.Bit ? 1 : dataLength * 8;
                sendData.Add((byte)(dtl >> 8 & 0xFF));
                sendData.Add((byte)(dtl & 0xFF));
                sendData.AddRange(msg.DataValue);      // 写入数据
                break;

            default:
                break;
            }
            return(sendData.ToArray());
        }