/// <summary> /// Qna_3E地址解析 /// </summary> /// <param name="address"></param> /// <returns></returns> private MitsubishiMCAddress ConvertArg_Qna_3E(string address) { address = address.ToUpper(); var addressInfo = new MitsubishiMCAddress(); switch (address[0]) { case 'M': //M中间继电器 { addressInfo.TypeCode = new byte[] { 0x90 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'X': // X输入继电器 { addressInfo.TypeCode = new byte[] { 0x9C }; addressInfo.DataType = 0x01; addressInfo.Format = 16; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'Y': //Y输出继电器 { addressInfo.TypeCode = new byte[] { 0x9D }; addressInfo.DataType = 0x01; addressInfo.Format = 16; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'D': //D数据寄存器 { addressInfo.TypeCode = new byte[] { 0xA8 }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'W': //W链接寄存器 { addressInfo.TypeCode = new byte[] { 0xB4 }; addressInfo.DataType = 0x00; addressInfo.Format = 16; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'L': //L锁存继电器 { addressInfo.TypeCode = new byte[] { 0x92 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'F': //F报警器 { addressInfo.TypeCode = new byte[] { 0x93 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'V': //V边沿继电器 { addressInfo.TypeCode = new byte[] { 0x94 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'B': //B链接继电器 { addressInfo.TypeCode = new byte[] { 0xA0 }; addressInfo.DataType = 0x01; addressInfo.Format = 16; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'R': //R文件寄存器 { addressInfo.TypeCode = new byte[] { 0xAF }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'S': { //累计定时器的线圈 if (address[1] == 'C') { addressInfo.TypeCode = new byte[] { 0xC6 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //累计定时器的触点 else if (address[1] == 'S') { addressInfo.TypeCode = new byte[] { 0xC7 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //累计定时器的当前值 else if (address[1] == 'N') { addressInfo.TypeCode = new byte[] { 0xC8 }; addressInfo.DataType = 0x00; addressInfo.Format = 100; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } // S步进继电器 else { addressInfo.TypeCode = new byte[] { 0x98 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; } case 'Z': { //文件寄存器ZR区 if (address[1] == 'R') { addressInfo.TypeCode = new byte[] { 0xB0 }; addressInfo.DataType = 0x00; addressInfo.Format = 16; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //变址寄存器 else { addressInfo.TypeCode = new byte[] { 0xCC }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; } case 'T': { // 定时器的当前值 if (address[1] == 'N') { addressInfo.TypeCode = new byte[] { 0xC2 }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //定时器的触点 else if (address[1] == 'S') { addressInfo.TypeCode = new byte[] { 0xC1 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //定时器的线圈 else if (address[1] == 'C') { addressInfo.TypeCode = new byte[] { 0xC0 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } break; } case 'C': { //计数器的当前值 if (address[1] == 'N') { addressInfo.TypeCode = new byte[] { 0xC5 }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //计数器的触点 else if (address[1] == 'S') { addressInfo.TypeCode = new byte[] { 0xC4 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } //计数器的线圈 else if (address[1] == 'C') { addressInfo.TypeCode = new byte[] { 0xC3 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format); } break; } } return(addressInfo); }
/// <summary> /// 读取数据 /// </summary> /// <param name="address">地址</param> /// <param name="length"></param> /// <param name="isBit"></param> /// <param name="setEndian"></param> /// <returns></returns> public Result <byte[]> Read(string address, ushort length, bool isBit = false, bool setEndian = true) { if (!socket?.Connected ?? true) { Connect(); } var result = new Result <byte[]>(); try { //发送读取信息 MitsubishiMCAddress arg = null; byte[] command = null; switch (version) { case MitsubishiVersion.A_1E: arg = ConvertArg_A_1E(address); command = GetReadCommand_A_1E(arg.BeginAddress, arg.TypeCode, length, isBit); break; case MitsubishiVersion.Qna_3E: arg = ConvertArg_Qna_3E(address); command = GetReadCommand_Qna_3E(arg.BeginAddress, arg.TypeCode, length, isBit); break; } result.Requst = string.Join(" ", command.Select(t => t.ToString("X2"))); Result <byte[]> sendResult = new Result <byte[]>(); switch (version) { case MitsubishiVersion.A_1E: var lenght = command[10] + command[11] * 256; if (isBit) { sendResult = SendPackage(command, (int)Math.Ceiling(lenght * 0.5) + 2); } else { sendResult = SendPackage(command, lenght * 2 + 2); } break; case MitsubishiVersion.Qna_3E: sendResult = SendPackage(command); break; } if (!sendResult.IsSucceed) { return(sendResult); } byte[] dataPackage = sendResult.Value; result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2"))); var bufferLength = length; byte[] responseValue = null; switch (version) { case MitsubishiVersion.A_1E: responseValue = new byte[dataPackage.Length - 2]; Array.Copy(dataPackage, 2, responseValue, 0, responseValue.Length); break; case MitsubishiVersion.Qna_3E: if (isBit) { bufferLength = (ushort)Math.Ceiling(bufferLength * 0.5); } responseValue = new byte[bufferLength]; Array.Copy(dataPackage, dataPackage.Length - bufferLength, responseValue, 0, bufferLength); break; } result.Value = responseValue; } catch (SocketException ex) { result.IsSucceed = false; if (ex.SocketErrorCode == SocketError.TimedOut) { result.Err = "连接超时"; result.ErrList.Add("连接超时"); } else { result.Err = ex.Message; result.ErrList.Add(ex.Message); } socket?.SafeClose(); } finally { if (isAutoOpen) { Dispose(); } } return(result.EndTime()); }
/// <summary> /// 写入数据 /// </summary> /// <param name="address"></param> /// <param name="data"></param> /// <param name="isBit"></param> /// <returns></returns> public Result Write(string address, byte[] data, bool isBit = false) { if (!socket?.Connected ?? true) { var connectResult = Connect(); if (!connectResult.IsSucceed) { return(connectResult); } } Result result = new Result(); try { Array.Reverse(data); //发送写入信息 MitsubishiMCAddress arg = null; byte[] command = null; switch (version) { case MitsubishiVersion.A_1E: arg = ConvertArg_A_1E(address); command = GetWriteCommand_A_1E(arg.BeginAddress, arg.TypeCode, data, isBit); break; case MitsubishiVersion.Qna_3E: arg = ConvertArg_Qna_3E(address); command = GetWriteCommand_Qna_3E(arg.BeginAddress, arg.TypeCode, data, isBit); break; } result.Requst = string.Join(" ", command.Select(t => t.ToString("X2"))); Result <byte[]> sendResult = new Result <byte[]>(); switch (version) { case MitsubishiVersion.A_1E: sendResult = SendPackage(command, 2); break; case MitsubishiVersion.Qna_3E: sendResult = SendPackage(command); break; } if (!sendResult.IsSucceed) { return(sendResult); } byte[] dataPackage = sendResult.Value; result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2"))); } catch (SocketException ex) { result.IsSucceed = false; if (ex.SocketErrorCode == SocketError.TimedOut) { result.Err = "连接超时"; result.ErrList.Add("连接超时"); } else { result.Err = ex.Message; result.Exception = ex; result.ErrList.Add(ex.Message); } socket?.SafeClose(); } catch (Exception ex) { result.IsSucceed = false; result.Err = ex.Message; result.Exception = ex; result.ErrList.Add(ex.Message); socket?.SafeClose(); } finally { if (isAutoOpen) { Dispose(); } } return(result.EndTime()); }
/// <summary> /// A_1E地址解析 /// </summary> /// <param name="address"></param> /// <returns></returns> private MitsubishiMCAddress ConvertArg_A_1E(string address) { address = address.ToUpper(); var addressInfo = new MitsubishiMCAddress(); switch (address[0]) { case 'X': //X输入寄存器 { addressInfo.TypeCode = new byte[] { 0x58, 0x20 }; addressInfo.DataType = 0x01; addressInfo.Format = 8; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'Y': //Y输出寄存器 { addressInfo.TypeCode = new byte[] { 0x59, 0x20 }; addressInfo.DataType = 0x01; addressInfo.Format = 8; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'M': //M中间寄存器 { addressInfo.TypeCode = new byte[] { 0x4D, 0x20 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'S': //S状态寄存器 { addressInfo.TypeCode = new byte[] { 0x53, 0x20 }; addressInfo.DataType = 0x01; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'D': //D数据寄存器 { addressInfo.TypeCode = new byte[] { 0x44, 0x20 }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; case 'R': //R文件寄存器 { addressInfo.TypeCode = new byte[] { 0x52, 0x20 }; addressInfo.DataType = 0x00; addressInfo.Format = 10; addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format); } break; } return(addressInfo); }