private void ModbusRtu_OnReceiveDataChanged(object sender, ReceiveDataEventArgs e) { List <byte> recevideData = e.ReceiveData; this.canSendNextRequestCommandBytes = true; if (null != recevideData) { this.currentRecivedByteData = recevideData; DataAnalyzeMode dataAnalyzeMode = ModbusConfigService.GetCurrentDataAnalyzeMode(); AnalyzeRecivedDataReponse reponse = RecivedDataAnalyzer.AnalyzeRecivedData(dataAnalyzeMode, this.currentRequestByteData, this.currentRecivedByteData); if (reponse.ModbusReponseSuccess && reponse.AnalyzeRecivedDataSuccess) { ProcessRegisterValue(reponse.Registers, this.allDataPoints); } //if (reponse.DataPointType == DataPointType.WriteAndReadByFunNum01 // || reponse.DataPointType == DataPointType.WriteAndReadByFunNum03) //{ // //TODO:分析写寄存器接受侦 //} } }
/// <summary> /// 解析响应字节流 /// </summary> /// <param name="dataAnalyzeMode">数据解析方式</param> /// <param name="requestByteData">请求字节流</param> /// <param name="receviceByteData">响应字节流</param> /// <returns></returns> public static AnalyzeRecivedDataReponse AnalyzeRecivedDataStatic(DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> receviceByteData) { var requestBytesWithOutTcpHeader = GetDataFromRequestDataWithOutTcpHeader(requestByteData); var receviceBytesWithOutTcpHeader = GetDataFromResponseDataWithOutTcpHeader(receviceByteData); return(ModbusRecivedDataAnalyzer.AnalyzeRecivedData(dataAnalyzeMode, requestBytesWithOutTcpHeader, receviceBytesWithOutTcpHeader)); }
/// <summary> /// 获取数据解析方式 /// </summary> /// <param name="modbusConfigFile">配置文件物理路径(包含名称+后缀):例如:Config/ModbusConfig.xml </param> /// <returns></returns> public static DataAnalyzeMode GetDataAnalyzeModeFromConfigFile(string modbusConfigFile) { DataAnalyzeMode dataAnalyzeMode = DataAnalyzeMode.DataHighToLow; try { if (System.IO.File.Exists(modbusConfigFile)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(modbusConfigFile); XmlNode dataAnalyzeModeNode = xmlDoc.SelectSingleNode("/ModbusConfig/DataAnalyzeMode"); XmlElement dataAnalyzeModeElement = (XmlElement)dataAnalyzeModeNode; if (dataAnalyzeModeElement != null) { dataAnalyzeMode = (DataAnalyzeMode)Enum.Parse(typeof(DataAnalyzeMode), dataAnalyzeModeElement.GetAttribute("Value"), true); } } } catch (Exception) { throw; } return(dataAnalyzeMode); }
public static void SaveDataAnalyzeModeToConfigFile(DataAnalyzeMode dataAnalyzeMode) { try { string modbusConfigRelativePath = ApplicationSettingsFactory.GetApplicationSettings().ModbusConfigFilePath; string modbusConfigFile = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, modbusConfigRelativePath); if (System.IO.File.Exists(modbusConfigFile)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(modbusConfigFile); XmlNode dataAnalyzeModeNode = xmlDoc.SelectSingleNode("/ModbusConfig/DataAnalyzeMode"); XmlElement dataAnalyzeModeElement = (XmlElement)dataAnalyzeModeNode; if (dataAnalyzeModeElement != null) { dataAnalyzeModeElement.SetAttribute("Value", Convert.ToString(dataAnalyzeMode)); } xmlDoc.Save(modbusConfigFile); } } catch (Exception) { throw; } }
public void SetDataPointRealValueByFunNun16Test() { ModbusRTUServer modbusRTUServer = new ModbusRTUServer(); modbusRTUServer.InitializeFromConfigFile(modbusConfigFile, serialPortConfigFile); List <DataPoint> dataPoints = new List <DataPoint>(); modbusRTUServer.SerialPort.OnCurrentRequestDataChanged += new EventHandler <RequstDataEventArgs>(SerialPort_OnRequestDataChanged); modbusRTUServer.SerialPort.OnCurrentReceiveDataChanged += new EventHandler <ReceiveDataEventArgs>(SerialPort_OnReceiveDataChanged); dataAnalyzeMode = modbusRTUServer.DataAnalyzeMode; allDataPoints = modbusRTUServer.AllDataPoints; dataPoints.Add(new DataPoint() { DeviceAddress = 1, StartRegisterAddress = 83, DataPointType = DataPointType.WriteAndReadByFunNum03, DataPointDataType = DataPointDataType.F32, RealTimeValue = -1, ValueToSet = 101.7 }); List <List <byte> > writeRegisterCommandBytes = ModbusRTU.CreateWriteRegisterCommands(DataAnalyzeMode.DataHighToLow, dataPoints); if (modbusRTUServer.SerialPort.TryOpenSerialPort()) { foreach (var writeBytes in writeRegisterCommandBytes) { modbusRTUServer.SerialPort.WriteSerialPort(writeBytes.ToArray()); } } }
public static DataAnalyzeMode GetDataAnalyzeModeFromConfigFile() { DataAnalyzeMode dataAnalyzeMode = DataAnalyzeMode.DataHighToLow; try { string modbusConfigRelativePath = ApplicationSettingsFactory.GetApplicationSettings().ModbusConfigFilePath; string modbusConfigFile = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, modbusConfigRelativePath); if (System.IO.File.Exists(modbusConfigFile)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(modbusConfigFile); XmlNode dataAnalyzeModeNode = xmlDoc.SelectSingleNode("/ModbusConfig/DataAnalyzeMode"); XmlElement dataAnalyzeModeElement = (XmlElement)dataAnalyzeModeNode; if (dataAnalyzeModeElement != null) { dataAnalyzeMode = (DataAnalyzeMode)Enum.Parse(typeof(DataAnalyzeMode), dataAnalyzeModeElement.GetAttribute("Value"), true); } } } catch (Exception) { throw; } return(dataAnalyzeMode); }
public ModbusConfigService(IDataPointRepository dataPointRepository, IModuleRepository moduleRepository) { _dataPointRepository = dataPointRepository; _moduleRepository = moduleRepository; currentDataAnalyzeMode = DataAnalyzeModeConfiger.GetDataAnalyzeModeFromConfigFile(); }
/// <summary> /// 初始化运行环境 /// </summary> /// <param name="modbusConfigFile">配置文件物理路径(包含名称+后缀):例如:Config/ModbusConfig.xml</param> /// <param name="serialPortConfigFile">配置文件获路径(包含文件名+后缀)例如:Config/SerialPortConfig.xml</param> public void InitializeFromConfigFile(string modbusConfigFile, string serialPortConfigFile) { ModbusConfig modbusConfig = new ModbusConfig(); modbusConfig = GetModbusConfigFromFile(modbusConfigFile); dataAnalyzeMode = modbusConfig.DataAnalyzeMode; allDataPoints = modbusConfig.DataPointsFromConfigFileList.ToList(); allReadRegisterCommands = GetReadRegisterCommands(allDataPoints); //初始化串口 var serialPorObj = CreateSerialPortFromConfigFile(serialPortConfigFile); this.serialPort = new SerialPortHelper(serialPorObj); }
/// <summary> /// 设置多个线圈的值 /// 根据Modbus协议,功能码15(0F),接收帧为 /// 11 0F 0013 0009 /// 并不包含寄存器的值。 /// </summary> /// <param name="requestByteData"></param> /// <param name="receviceByteData"></param> /// <returns></returns> private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum015( DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> receviceByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); //根据Modbus协议,功能码15(0F),接收帧为 //11 0F 0013 0009 //并不包含寄存器的值。 //故返回一个空的List<Register> try { //接受侦receviceByteData中寄存器值的数据之前的字节数: //deviceAddress、funNum、ecevideByteData[2]个占1个字节 int byteCountBeforeDataRegion = 4; //避免数据返回不完整引发下标溢出 if (receviceByteData.Count > (byteCountBeforeDataRegion + 2) && requestByteData.Count > (byteCountBeforeDataRegion + 2)) { if (requestByteData[byteCountBeforeDataRegion] == receviceByteData[byteCountBeforeDataRegion] && requestByteData[byteCountBeforeDataRegion + 1] == receviceByteData[byteCountBeforeDataRegion + 1]) { reponse.ModbusReponseSuccess = true; } else { reponse.ModbusReponseSuccess = false; } } } catch (Exception ex) { reponse.AnalyzeRecivedDataSuccess = false; //LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!"); reponse.ErrorMsg = "AnalyzeRecivedDataByFunNum15->解析Modbus接收帧时发生异常!" + ex.Message; return(reponse); } return(reponse); }
public void GetDataPointRealValueTest() { ModbusRTUServer modbusRTUServer = new ModbusRTUServer(); modbusRTUServer.InitializeFromConfigFile(modbusConfigFile, serialPortConfigFile); modbusRTUServer.SerialPort.OnCurrentRequestDataChanged += new EventHandler <RequstDataEventArgs>(SerialPort_OnRequestDataChanged); modbusRTUServer.SerialPort.OnCurrentReceiveDataChanged += new EventHandler <ReceiveDataEventArgs>(SerialPort_OnReceiveDataChanged); dataAnalyzeMode = modbusRTUServer.DataAnalyzeMode; allDataPoints = modbusRTUServer.AllDataPoints; if (modbusRTUServer.SerialPort.TryOpenSerialPort()) { foreach (var readRegisterCommand in modbusRTUServer.AllReadRegisterCommands) { modbusRTUServer.SerialPort.WriteSerialPort(readRegisterCommand.ReadCommand.ToArray()); } } }
/// <summary> /// 设置多个寄存器的值 ///根据Modbus协议,功能码16(10H),接收帧为 ///11 0F 0013 0009 ///并不包含寄存器的值。 /// </summary> /// <param name="requestByteData"></param> /// <param name="recevideByteData"></param> /// <returns></returns> private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum16( DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> recevideByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); //根据Modbus协议,功能码16(10H),接收帧为 //11 0F 0013 0009 //并不包含寄存器的值。 //故返回一个空的List<Register> try { int byteCountBeforeDataRegion = 4; //避免数据返回不完整引发下标溢出 if (recevideByteData.Count > (byteCountBeforeDataRegion + 2) && requestByteData.Count > (byteCountBeforeDataRegion + 2)) { if (requestByteData[byteCountBeforeDataRegion] == recevideByteData[byteCountBeforeDataRegion] && requestByteData[byteCountBeforeDataRegion + 1] == recevideByteData[byteCountBeforeDataRegion + 1]) { reponse.ModbusReponseSuccess = true; } else { reponse.ModbusReponseSuccess = false; } } } catch (Exception) { reponse.AnalyzeRecivedDataSuccess = false; LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!"); return(reponse); } return(reponse); }
public SetDataAnalyzeModeResponse SetDataAnalyzeMode(SetDataAnalyzeModeRequest request) { SetDataAnalyzeModeResponse response = new SetDataAnalyzeModeResponse(); DataAnalyzeMode oldDataAnalyzeMode = currentDataAnalyzeMode; try { currentDataAnalyzeMode = request.DataAnalyzeMode; DataAnalyzeModeConfiger.SaveDataAnalyzeModeToConfigFile(request.DataAnalyzeMode); } catch (Exception ex) { currentDataAnalyzeMode = oldDataAnalyzeMode; string message = "保存数据解析模式失败"; response.ResponseSucceed = false; LoggingFactory.GetLogger().WriteDebugLogger(message + ex.Message); } return(response); }
public GetDataAnalyzeModeResponse GetDataAnalyzeMode() { GetDataAnalyzeModeResponse response = new GetDataAnalyzeModeResponse(); DataAnalyzeMode oldDataAnalyzeMode = currentDataAnalyzeMode; try { currentDataAnalyzeMode = DataAnalyzeModeConfiger.GetDataAnalyzeModeFromConfigFile(); response.DataAnalyzeMode = currentDataAnalyzeMode; } catch (Exception ex) { currentDataAnalyzeMode = oldDataAnalyzeMode; string message = "获取数据解析模式失败"; response.ResponseSucceed = false; LoggingFactory.GetLogger().WriteDebugLogger(message + ex.Message); } return(response); }
/// <summary> /// 设置数据解析方式 /// </summary> /// <param name="dataAnalyzeMode">数据解析方式</param> /// <param name="modbusConfigFile">配置文件物理路径(包含名称+后缀):例如:Config/ModbusConfig.xml </param> public static void SaveDataAnalyzeModeToConfigFile(DataAnalyzeMode dataAnalyzeMode, string modbusConfigFile) { try { if (System.IO.File.Exists(modbusConfigFile)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(modbusConfigFile); XmlNode dataAnalyzeModeNode = xmlDoc.SelectSingleNode("/ModbusConfig/DataAnalyzeMode"); XmlElement dataAnalyzeModeElement = (XmlElement)dataAnalyzeModeNode; if (dataAnalyzeModeElement != null) { dataAnalyzeModeElement.SetAttribute("Value", Convert.ToString(dataAnalyzeMode)); } xmlDoc.Save(modbusConfigFile); } } catch (Exception) { throw; } }
/// <summary> /// 根据数据点获取写寄存器命令(若干个请求字节流) /// </summary> /// <param name="dataAnalyzeMode">数据解析模式</param> /// <param name="dataPoints"> /// dataPoints中的DataPoint不必满足如下条件: /// 1.设备地址相同; /// 2.读寄存器用的功能码相同; /// 3.相邻DataPoint的寄存器地址是连续的。 /// /// 该方法内部将自动调整为以上条件 /// </param> /// <returns></returns> public static List <List <byte> > CreateWriteRegisterCommands(DataAnalyzeMode dataAnalyzeMode, List <DataPoint> dataPoints) { List <List <byte> > writeRegisterCommands = new List <List <byte> >(); if (null == dataPoints || dataPoints.Count < 1) { return(writeRegisterCommands); } List <List <DataPoint> > dataPointsGroupedForWrite = DataPointGrouper.GroupingDataPointsForWriteRegister(dataPoints); foreach (var dataPointsGroup in dataPointsGroupedForWrite) { List <List <byte> > requestCommadBytes = TCPRequestCommandByteStreamCreator.CreateRequestCommandByteStreamForWriteRegisterBy(dataAnalyzeMode, dataPointsGroup); foreach (var requestCommadByte in requestCommadBytes) { writeRegisterCommands.Add(requestCommadByte); } } return(writeRegisterCommands); }
/// <summary> /// 写单个寄存器 /// </summary> /// <param name="requestByteData"></param> /// <param name="recevideByteData"></param> /// <returns></returns> private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum06( DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> recevideByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); try { int deviceAddress = recevideByteData[0]; //byte[] startRegisterByte = new byte[] { recevideByteData[2], recevideByteData[3] }; //int startRegisterAddress = BitConverter.ToUInt16(startRegisterByte, 0); int startRegisterAddress = requestByteData[2] * 256 + requestByteData[3]; //byte[] valueToSetByte = new byte[] { requestByteData[4], requestByteData[5] }; //double valueToSet = BitConverter.ToDouble(valueToSetByte, 0); //接受侦recevideByteData中寄存器值的数据之前的字节数: //deviceAddress、funNum、ecevideByteData[2]个占1个字节 int byteCountBeforeDataRegion = 4; int countOfRegisterToRead = 1; //避免数据返回不完整引发下标溢出 if (recevideByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2) && requestByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2)) { if (requestByteData[byteCountBeforeDataRegion] == recevideByteData[byteCountBeforeDataRegion] && requestByteData[byteCountBeforeDataRegion + 1] == recevideByteData[byteCountBeforeDataRegion + 1]) { reponse.ModbusReponseSuccess = true; } else { reponse.ModbusReponseSuccess = false; } Register register = new Register(); register.DeviceAddress = deviceAddress; register.RegisterAddress = startRegisterAddress; //byte[] bytevalues = new byte[] // { // recevideByteData[byteCountBeforeDataRegion], // recevideByteData[byteCountBeforeDataRegion + 1], // }; //register.RegisterValue = BitConverter.ToUInt16(bytevalues, 0); if (dataAnalyzeMode == DataAnalyzeMode.DataHighToLow) { //HL HL register.RegisterValue = (ushort)(recevideByteData[byteCountBeforeDataRegion] * 256 + recevideByteData[byteCountBeforeDataRegion + 1]); register.LowToHighDataBytes.Add(recevideByteData[byteCountBeforeDataRegion + 1]); //低位 register.LowToHighDataBytes.Add(recevideByteData[byteCountBeforeDataRegion]); //高位 } else { //LH LH register.RegisterValue = (ushort)(recevideByteData[byteCountBeforeDataRegion] + recevideByteData[byteCountBeforeDataRegion + 1] * 256); register.LowToHighDataBytes.Add(recevideByteData[byteCountBeforeDataRegion]); //低位 register.LowToHighDataBytes.Add(recevideByteData[byteCountBeforeDataRegion + 1]); //高位 } reponse.Registers.Add(register); } } catch (Exception) { reponse.AnalyzeRecivedDataSuccess = false; LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!"); return(reponse); } return(reponse); }
/// <summary> /// 写单个线圈 /// </summary> /// <param name="requestByteData"></param> /// <param name="recevideByteData"></param> /// <returns></returns> private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum05( DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> recevideByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); try { int deviceAddress = recevideByteData[0]; int startRegisterAddress = requestByteData[2] * 256 + requestByteData[3]; //接受侦recevideByteData中寄存器值的数据之前的字节数: //deviceAddress、funNum、ecevideByteData[2]个占1个字节 int byteCountBeforeDataRegion = 4; int countOfRegisterToRead = 1; //避免数据返回不完整引发下标溢出 if (recevideByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2) && requestByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2)) { if (requestByteData[byteCountBeforeDataRegion] == recevideByteData[byteCountBeforeDataRegion] && requestByteData[byteCountBeforeDataRegion + 1] == recevideByteData[byteCountBeforeDataRegion + 1]) { reponse.ModbusReponseSuccess = true; } else { reponse.ModbusReponseSuccess = false; } Register register = new Register(); register.DeviceAddress = deviceAddress; register.RegisterAddress = startRegisterAddress; byte fistByteInRecevide = recevideByteData[byteCountBeforeDataRegion]; byte secondByteInRecevide = recevideByteData[byteCountBeforeDataRegion + 1]; byte fistByteInRequest = requestByteData[byteCountBeforeDataRegion]; byte secondByteInRequest = requestByteData[byteCountBeforeDataRegion + 1]; if (0xFF == fistByteInRecevide && 0x00 == secondByteInRecevide) { register.RegisterValue = 1; //开:FF00 } else if (0x00 == fistByteInRecevide && 0x00 == secondByteInRecevide) { register.RegisterValue = 0; //关:0000 } reponse.Registers.Add(register); } } catch (Exception) { reponse.AnalyzeRecivedDataSuccess = false; LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!"); return(reponse); } return(reponse); }
private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum03( DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> recevideByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); try { //接受侦recevideByteData中寄存器值的数据之前的字节数: //deviceAddress、funNum、recevideByteData[2]个占1个字节 int byteCountBeforeDataRegion = 3; //避免数据返回不完整引发下标溢出 if (recevideByteData.Count > (byteCountBeforeDataRegion + recevideByteData[2])) { int deviceAddress = requestByteData[0]; int startRegisterAddress = requestByteData[2] * 256 + requestByteData[3]; //寄存器的个数 int countOfRegisterHadRead = recevideByteData[2] / 2; for (int i = 0; i < countOfRegisterHadRead; i++) { Register register = new Register(); register.DeviceAddress = deviceAddress; register.RegisterAddress = startRegisterAddress; if (dataAnalyzeMode == DataAnalyzeMode.DataHighToLow) { //HL HL register.RegisterValue = (ushort)(recevideByteData[2 * i + byteCountBeforeDataRegion] * 256 + recevideByteData[2 * i + byteCountBeforeDataRegion + 1]); //先加入低位 register.LowToHighDataBytes.Add(recevideByteData[2 * i + byteCountBeforeDataRegion + 1]); //后加入高位 register.LowToHighDataBytes.Add(recevideByteData[2 * i + byteCountBeforeDataRegion]); } else { //LH LH register.RegisterValue = (ushort)(recevideByteData[2 * i + byteCountBeforeDataRegion] + recevideByteData[2 * i + byteCountBeforeDataRegion + 1] * 256); //先加入低位 register.LowToHighDataBytes.Add(recevideByteData[2 * i + byteCountBeforeDataRegion]); //后加入高位 register.LowToHighDataBytes.Add(recevideByteData[2 * i + byteCountBeforeDataRegion + 1]); } ; reponse.Registers.Add(register); ++startRegisterAddress; } } } catch (Exception) { reponse.AnalyzeRecivedDataSuccess = false; LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!"); return(reponse); } return(reponse); }
public static AnalyzeRecivedDataReponse AnalyzeRecivedData(DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> recevideByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); //TODO:暂时注释,调试完后取消注释 if (!RecivedDataCorrespondToRequesData(requestByteData, recevideByteData)) { reponse.ModbusReponseSuccess = false; return(reponse); } if (recevideByteData.Count < 2 || requestByteData.Count < 2) { //无法获取设备地址、功能码 string message = "请求帧或接受帧中不存在设备地址或功能码。"; LoggingFactory.GetLogger().WriteDebugLogger(message); reponse.ModbusReponseSuccess = false; return(reponse); } if (requestByteData[0] != recevideByteData[0] || requestByteData[1] != recevideByteData[1]) { string message = "请求帧与接受帧的设备地址或功能码不对应," + "请求接受的数据不对应。"; LoggingFactory.GetLogger().WriteDebugLogger(message); reponse.AnalyzeRecivedDataSuccess = false; return(reponse); } int funNum = recevideByteData[1]; if (1 == funNum) { reponse = AnalyzeRecivedDataByFunNum01(dataAnalyzeMode, requestByteData, recevideByteData); } if (3 == funNum) { reponse = AnalyzeRecivedDataByFunNum03(dataAnalyzeMode, requestByteData, recevideByteData); } if (5 == funNum) { reponse = AnalyzeRecivedDataByFunNum05(dataAnalyzeMode, requestByteData, recevideByteData); } if (6 == funNum) { reponse = AnalyzeRecivedDataByFunNum06(dataAnalyzeMode, requestByteData, recevideByteData); } if (15 == funNum) { reponse = AnalyzeRecivedDataByFunNum015(dataAnalyzeMode, requestByteData, recevideByteData); } if (16 == funNum) { reponse = AnalyzeRecivedDataByFunNum16(dataAnalyzeMode, requestByteData, recevideByteData); } return(reponse); }
private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum01( DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> recevideByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); try { int deviceAddress = requestByteData[0]; int startRegisterAddress = requestByteData[2] * 256 + requestByteData[3]; int countOfRegisterToRead = requestByteData[4] * 256 + requestByteData[5]; //接受侦recevideByteData中寄存器值的数据之前的字节数: //deviceAddress、funNum、recevideByteData[2]个占1个字节 int byteCountBeforeDataRegion = 3; //数据区表示寄存器值的字节数 int registerValueByteCount = recevideByteData[2]; //避免数据返回不完整引发下标溢出 if (recevideByteData.Count > (byteCountBeforeDataRegion + recevideByteData[2])) { byte byteData = 0; List <UInt16> totalRecvVal = new List <ushort>(); for (int k = 0; k < registerValueByteCount; k++) { byteData = recevideByteData[byteCountBeforeDataRegion + k]; //解析01功能码的顺序是从每个返回字节的低位到高位 totalRecvVal.Add((UInt16)(byteData & 0x01)); //一个字节中的最低位 totalRecvVal.Add((UInt16)((byteData & 0x02) >> 1)); totalRecvVal.Add((UInt16)((byteData & 0x04) >> 2)); totalRecvVal.Add((UInt16)((byteData & 0x08) >> 3)); totalRecvVal.Add((UInt16)((byteData & 0x10) >> 4)); totalRecvVal.Add((UInt16)((byteData & 0x20) >> 5)); totalRecvVal.Add((UInt16)((byteData & 0x40) >> 6)); totalRecvVal.Add((UInt16)((byteData & 0x80) >> 7)); //一个字节中的最高位,先加入高位data } //条件:i < countOfRegisterToRead 是要求实际要读多少个寄存器的值,就存储多少个值 //totalRecvVal中可能存在不表示寄存器值的多余数据, //通过条件:i < countOfRegisterToRead,提取有效数据,剔除无效数据 for (int i = 0; i < totalRecvVal.Count && i < countOfRegisterToRead; i++) { Register register = new Register(); register.DeviceAddress = deviceAddress; register.RegisterAddress = startRegisterAddress; register.RegisterValue = totalRecvVal[i]; reponse.Registers.Add(register); ++startRegisterAddress; } } } catch (Exception) { reponse.AnalyzeRecivedDataSuccess = false; LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!"); return(reponse); } return(reponse); }
private static List <List <byte> > CreateRequestCommandByteStreamForFunNum16(DataAnalyzeMode dataAnalyzeMode, List <DataPoint> dataPoints) { List <List <byte> > requestCommandByteStreams = new List <List <byte> >(); DataPoint firstDataPoint = dataPoints.First(); int theFirstRegisterAddress = dataPoints.First().StartRegisterAddress; switch (firstDataPoint.DataPointDataType) { case DataPointDataType.S16: { FunNum16CustomerRequestData <short> customerRequestData = new FunNum16CustomerRequestData <short>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((short)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.U16: { FunNum16CustomerRequestData <ushort> customerRequestData = new FunNum16CustomerRequestData <ushort>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((ushort)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.S32: { FunNum16CustomerRequestData <int> customerRequestData = new FunNum16CustomerRequestData <int>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((int)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.U32: { FunNum16CustomerRequestData <uint> customerRequestData = new FunNum16CustomerRequestData <uint>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((uint)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.S64: { FunNum16CustomerRequestData <long> customerRequestData = new FunNum16CustomerRequestData <long>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((long)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.U64: { FunNum16CustomerRequestData <ulong> customerRequestData = new FunNum16CustomerRequestData <ulong>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((ulong)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.F32: { FunNum16CustomerRequestData <float> customerRequestData = new FunNum16CustomerRequestData <float>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((float)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.D64: { FunNum16CustomerRequestData <double> customerRequestData = new FunNum16CustomerRequestData <double>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum16; customerRequestData.StartingRegisterAddress = (ushort)theFirstRegisterAddress; foreach (var dataPoint in dataPoints) { customerRequestData.PresetData.Add((double)dataPoint.ValueToSet); } requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.Bit: break; default: break; } return(requestCommandByteStreams); }
/// <summary> /// 因为:功能码06是设置单个寄存器(占两字节,所以T的类型只能为short ushort)的值 /// </summary> /// <param name="dataPoints"></param> /// <returns></returns> private static List <List <byte> > CreateRequestCommandByteStreamForFunNum06(DataAnalyzeMode dataAnalyzeMode, List <DataPoint> dataPoints) { List <List <byte> > requestCommandByteStreams = new List <List <byte> >(); DataPoint firstDataPoint = dataPoints.First(); int theFirstRegisterAddress = dataPoints.First().StartRegisterAddress; switch (firstDataPoint.DataPointDataType) { case DataPointDataType.S16: { FunNum06CustomerRequestData <short> customerRequestData = new FunNum06CustomerRequestData <short>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum06; customerRequestData.RegisterAddress = (ushort)theFirstRegisterAddress; customerRequestData.PresetData = (short)firstDataPoint.ValueToSet; requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.U16: { FunNum06CustomerRequestData <ushort> customerRequestData = new FunNum06CustomerRequestData <ushort>(); customerRequestData.DataAnalyzeMode = dataAnalyzeMode; customerRequestData.DeviceAddress = (byte)firstDataPoint.DeviceAddress; customerRequestData.FunctionNum = FunctionNumType.FunctionNum06; customerRequestData.RegisterAddress = (ushort)theFirstRegisterAddress; customerRequestData.PresetData = (ushort)firstDataPoint.ValueToSet; requestCommandByteStreams = TCPRequesCommandCreator.CreateRequestCommandByteStream(customerRequestData); break; } case DataPointDataType.S32: case DataPointDataType.U32: case DataPointDataType.S64: case DataPointDataType.U64: case DataPointDataType.F32: case DataPointDataType.D64: //因为:功能码06是设置单个寄存器(占两字节,所以T的类型只能为short ushort)的值 //其他T类型只能由功能码16(设置多个寄存器的值)去处理 requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum16(dataAnalyzeMode, dataPoints); break; case DataPointDataType.Bit: break; default: break; } return(requestCommandByteStreams); }
/// <summary> /// 生成modbus请求帧:用于写取寄存器值 /// </summary> /// <param name="dataPoints"> /// dataPointsataPints中的DataPoint必须同时满足如下条件(缺一不可); /// 1.设备地址相同; /// 2.写寄存器用的功能码相同; /// 3.写的值的数据类型相同(例如:数据类型都是int) /// 4.相邻DataPoint的寄存器地址是连续的。 /// </param> /// <returns>modbus请求帧</returns> public static List <List <byte> > CreateRequestCommandByteStreamForWriteRegisterBy(DataAnalyzeMode dataAnalyzeMode, List <DataPoint> dataPoints) { List <List <byte> > requestCommandByteStreams = new List <List <byte> >(); if (null == dataPoints || dataPoints.Count < 1) { return(requestCommandByteStreams); } DataPoint firstDataPoint = dataPoints.First(); /* * 根据DataPointDataType来判断使用功能码,有待商榷。 * 根据DataPointType来判断使用功能码是否才是正确的? */ if (DataPointDataType.Bit == firstDataPoint.DataPointDataType) { if (dataPoints.Count == 1) { requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum05(dataPoints); } else { requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum15(dataPoints); } } else { if (dataPoints.Count == 1) { requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum06(dataAnalyzeMode, dataPoints); } else { requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum16(dataAnalyzeMode, dataPoints); } } return(requestCommandByteStreams); }
/// <summary> /// 解析响应字节流 /// </summary> /// <param name="dataAnalyzeMode">数据解析方式</param> /// <param name="requestByteData">请求字节流</param> /// <param name="receviceByteData">响应字节流</param> /// <returns></returns> public AnalyzeRecivedDataReponse AnalyzeRecivedData(DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> receviceByteData) { return(AnalyzeRecivedDataStatic(dataAnalyzeMode, requestByteData, receviceByteData)); }
public void AddWriteRegisterCommands(List <DataPoint> dataPoints) { if (null == dataPoints || dataPoints.Count < 1) { return; } DataAnalyzeMode dataAnalyzeMode = ModbusConfigService.GetCurrentDataAnalyzeMode(); List <List <DataPoint> > dataPointsGroupedForWrite = DataPointGrouper.GroupingDataPointsForWriteRegister(dataPoints); foreach (var dataPointsGroup in dataPointsGroupedForWrite) { List <List <byte> > requestCommadBytes = RequestCommandByteStreamCreater.CreateRequestCommandByteStreamForWriteRegisterBy(dataAnalyzeMode, dataPointsGroup); foreach (var requestCommadByte in requestCommadBytes) { WriteRegisterCommand writeRegisterCommand = new WriteRegisterCommand(); //请求唯一性,用guid标示唯一性 List <byte> guidBytes = Guid.NewGuid().ToByteArray().ToList(); requestCommadByte.AddRange(guidBytes); writeRegisterCommand.WriteCommand = requestCommadByte; //TODO:删除,测试用的 //List<byte> textBytes = new List<byte>(); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x10); //textBytes.Add((byte)0x00); //textBytes.Add((byte)0x72); //textBytes.Add((byte)0x04); //textBytes.Add((byte)0x01); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x03); //textBytes.Add((byte)0x04); //textBytes.Add((byte)0x09); //textBytes.Add((byte)0x09); //GUID //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //textBytes.Add((byte)0x02); //writeRegisterCommand.WriteCommand = textBytes; this.allWriterRegisterCommands.Enqueue(writeRegisterCommand); } } }
/// <summary> /// 构造函数 /// </summary> /// <param name="dataAnalyzeMode">数据解析方式</param> public FunNum06CustomerRequestData(DataAnalyzeMode dataAnalyzeMode) { this.DataAnalyzeMode = dataAnalyzeMode; }
/// <summary> /// 生成modbus请求帧:用于写取寄存器值 /// </summary> /// <param name="dataPoints"> /// dataPointsataPints中的DataPoint必须同时满足如下条件(缺一不可); /// 1.设备地址相同; /// 2.写寄存器用的功能码相同; /// 3.写的值的数据类型相同(例如:数据类型都是int) /// 4.相邻DataPoint的寄存器地址是连续的。 /// </param> /// <returns>modbus请求帧</returns> public static List <List <byte> > CreateRequestCommandByteStreamForWriteRegisterBy(DataAnalyzeMode dataAnalyzeMode, List <DataPoint> dataPoints, FunctionNumType functionNumType) { List <List <byte> > requestCommandByteStreams = new List <List <byte> >(); if (null == dataPoints || dataPoints.Count < 1) { return(requestCommandByteStreams); } switch (functionNumType) { case FunctionNumType.FunctionNum05: requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum05(dataPoints); break; case FunctionNumType.FunctionNum06: requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum06(dataAnalyzeMode, dataPoints); break; case FunctionNumType.FunctionNum15: requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum15(dataPoints); break; case FunctionNumType.FunctionNum16: requestCommandByteStreams = CreateRequestCommandByteStreamForFunNum16(dataAnalyzeMode, dataPoints); break; default: break; } return(requestCommandByteStreams); }
/// <summary> /// 解析返回的数据 /// </summary> /// <param name="dataAnalyzeMode"> 解析数据方式 </param> /// <param name="requestByteData"> /// 请求数据字节流, /// 注意:要求第一个字节位是:单元标识符(从机地址位), /// 即:如果是TCP请求帧,要求去掉TCP报头所剩下的字节。 /// 例如03功能码,要求请求数据字节流第一个字节位<see cref="FunNum03RequestDataBase.DeviceAddress"/> /// </param> /// <param name="receviceByteData"> /// 响应数据字节流 /// 注意:要求第一个字节位是:单元标识符(从机地址位), /// 即:如果是TCP响应帧,要求去掉TCP报头所剩下的字节。 /// 例如03功能码,要求响应数据字节流第一个字节位<see cref="FunNum03RequestDataBase.DeviceAddress"/> /// </param> /// <returns></returns> public static AnalyzeRecivedDataReponse AnalyzeRecivedData(DataAnalyzeMode dataAnalyzeMode, List <byte> requestByteData, List <byte> receviceByteData) { AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse(); reponse = RecivedDataCorrespondToRequesData(requestByteData, receviceByteData); if (!(reponse.ModbusReponseSuccess && reponse.AnalyzeRecivedDataSuccess)) { reponse.ModbusReponseSuccess = false; return(reponse); } byte funNumHex = receviceByteData[1]; //功能码的16进制值 string funNmDecimal = Convert.ToString(funNumHex, 10); //功能码的10进制值字符串 FunctionNumType functionNumType = 0; Enum.TryParse(funNmDecimal, true, out functionNumType); switch (functionNumType) { case FunctionNumType.FunctionNum01: reponse = AnalyzeRecivedDataByFunNum01(dataAnalyzeMode, requestByteData, receviceByteData); break; case FunctionNumType.FunctionNum02: break; case FunctionNumType.FunctionNum03: reponse = AnalyzeRecivedDataByFunNum03(dataAnalyzeMode, requestByteData, receviceByteData); break; case FunctionNumType.FunctionNum04: break; case FunctionNumType.FunctionNum05: reponse = AnalyzeRecivedDataByFunNum05(dataAnalyzeMode, requestByteData, receviceByteData); break; case FunctionNumType.FunctionNum06: reponse = AnalyzeRecivedDataByFunNum06(dataAnalyzeMode, requestByteData, receviceByteData); break; case FunctionNumType.FunctionNum07: break; case FunctionNumType.FunctionNum08: break; case FunctionNumType.FunctionNum09: break; case FunctionNumType.FunctionNum10: break; case FunctionNumType.FunctionNum11: break; case FunctionNumType.FunctionNum12: break; case FunctionNumType.FunctionNum13: break; case FunctionNumType.FunctionNum14: break; case FunctionNumType.FunctionNum15: reponse = AnalyzeRecivedDataByFunNum015(dataAnalyzeMode, requestByteData, receviceByteData); break; case FunctionNumType.FunctionNum16: reponse = AnalyzeRecivedDataByFunNum16(dataAnalyzeMode, requestByteData, receviceByteData); break; case FunctionNumType.FunctionNum17: break; case FunctionNumType.FunctionNum18: break; case FunctionNumType.FunctionNum19: break; case FunctionNumType.FunctionNum20: break; default: throw new ArgumentOutOfRangeException(); } return(reponse); }