예제 #1
0
        /// <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);
        }
예제 #2
0
파일: Modbus.cs 프로젝트: nxzzkj/lazyiot
        /// <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);
        }