Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 写单个寄存器
        /// </summary>
        /// <param name="requestByteData"></param>
        /// <param name="receviceByteData"></param>
        /// <returns></returns>
        private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum06(
            DataAnalyzeMode dataAnalyzeMode,
            List <byte> requestByteData,
            List <byte> receviceByteData)
        {
            AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse();

            try
            {
                int deviceAddress = receviceByteData[0];

                //byte[] startRegisterByte = new byte[] { receviceByteData[2], receviceByteData[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);

                //接受侦receviceByteData中寄存器值的数据之前的字节数:
                //deviceAddress、funNum、ecevideByteData[2]个占1个字节
                int byteCountBeforeDataRegion = 4;
                int countOfRegisterToRead     = 1;

                //避免数据返回不完整引发下标溢出
                if (receviceByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2) &&
                    requestByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2))
                {
                    if (requestByteData[byteCountBeforeDataRegion] == receviceByteData[byteCountBeforeDataRegion] &&
                        requestByteData[byteCountBeforeDataRegion + 1] == receviceByteData[byteCountBeforeDataRegion + 1])
                    {
                        reponse.ModbusReponseSuccess = true;
                    }
                    else
                    {
                        reponse.ModbusReponseSuccess = false;
                    }

                    Register register = new Register();
                    register.DeviceAddress   = deviceAddress;
                    register.RegisterAddress = startRegisterAddress;

                    //byte[] bytevalues = new byte[]
                    //    {
                    //         receviceByteData[byteCountBeforeDataRegion],
                    //         receviceByteData[byteCountBeforeDataRegion + 1],
                    //    };

                    //register.RegisterValue = BitConverter.ToUInt16(bytevalues, 0);
                    if (dataAnalyzeMode == DataAnalyzeMode.DataHighToLow)
                    {
                        //HL HL
                        register.RegisterValue = (ushort)(receviceByteData[byteCountBeforeDataRegion] * 256 +
                                                          receviceByteData[byteCountBeforeDataRegion + 1]);


                        register.LowToHighDataBytes.Add(receviceByteData[byteCountBeforeDataRegion + 1]); //低位
                        register.LowToHighDataBytes.Add(receviceByteData[byteCountBeforeDataRegion]);     //高位
                    }
                    else
                    {
                        //LH LH
                        register.RegisterValue = (ushort)(receviceByteData[byteCountBeforeDataRegion] +
                                                          receviceByteData[byteCountBeforeDataRegion + 1] * 256);

                        register.LowToHighDataBytes.Add(receviceByteData[byteCountBeforeDataRegion]);     //低位
                        register.LowToHighDataBytes.Add(receviceByteData[byteCountBeforeDataRegion + 1]); //高位
                    }


                    reponse.Registers.Add(register);
                }
            }
            catch (Exception ex)
            {
                reponse.AnalyzeRecivedDataSuccess = false;
                //LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!");
                reponse.ErrorMsg = "AnalyzeRecivedDataByFunNum06->解析Modbus接收帧时发生异常!" + ex.Message;

                return(reponse);
            }

            return(reponse);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 写单个线圈
        /// </summary>
        /// <param name="requestByteData"></param>
        /// <param name="receviceByteData"></param>
        /// <returns></returns>
        private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum05(
            DataAnalyzeMode dataAnalyzeMode,
            List <byte> requestByteData,
            List <byte> receviceByteData)
        {
            AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse();

            try
            {
                int deviceAddress        = receviceByteData[0];
                int startRegisterAddress = requestByteData[2] * 256 + requestByteData[3];

                //接受侦receviceByteData中寄存器值的数据之前的字节数:
                //deviceAddress、funNum、ecevideByteData[2]个占1个字节
                int byteCountBeforeDataRegion = 4;
                int countOfRegisterToRead     = 1;

                //避免数据返回不完整引发下标溢出
                if (receviceByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2) &&
                    requestByteData.Count > (byteCountBeforeDataRegion + countOfRegisterToRead * 2))
                {
                    if (requestByteData[byteCountBeforeDataRegion] == receviceByteData[byteCountBeforeDataRegion] &&
                        requestByteData[byteCountBeforeDataRegion + 1] == receviceByteData[byteCountBeforeDataRegion + 1])
                    {
                        reponse.ModbusReponseSuccess = true;
                    }
                    else
                    {
                        reponse.ModbusReponseSuccess = false;
                    }

                    Register register = new Register();
                    register.DeviceAddress   = deviceAddress;
                    register.RegisterAddress = startRegisterAddress;

                    byte fistByteInRecevide   = receviceByteData[byteCountBeforeDataRegion];
                    byte secondByteInRecevide = receviceByteData[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 ex)
            {
                reponse.AnalyzeRecivedDataSuccess = false;
                //LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!");
                reponse.ErrorMsg = "AnalyzeRecivedDataByFunNum05->解析Modbus接收帧时发生异常!" + ex.Message;

                return(reponse);
            }

            return(reponse);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum03(
            DataAnalyzeMode dataAnalyzeMode,
            List <byte> requestByteData,
            List <byte> receviceByteData)
        {
            AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse();

            try
            {
                //接受帧receviceByteData中寄存器值的数据之前的字节数:
                //deviceAddress、funNum、receviceByteData[2]各占1个字节
                int byteCountBeforeDataRegion = 3;

                //避免数据返回不完整引发下标溢出
                if (receviceByteData.Count > (byteCountBeforeDataRegion + receviceByteData[2]))
                {
                    int deviceAddress        = requestByteData[0];
                    int startRegisterAddress = requestByteData[2] * 256 + requestByteData[3];

                    //寄存器的个数
                    int countOfRegisterHadRead = receviceByteData[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)(receviceByteData[2 * i + byteCountBeforeDataRegion] * 256 +
                                         receviceByteData[2 * i + byteCountBeforeDataRegion + 1]);

                            //先加入低位
                            register.LowToHighDataBytes.Add(receviceByteData[2 * i + byteCountBeforeDataRegion + 1]);
                            //后加入高位
                            register.LowToHighDataBytes.Add(receviceByteData[2 * i + byteCountBeforeDataRegion]);
                        }
                        else
                        {
                            //LH LH
                            register.RegisterValue =
                                (ushort)(receviceByteData[2 * i + byteCountBeforeDataRegion] +
                                         receviceByteData[2 * i + byteCountBeforeDataRegion + 1] * 256);

                            //先加入低位
                            register.LowToHighDataBytes.Add(receviceByteData[2 * i + byteCountBeforeDataRegion]);
                            //后加入高位
                            register.LowToHighDataBytes.Add(receviceByteData[2 * i + byteCountBeforeDataRegion + 1]);
                        }

                        reponse.Registers.Add(register);
                        ++startRegisterAddress;
                    }
                }
            }
            catch (Exception ex)
            {
                reponse.AnalyzeRecivedDataSuccess = false;
                //LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!");
                reponse.ErrorMsg = "AnalyzeRecivedDataByFunNum03->解析Modbus接收帧时发生异常!" + ex.Message;
                return(reponse);
            }

            return(reponse);
        }
Ejemplo n.º 6
0
        private static AnalyzeRecivedDataReponse AnalyzeRecivedDataByFunNum01(
            DataAnalyzeMode dataAnalyzeMode,
            List <byte> requestByteData,
            List <byte> receviceByteData)
        {
            AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse();

            try
            {
                int deviceAddress = requestByteData[0];

                int startRegisterAddress  = requestByteData[2] * 256 + requestByteData[3];
                int countOfRegisterToRead = requestByteData[4] * 256 + requestByteData[5];


                //接受侦receviceByteData中寄存器值的数据之前的字节数:
                //deviceAddress、funNum、receviceByteData[2]个占1个字节
                int byteCountBeforeDataRegion = 3;
                //数据区表示寄存器值的字节数
                int registerValueByteCount = receviceByteData[2];

                //避免数据返回不完整引发下标溢出
                if (receviceByteData.Count > (byteCountBeforeDataRegion + receviceByteData[2]))
                {
                    byte          byteData     = 0;
                    List <UInt16> totalRecvVal = new List <ushort>();
                    for (int k = 0; k < registerValueByteCount; k++)
                    {
                        byteData = receviceByteData[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 ex)
            {
                reponse.AnalyzeRecivedDataSuccess = false;
                //LoggingFactory.GetLogger().WriteDebugLogger("解析Modbus接收帧时发生异常!");
                reponse.ErrorMsg = "AnalyzeRecivedDataByFunNum01->解析Modbus接收帧时发生异常!" + ex.Message;
                return(reponse);
            }

            return(reponse);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 判读接受的数据是否对应请求
        /// </summary>
        /// <returns></returns>
        private static AnalyzeRecivedDataReponse RecivedDataCorrespondToRequesData(List <byte> requestByteData, List <byte> receviceByteData)
        {
            AnalyzeRecivedDataReponse reponse = new AnalyzeRecivedDataReponse();

            #region 基本的规则校验

            if (receviceByteData.Count < 2 || requestByteData.Count < 2)
            {
                //无法获取设备地址、功能码
                string message = "请求帧或接受帧中不存在设备地址或功能码。";
                //LoggingFactory.GetLogger().WriteDebugLogger(message);
                reponse.ErrorMsg             = message;
                reponse.ModbusReponseSuccess = false;
                return(reponse);
            }

            if (requestByteData[0] != receviceByteData[0])
            {
                string message = "请求帧与接受帧的设备地址不对应,响应数据有误。";
                //LoggingFactory.GetLogger().WriteDebugLogger(message);
                reponse.ErrorMsg = message;
                reponse.AnalyzeRecivedDataSuccess = false;
                return(reponse);
            }


            if (requestByteData[1] != receviceByteData[1])
            {
                string message = "请求帧与接受帧的功能码不对应,响应数据有误。";
                //LoggingFactory.GetLogger().WriteDebugLogger(message);
                reponse.ErrorMsg = message;
                reponse.AnalyzeRecivedDataSuccess = false;
                return(reponse);
            }

            #endregion


            #region TODO:数据校验

            #endregion

            #region  返回的数据根据是否带GUID判断是否是对应的数据
            //try
            //{
            //    //请求或返回起码长度为4:1个字节设备地址、1个字节功能码、2个字节CRC校验位
            //    //16是16个字节的GUID。
            //    int byteDataMinLenth = 4 + 16;
            //    if (requestByteData.Count < byteDataMinLenth)
            //    {
            //        correspond = false;
            //    }

            //    //数据溢出也表明响应的数据不对。
            //    List<byte> requestGuid = GetGuidBytesForm(requestByteData);
            //    List<byte> recieveGuid = GetGuidBytesForm(receviceByteData);

            //    for (int i = 0; i < 16; i++)
            //    {
            //        if (requestGuid[i] != recieveGuid[i])
            //        {
            //            correspond = false;
            //            break;
            //        }
            //    }

            //}
            //catch (Exception)
            //{
            //    correspond = false;
            //}
            #endregion

            reponse.ModbusReponseSuccess = true;
            return(reponse);
        }