/// <summary> /// Gets the element value according to its type, converted to double. /// </summary> public double GetElemVal(int elemIdx) { Elem elem = Elems[elemIdx]; byte[] elemData = ElemData[elemIdx]; byte[] buf; // order bytes if needed if (elem.ByteOrder == null) { buf = elemData; } else { buf = new byte[elemData.Length]; ModbusUtils.ApplyByteOrder(elemData, buf, elem.ByteOrder); } // calculate value switch (elem.ElemType) { case ElemType.UShort: return(BitConverter.ToUInt16(buf, 0)); case ElemType.Short: return(BitConverter.ToInt16(buf, 0)); case ElemType.UInt: return(BitConverter.ToUInt32(buf, 0)); case ElemType.Int: return(BitConverter.ToInt32(buf, 0)); case ElemType.ULong: // possible data loss return(BitConverter.ToUInt64(buf, 0)); case ElemType.Long: // possible data loss return(BitConverter.ToInt64(buf, 0)); case ElemType.Float: return(BitConverter.ToSingle(buf, 0)); case ElemType.Double: return(BitConverter.ToDouble(buf, 0)); case ElemType.Bool: return(buf[0] > 0 ? 1.0 : 0.0); default: return(0.0); } }
/// <summary> /// Initializes the request PDU and calculates the response length. /// </summary> public override void InitReqPDU() { if (DataBlock == DataBlock.Custom) { // build PDU for custom command int dataLength = Data == null ? 0 : Data.Length; ReqPDU = new byte[1 + dataLength]; ReqPDU[0] = FuncCode; if (dataLength > 0) { Buffer.BlockCopy(Data, 0, ReqPDU, 1, dataLength); } RespPduLen = ReqPDU.Length; // assuming echo } else if (Multiple) { // build PDU for WriteMultipleCoils and WriteMultipleRegisters commands int quantity; // quantity of registers int dataLength; // data length in bytes if (DataBlock == DataBlock.Coils) { quantity = ElemCnt; dataLength = (ElemCnt % 8 == 0) ? ElemCnt / 8 : ElemCnt / 8 + 1; } else { quantity = ElemCnt * ModbusUtils.GetQuantity(ElemType); dataLength = quantity * 2; } ReqPDU = new byte[6 + dataLength]; ReqPDU[0] = FuncCode; ReqPDU[1] = (byte)(Address / 256); ReqPDU[2] = (byte)(Address % 256); ReqPDU[3] = (byte)(quantity / 256); ReqPDU[4] = (byte)(quantity % 256); ReqPDU[5] = (byte)dataLength; ModbusUtils.ApplyByteOrder(Data, 0, ReqPDU, 6, dataLength, ByteOrder, false); // set response length RespPduLen = 5; } else { // build PDU for WriteSingleCoil and WriteSingleRegister commands int dataLength = DataBlock == DataBlock.Coils ? 2 : ModbusUtils.GetDataLength(ElemType); ReqPDU = new byte[3 + dataLength]; ReqPDU[0] = FuncCode; ReqPDU[1] = (byte)(Address / 256); ReqPDU[2] = (byte)(Address % 256); if (DataBlock == DataBlock.Coils) { ReqPDU[3] = Value > 0 ? (byte)0xFF : (byte)0x00; ReqPDU[4] = 0x00; } else { byte[] data = dataLength == 2 ? new byte[] // standard Modbus { (byte)(Value / 256), (byte)(Value % 256) } : Data; ModbusUtils.ApplyByteOrder(data, 0, ReqPDU, 3, dataLength, ByteOrder, false); } // set response length RespPduLen = ReqPDU.Length; // echo } }