Beispiel #1
0
        /// <summary>
        /// 从西门子PLC中读取想要的数据,返回结果类说明
        /// </summary>
        /// <param name="type">想要读取的数据类型</param>
        /// <param name="address">读取数据的起始地址</param>
        /// <param name="lengh">读取的数据长度</param>
        /// <returns>返回读取结果</returns>
        public OperateResult <byte[]> ReadFromPLC(SiemensDataType type, ushort address, ushort lengh)
        {
            OperateResult <byte[]> result = new OperateResult <byte[]>();

            byte[] _PLCCommand = new byte[16];
            _PLCCommand[0] = 0x53;
            _PLCCommand[1] = 0x35;
            _PLCCommand[2] = 0x10;
            _PLCCommand[3] = 0x01;
            _PLCCommand[4] = 0x03;
            _PLCCommand[5] = 0x05;
            _PLCCommand[6] = 0x03;
            _PLCCommand[7] = 0x08;

            //指定数据区
            _PLCCommand[8] = type.DataCode;
            _PLCCommand[9] = 0x00;

            //指定数据地址
            _PLCCommand[10] = (byte)(address / 256);
            _PLCCommand[11] = (byte)(address % 256);

            //指定数据长度
            _PLCCommand[12] = (byte)(lengh / 256);
            _PLCCommand[13] = (byte)(lengh % 256);

            _PLCCommand[14] = 0xff;
            _PLCCommand[15] = 0x02;


            //超时验证的线程池技术
            Socket     socket  = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            HslTimeOut timeout = new HslTimeOut()
            {
                WorkSocket = socket
            };

            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout);
                socket.Connect(new IPEndPoint(PLCIpAddress, GetPort()));
                timeout.IsSuccessful = true;
            }
            catch
            {
                ChangePort();
                result.Message = StringResources.ConnectedFailed;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            try
            {
                //连接成功,发送数据
                socket.Send(_PLCCommand);
                byte[] rec_head = NetSupport.ReadBytesFromSocket(socket, 16);
                if (rec_head[8] != 0x00)
                {
                    result.ErrorCode = rec_head[8];
                    Thread.Sleep(10);
                    socket?.Close();
                    return(result);
                }
                result.Content   = NetSupport.ReadBytesFromSocket(socket, lengh);
                result.IsSuccess = true;
                result.Message   = "读取成功";
            }
            catch (Exception ex)
            {
                result.Message = StringResources.SocketIOException + ex.Message;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            Thread.Sleep(10);
            socket?.Close();
            //所有的数据接收完成,进行返回
            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// 向PLC中写入数据,返回值说明
        /// </summary>
        /// <param name="type">要写入的数据类型</param>
        /// <param name="address">要写入的数据地址</param>
        /// <param name="data">要写入的实际数据</param>
        /// <exception cref="ArgumentNullException">写入的数据不能为空</exception>
        /// <returns>返回写入结果</returns>
        public OperateResult <byte[]> WriteIntoPLC(SiemensDataType type, ushort address, byte[] data)
        {
            var result = new OperateResult <byte[]>();

            byte[] _PLCCommand = new byte[16 + data.Length];
            _PLCCommand[0] = 0x53;
            _PLCCommand[1] = 0x35;
            _PLCCommand[2] = 0x10;
            _PLCCommand[3] = 0x01;
            _PLCCommand[4] = 0x03;
            _PLCCommand[5] = 0x03;
            _PLCCommand[6] = 0x03;
            _PLCCommand[7] = 0x08;

            //指定数据区
            _PLCCommand[8] = type.DataCode;
            _PLCCommand[9] = 0x00;

            //指定数据地址
            _PLCCommand[10] = (byte)(address / 256);
            _PLCCommand[11] = (byte)(address % 256);

            //指定数据长度
            _PLCCommand[12] = (byte)(data.Length / 256);
            _PLCCommand[13] = (byte)(data.Length % 256);

            _PLCCommand[14] = 0xff;
            _PLCCommand[15] = 0x02;

            //放置数据
            Array.Copy(data, 0, _PLCCommand, 16, data.Length);


            //超时验证的线程池技术
            var socket  = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var timeout = new HslTimeOut()
            {
                WorkSocket = socket
            };

            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout);
                socket.Connect(new IPEndPoint(PLCIpAddress, PortWrite));
                timeout.IsSuccessful = true;
            }
            catch
            {
                result.Message = StringResources.ConnectedFailed;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            try
            {
                //连接成功,发送数据
                socket.Send(_PLCCommand);
                byte[] rec_head = NetSupport.ReadBytesFromSocket(socket, 16);
                //分析数据
                if (rec_head[8] != 0x00)
                {
                    result.ErrorCode = rec_head[8];
                    Thread.Sleep(10);
                    socket?.Close();
                    return(result);
                }
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                result.IsSuccess = true;
                result.Message   = "写入成功";
            }
            catch (Exception ex)
            {
                result.Message = StringResources.SocketIOException + ex.Message;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            return(result);
        }
Beispiel #3
0
 /// <summary>
 /// 向PLC中写入short数据,返回值说明
 /// </summary>
 /// <param name="type">要写入的数据类型</param>
 /// <param name="address">要写入的数据地址</param>
 /// <param name="data">要写入的实际数据</param>
 /// <exception cref="ArgumentNullException">写入的数据不能为空</exception>
 /// <returns>返回写入结果</returns>
 public OperateResult <byte[]> WriteIntoPLC(SiemensDataType type, ushort address, short[] data)
 {
     return(WriteIntoPLC(type, address, GetBytesFromArray(data, false)));
 }
Beispiel #4
0
 /// <summary>
 /// 向PLC中写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode
 /// </summary>
 /// <param name="type">要写入的数据类型</param>
 /// <param name="address">要写入的数据地址</param>
 /// <param name="data">要写入的实际数据</param>
 /// <param name="length">指定的字符串长度,必须大于0</param>
 /// <returns>返回读取结果</returns>
 public OperateResult <byte[]> WriteUnicodeStringIntoPLC(SiemensDataType type, ushort address, string data, int length)
 {
     byte[] temp = Encoding.Unicode.GetBytes(data);
     temp = ManageBytesLength(temp, length * 2);
     return(WriteIntoPLC(type, address, temp));
 }
Beispiel #5
0
 /// <summary>
 /// 向PLC中写入字符串,编码格式为Unicode
 /// </summary>
 /// <param name="type">要写入的数据类型</param>
 /// <param name="address">要写入的数据地址</param>
 /// <param name="data">要写入的实际数据</param>
 /// <returns>返回读取结果</returns>
 public OperateResult <byte[]> WriteUnicodeStringIntoPLC(SiemensDataType type, ushort address, string data)
 {
     byte[] temp = Encoding.Unicode.GetBytes(data);
     return(WriteIntoPLC(type, address, temp));
 }
Beispiel #6
0
 /// <summary>
 /// 向PLC中写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII
 /// </summary>
 /// <param name="type">要写入的数据类型</param>
 /// <param name="address">要写入的数据地址</param>
 /// <param name="data">要写入的实际数据</param>
 /// <param name="length">指定的字符串长度,必须大于0</param>
 /// <returns>返回读取结果</returns>
 public OperateResultBytes WriteAsciiStringIntoPLC(SiemensDataType type, ushort address, string data, int length)
 {
     byte[] temp = Encoding.ASCII.GetBytes(data);
     temp = ManageBytesLength(temp, length);
     return(WriteIntoPLC(type, address, temp));
 }