/// <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); }
/// <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); }
/// <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))); }
/// <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)); }
/// <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)); }
/// <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)); }