Пример #1
0
        /// <summary>
        /// 请求获取数据的命令,并且返回请求结果数据的字节数组
        /// </summary>
        /// <param name="device"></param>
        /// <param name="realData"></param>
        /// <param name="error"></param>
        /// <param name="fragment">当前请求的modbus地址分段</param>
        /// <returns></returns>
        public Task <List <byte> > RequestData(RealData read)
        {
            List <byte> allbytes = new List <byte>();

            var task = Task.Run <List <byte> >(() =>
            {
                try
                {
                    if (serialPort != null && serialPort.IsOpen)
                    {
                        //分段读取数据,如果是读取整个寄存器的话,一次只能最多读取123个,
                        //如果是读取线圈的话最大只能读取1999个,因此要分段进行数据的读取
                        //增加了一个写入后返回消息
                        master.Transport.WriteMessage = new Action <byte[]>((s) =>
                        {
                            if (LogOutput != null)
                            {
                                LogOutput(ModbusConvert.ByteToHexStr(s));
                            }
                        });
                        master.Transport.CheckFrame = true;
                        ModbusFragment fragment     = read.Fragment;
                        switch (fragment.Code)
                        {
                        case "01":        // 01和05是一个码 可写可读
                            {
                                //返回的线圈状态,由于线圈是按位操作,转换也是按位转换
                                Task <bool[]> result = master.ReadCoilsAsync(byte.Parse(read.Address), fragment.StartRegister, fragment.RegisterNum);

                                byte[] bytes = ModbusConvert.BoolToByte(result.Result);

                                allbytes.AddRange(bytes);
                            }
                            break;

                        case "02":        //只读属性
                            {
                                //返回的线圈状态
                                Task <bool[]> result = master.ReadInputsAsync(byte.Parse(read.Address), fragment.StartRegister, fragment.RegisterNum);
                                byte[] bytes         = ModbusConvert.BoolToByte(result.Result);

                                allbytes.AddRange(bytes);
                            }
                            break;

                        case "03":        //HR保持寄存器,可写可读
                            {
                                //返回的数据全部是ushort 需要将ushort 转换为byte在进行传递
                                Task <ushort[]> result = master.ReadHoldingRegistersAsync(byte.Parse(read.Address), fragment.StartRegister, fragment.RegisterNum);
                                byte[] bytes           = ModbusConvert.Ushorts2Bytes(result.Result);
                                allbytes.AddRange(bytes);
                            }
                            break;

                        case "04":        //只读属性
                            {
                                //返回的数据全部是ushort 需要将ushort 转换为byte在进行传递
                                Task <ushort[]> result = master.ReadInputRegistersAsync(byte.Parse(read.Address), fragment.StartRegister, fragment.RegisterNum);
                                byte[] bytes           = ModbusConvert.Ushorts2Bytes(result.Result);

                                allbytes.AddRange(bytes);
                            }
                            break;
                        }
                    }
                    return(allbytes);
                }
                catch
                {
                    return(allbytes);
                }
            });

            return(task);
        }
Пример #2
0
        public Task Start()
        {
            LogOutput("服务已经启动");
            InitSerialPort();

            LogOutput("串口初始化完成");
            if (Serial_PARA.ModbusType == "ASCII")
            {
                master = ModbusSerialMaster.CreateAscii(serialPort);
            }
            else
            {
                master = ModbusSerialMaster.CreateRtu(serialPort);
            }
            LogOutput("Modbus创建成功");
            //通用部分设置

            master.Transport.ReadTimeout  = Serial_PARA.ReadTimeout;         //读取数据超时1000ms
            master.Transport.WriteTimeout = Serial_PARA.WriteTimeout;        //写入数据超时1000ms
            master.Transport.Retries      = Serial_PARA.CollectFaultsNumber; //重试次数
            if (master.Transport.Retries < 0)
            {
                master.Transport.Retries = 0;
            }
            master.Transport.WaitToRetryMilliseconds     = Serial_PARA.CollectFaultsInternal;//重试间隔
            master.Transport.RetryOnOldResponseThreshold = Convert.ToUInt32(Serial_PARA.CollectFaultsNumber);
            master.Transport.SlaveBusyUsesRetryCount     = Serial_PARA.ContinueCollect;
            master.Transport.WaitToRetryMilliseconds     = Serial_PARA.CollectFaultsInternal;
            LogOutput("Modbus从机属性配置");
            Thread.Sleep(100);
            var task = Task.Run(() =>
            {
                try
                {
                    #region
                    {
                        //此处采用多线程技术创建一个实时读取数据的任务
                        while (true)
                        {
                            try
                            {
                                if (!serialPort.IsOpen)
                                {
                                    serialPort.Open();
                                }
                                for (int i = 0; i < Serial_PARA.Chanels.Count; i++)
                                {
                                    if (Serial_PARA.Chanels[i].BindingArress.Trim() == "")
                                    {
                                        continue;
                                    }
                                    //以下开始读取4气体检测的值
                                    List <RealData> receivedatas = new List <RealData>();
                                    foreach (ModbusPara para in Serial_PARA.ModbusParas)
                                    {
                                        RealData realData = new RealData();
                                        try
                                        {
                                            if (para.Enable == 0)
                                            {
                                                continue;
                                            }

                                            realData.Address  = Serial_PARA.Chanels[i].BindingArress;
                                            realData.Fragment = new ModbusFragment()
                                            {
                                                Code          = para.ModbusCode,
                                                DataType      = "uint",
                                                RegisterNum   = Convert.ToByte(para.RegisterNum),
                                                StartRegister = Convert.ToByte(para.StartRegister)
                                            };

                                            realData.ParaName = para.Name;
                                            realData.SlaveId  = Serial_PARA.Chanels[i].Id;

                                            var datas = RequestData(realData).Result;

                                            if (datas.Count > 0)
                                            {
                                                realData.ReadSendByte = datas.ToArray();
                                                receivedatas.Add(realData);
                                            }
                                        }
                                        catch
                                        {
                                            if (LogOutput != null)
                                            {
                                                LogOutput(realData.ParaName + " 没有获取到数据");
                                            }
                                        }
                                    }

                                    if (ReadDataSuccessed != null)
                                    {
                                        ReadDataSuccessed(receivedatas);
                                    }
                                }
                                Thread.Sleep(Serial_PARA.UpdateCycle * 1000);
                            }
                            catch (Exception emx)
                            {
                                if (LogOutput != null)
                                {
                                    LogOutput(emx.Message + " ERROR=02");
                                }
                                ///出现异常则5秒后再进行读取
                                Thread.Sleep(5000);
                            }
                        }
                    }
                    #endregion
                }
                catch (Exception emx)
                {
                    if (LogOutput != null)
                    {
                        LogOutput(emx.Message + " ERROR=03");
                    }
                }
            });

            return(task);
        }