/// <summary> /// 解析接收到的数据 /// </summary> /// <param name="bData"></param> /// <param name="mFunctionCode"></param> public ModbusData ReceiveAnalysis(byte[] bData) { ModbusData moddata = null; try { int mReceiveByteCount = bData.Length; #region 接收到的数据 moddata = new ModbusData(); moddata.SlaveID = bData[0]; //设备ID moddata.Code = bData[1]; //功能 moddata.FunctionCode = (FunctionCode)bData[1]; moddata.Data = bData; moddata.FunctionCode = (FunctionCode)bData[1]; moddata.DataLength = bData[2]; //当前数据的字节数 moddata.MCount = moddata.DataLength / 2; //返回的寄存器个数 Array.Copy(bData, bData.Length - 3, moddata.CRCData, 0, 2); //拷贝校验码 #endregion } catch (Exception ex) { strErrMsg = ex.Message.ToString(); } return(moddata); }
/// <summary> /// 获取某个参数的解析数据,如果该参数还没有接收到数返回为null /// </summary> /// <param name="server"></param> /// <param name="device"></param> /// <param name="para"></param> /// <param name="datas"></param> /// <param name="datatime"></param> /// <returns></returns> protected override IOData Analysis(IO_SERVER server, IO_COMMUNICATION communication, IO_DEVICE device, IO_PARA para, byte[] datas, DateTime datatime) { try { //02号功能码 (DI离散输入量) //01号和05号功能码 (DI离散输入量) //03号功能码 (HR保持寄存器) //04号功能码 (AR保持寄存器) //08号功能码 (诊断) //15号功能码 (强制多个寄存器) //07号功能码 (读不正常状态) //构造字符串 // 线圈状态 = 1, //读输入状态 = 2, //读保持型寄存器 = 3, //读输入型寄存器 = 4, //强制单个线圈 = 5, //写单个寄存器 = 6, //强制多个线圈 = 15, //写多个寄存器 = 16, //读变量 = 20, //写变量 = 21, //错误信息 = 80, //NONE string parastring = para.IO_PARASTRING; ModbusData analysisData = ModbusAnalysis.ReceiveAnalysis(datas); IOData data = new IOData(); data.QualityStamp = QualityStamp.BAD; data.ParaValue = "-9999"; data.Date = DateTime.Now; data.ID = para.IO_ID; data.CommunicationID = communication.IO_COMM_ID; data.ParaName = para.IO_NAME; data.ServerID = server.SERVER_ID; string[] paras = parastring.Split(',');//读取参数设置的所有参数格式 if (paras.Length < 8) { return(data); } int function = int.Parse(paras[0].Split(':')[1].Trim()); //功能码 int deviation = int.Parse(paras[1].Split(':')[1].Trim()); //偏置量 if (Convert.ToInt32(analysisData.FunctionCode) > 30) //大于80标识返回的是错误信息 { base.DeviceException(analysisData.FunctionCode.ToString()); } if (Convert.ToInt32(analysisData.FunctionCode) != function)//如果接收的数据功能码和参数功能码不一致,则放弃该数据,否则继续下步解析 { return(data); } //判断寄存器存储的数据类型,不同的类型占用数据字节不一样 Type datatype = typeof(short); int numunit = 1;//判读当前占用的字节 switch (paras[2].Split(':')[1].Trim()) { case "8位有符号": datatype = typeof(sbyte); numunit = 2; break; case "8位无符号": datatype = typeof(byte); numunit = 2; break; case "16位有符号": datatype = typeof(Int16); numunit = 2; break; case "16位无符号": datatype = typeof(UInt16); numunit = 2; break; case "32位有符号": datatype = typeof(Int32); numunit = 4; break; case "32位无符号": datatype = typeof(UInt32); numunit = 4; break; case "字符型": datatype = typeof(String); break; case "32位浮点型": datatype = typeof(float); numunit = 4; break; case "64位双精度浮点型": datatype = typeof(double); numunit = 8; break; default: datatype = typeof(byte); numunit = 2; break; } bool isbanary = false;//是否按位读写 int banarynumber = int.Parse(paras[6].Split(':')[1].Trim()); if (paras[5].Split(':')[1].Trim() == "1") { isbanary = true; } else { isbanary = false; } if (paras.Length == 8) { if (paras[7].Split('|')[1].Trim() == BitStoreMode.低位字节在前.ToString()) { data.BitStoreMode = BitStoreMode.低位字节在前; } else { data.BitStoreMode = BitStoreMode.高位字节在前; } } //判断当前返回寄存器的个数 if (deviation < analysisData.StartAddress || numunit > analysisData.MCount) { //返回空值表示当前寄存器 return(null); } if (isbanary == false) { try { byte[] valuebyte = new byte[numunit]; int index = (deviation - 1) * 2 + 3; if (index <= 0 || index >= analysisData.Data.Length) { base.DeviceException("error=10114 模拟量数据解析错误 数据点配置超过返回的数据点长度"); } if (analysisData.Data.Length > numunit + index) { Array.Copy(analysisData.Data, index, valuebyte, 0, valuebyte.Length);//拷贝数据 data.datas = valuebyte; data.DataType = datatype; data.Date = DateTime.Now; data.ID = analysisData.SlaveID.ToString(); data.ParaName = para.IO_NAME; data.ParaValue = ConvertType.BytesToBit(valuebyte, datatype, data.BitStoreMode).ToString(); if (data.ParaValue == null) { data.ParaValue = "-9999"; } data.ParaString = parastring; if (data.ParaValue != "-9999") { data.QualityStamp = QualityStamp.GOOD; } else { data.QualityStamp = QualityStamp.BAD; } } } catch (Exception emx) { base.DeviceException("error HA111" + emx.Message); } } else //如果按照位读取 { int index = (deviation - 1) * 2 + 3; if (index <= 0 || index >= analysisData.Data.Length) { this.DeviceException("error= HA11115开关量数据解析错误 数据点配置超过返回的数据点长度"); } if (analysisData.Data.Length > 2 + index) { try { byte[] valuebyte = new byte[2]; //按位读取的话,首先读取一个寄存器地址,并将该地址 Array.Copy(analysisData.Data, index, valuebyte, 0, valuebyte.Length); //拷贝数据 object num = ConvertType.BytesToBit(valuebyte, datatype, data.BitStoreMode).ToString(); if (datatype == typeof(UInt16)) { data.ParaValue = string.Format("{0}", Convert.ToUInt16(num) >> banarynumber & 1); data.QualityStamp = QualityStamp.GOOD; } else if (datatype == typeof(Int16)) { data.ParaValue = string.Format("{0}", Convert.ToInt16(num) >> banarynumber & 1); data.QualityStamp = QualityStamp.GOOD; } else if (datatype == typeof(sbyte)) { data.ParaValue = string.Format("{0}", Convert.ToSByte(num) >> banarynumber & 1); data.QualityStamp = QualityStamp.GOOD; } else if (datatype == typeof(byte)) { data.ParaValue = string.Format("{0}", Convert.ToByte(num) >> banarynumber & 1); data.QualityStamp = QualityStamp.GOOD; } else if (datatype == typeof(Int32)) { data.ParaValue = string.Format("{0}", Convert.ToInt32(num) >> banarynumber & 1); data.QualityStamp = QualityStamp.GOOD; } else if (datatype == typeof(UInt32)) { data.ParaValue = string.Format("{0}", Convert.ToUInt32(num) >> banarynumber & 1); data.QualityStamp = QualityStamp.GOOD; } if (banarynumber < 0 && banarynumber >= 16) { this.DeviceException("error=D10001 数据位数应该在0-15的范围内"); data.QualityStamp = QualityStamp.BAD; data.ParaValue = "-9999"; } data.datas = valuebyte; data.DataType = datatype; data.Date = DateTime.Now; data.ID = analysisData.SlaveID.ToString(); data.ParaName = para.IO_NAME; data.ParaString = parastring; } catch (Exception emx) { this.DeviceException(emx.Message); } } } return(data); } catch (Exception emx) { this.DeviceException(emx.Message); } return(null); }