/// <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); }
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); }