/// <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); }
/// <summary> /// 写入操作,针对的数据类型只有 字符串量 计算值 关系数据库值 /// </summary> /// <param name="server"></param> /// <param name="comm"></param> /// <param name="device"></param> /// <param name="para">要写入参数</param> /// <param name="value">要写入的值</param> /// <returns></returns> public Task <bool> ResponseData(string SlaveId, string Address, ModbusFragment para, string value) { var task = Task.Run <bool>(() => { if (para == null) { return(false); } //设备地址不能为空 if (Address == "") { return(false); } try { //获取参数中的 if (serialPort != null && serialPort.IsOpen && master != null) { ushort offset = para.StartRegister; switch (para.Code) { case "01": { ///写入单个线圈 if (ushort.Parse(value) > 0) { master.WriteSingleCoil(byte.Parse(Address), offset, true); } else { master.WriteSingleCoil(byte.Parse(Address), offset, false); } } break; case "02": //此类型只能查询,不能写入 { } break; case "03": { switch (para.DataType) { case "float": //单精度浮点型 { ushort[] buff = new ushort[2]; float WriteValue = float.Parse(value); ModbusConvert.SetReal(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(Address), offset, buff); } break; case "double": //双精度浮点数64位 { ushort[] buff = new ushort[4]; double WriteValue = double.Parse(value); ModbusConvert.SetDouble(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(Address), offset, buff); } break; case "string": //字符型 { ushort[] buff = new ushort[para.charsize]; string WriteValue = value; if (value.Length > para.charsize) { WriteValue = value.Substring(0, para.charsize); } if (value.Length < para.charsize) { WriteValue = value.PadRight(para.charsize, ' '); } ModbusConvert.SetString(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(Address), offset, buff); } break; case "byte": //无符号整数8位: { ushort[] buff = new ushort[1]; byte WriteValue = byte.Parse(value); ModbusConvert.SetByte(buff, 0, WriteValue, true); master.WriteSingleRegister(byte.Parse(Address), offset, buff[0]); } break; case "sbyte": //有符号整数8位: { ushort[] buff = new ushort[1]; sbyte WriteValue = sbyte.Parse(value); ModbusConvert.SetSByte(buff, 0, WriteValue, true); master.WriteSingleRegister(byte.Parse(Address), offset, buff[0]); } break; case "uint16": //无符号整数16位: { ushort WriteValue = ushort.Parse(value); ushort[] buff = new ushort[1]; ModbusConvert.SetUShort(buff, 0, WriteValue); master.WriteSingleRegister(byte.Parse(Address), offset, buff[0]); } break; case "int16": //有符号整数16位: { Int16 WriteValue = Int16.Parse(value); ushort[] buff = new ushort[1]; ModbusConvert.SetShort(buff, 0, WriteValue); master.WriteSingleRegister(byte.Parse(Address), offset, buff[0]); } break; case "uint32": //无符号整数32位: { uint WriteValue = uint.Parse(value); ushort[] buff = new ushort[2]; ModbusConvert.SetUInt(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(Address), offset, buff); } break; case "int32": //有符号整数32位: { int WriteValue = int.Parse(value); ushort[] buff = new ushort[2]; ModbusConvert.SetInt(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(Address), offset, buff); } break; } } break; } } } catch { return(false); } return(true); }); return(task); }
public void MakeFragment() { //先进行排序 for (int i = 0; i < Units.Count; i++) { ushort temp = Units[i]; int j = i; while ((j > 0) && (Units[j - 1] > temp)) { Units[j] = Units[j - 1]; --j; } Units[j] = temp; } int maxnum = 123; if (StoredCode == "03" || StoredCode == "04") { maxnum = 123; } else { maxnum = 1999; } Fragments = new List <ModbusFragment>(); ModbusFragment fragment = null; bool iscreate = true; for (int i = 0; i < Units.Count; i++) { if (iscreate) { fragment = new ModbusFragment(); fragment.Code = this.StoredCode; fragment.StartRegister = Units[i]; Fragments.Add(fragment); iscreate = false; } else { ushort num = Convert.ToUInt16(Units[i] - fragment.StartRegister + 9); ushort num2 = Convert.ToUInt16(Units[i - 1] - fragment.StartRegister + 9); if (num >= maxnum) { if (num == maxnum) { fragment.RegisterNum = num; } else if (num2 <= maxnum) { fragment.RegisterNum = num2; i--; } iscreate = true; } else { fragment.RegisterNum = num; iscreate = false; } } } }