// ------------------------------------------------------------------------ // Write asynchronous data acknowledge private void OnSend(System.IAsyncResult result) { if (result.IsCompleted == false) { throw ModbusException.GetModbusException(0xFD); } }
/// <summary> /// Read Discrete Inputs from Server device (FC2). /// </summary> /// <param name="startingAddress">First discrete input to read</param> /// <param name="quantity">Number of discrete Inputs to read</param> /// <returns>Boolean Array which contains the discrete Inputs</returns> public Modbus.DiscreteInputs ReadDiscreteInputs(int startingAddress, int quantity) { Logger.Info($"FC2 (Read Discrete Inputs from StartingAddress: { startingAddress }, Quantity: { quantity }"); if (this.modbusChannel == null) { Logger.Error("ConnectionException Throwed"); throw new InvalidOperationException("No ModbusChannel initialized."); } if (startingAddress > 65535 || quantity > 2000) { Logger.Error("ArgumentException Throwed"); throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); } var request = ModbusRequest.DiscriteInputRequest(startingAddress, quantity); var error = modbusChannel.SendReadCommand <DiscreteInputs>(request, out DiscreteInputs inputs); if (error != null) { throw ModbusException.FromProtocolException(error.ProtocolException); } return(inputs); }
protected override byte[] CheckResponse(byte[] respRaw, int respRawLength) { if (respRawLength < 13) { throw new InvalidResponseTelegramException("Error: Invalid response telegram, did not receive minimal length of 13 bytes"); } if ((respRaw[0] != StartOfFrame) | (respRaw[respRawLength - 2] != EndOfFrame1) | (respRaw[respRawLength - 1] != EndOfFrame2)) { throw new InvalidResponseTelegramException("Error: Invalid response telegram. No Start of Frame or End of Frame."); } // Convert ASCII telegram to binary byte[] buffer = new byte[(respRawLength - 3) / 2]; byte high, low, val; for (int i = 0; i < buffer.Length; i++) { //Example : Char1 = 0x35 ('5') and Char2 = 0x42 ('B') compressed to Byte = 0x5B val = respRaw[(2 * i) + 1]; high = (val <= 0x39) ? (byte)(val - 0x30) : (byte)(val - 0x37); val = respRaw[(2 * i) + 2]; low = (val <= 0x39) ? (byte)(val - 0x30) : (byte)(val - 0x37); buffer[i] = (byte)((byte)(high << 4) | low); } // Calculate LRC byte lrc = 0; for (int i = 0; i < buffer.Length - 1; i++) { lrc += buffer[i]; } lrc = (byte)(lrc * (-1)); // Check LRC if (buffer[buffer.Length - 1] != lrc) { throw new InvalidResponseTelegramException("Error: Invalid response telegram, LRC check failed"); } if (IsModbusException(buffer[1])) { throw ModbusException.GetModbusException(buffer[2]); } // Strip LRC and copy response PDU into output buffer byte[] responsePdu = new byte[buffer.Length - 1]; for (int i = 0; i < responsePdu.Length; i++) { responsePdu[i] = buffer[i]; } return(responsePdu); }
// ------------------------------------------------------------------------ // Write data and and wait for response private byte[] WriteSyncData(byte[] write_data, ushort id) { if (tcpSynCl.Connected) { try { tcpSynCl.Send(write_data, 0, write_data.Length, SocketFlags.None); int result = tcpSynCl.Receive(tcpSynClBuffer, 0, tcpSynClBuffer.Length, SocketFlags.None); byte unit = tcpSynClBuffer[6]; byte function = tcpSynClBuffer[7]; byte[] data; if (result == 0) { throw ModbusException.GetModbusException(0xFD); } // ------------------------------------------------------------ // Response data is slave exception if (function > 128) { throw ModbusException.GetModbusException(0xA1); } // ------------------------------------------------------------ // Write response data else if ((function >= (byte)EnumModbusFunctionCode.WriteSingleCoil) && (function != (byte)EnumModbusFunctionCode.ReadWriteMultipleRegisters)) { data = new byte[2]; Array.Copy(tcpSynClBuffer, 10, data, 0, 2); } // ------------------------------------------------------------ // Read response data else { data = new byte[tcpSynClBuffer[8]]; Array.Copy(tcpSynClBuffer, 9, data, 0, tcpSynClBuffer[8]); } return(data); } catch (SystemException) { throw ModbusException.GetModbusException(0xFD); } } else { throw ModbusException.GetModbusException(0xFD); } }
internal void CallException(ushort id, byte unit, byte function, ModbusException exception) { if ((tcpAsyCl == null) || (tcpSynCl == null)) { return; } if (exception.Code == 0xFD) { tcpSynCl = null; tcpAsyCl = null; } if (OnException != null) { throw exception; } }
// ------------------------------------------------------------------------ // Write asynchronous data private void WriteAsyncData(byte[] write_data, ushort id) { if ((tcpAsyCl != null) && (tcpAsyCl.Connected)) { try { tcpAsyCl.BeginSend(write_data, 0, write_data.Length, SocketFlags.None, new AsyncCallback(OnSend), null); tcpAsyCl.BeginReceive(tcpAsyClBuffer, 0, tcpAsyClBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), tcpAsyCl); } catch (SystemException) { throw ModbusException.GetModbusException(0xFD); } } else { throw ModbusException.GetModbusException(0xFD); } }
// ------------------------------------------------------------------------ // Write asynchronous data response private void OnReceive(System.IAsyncResult result) { if (result.IsCompleted == false) { throw ModbusException.GetModbusException(0xFD); } ushort id = SwapUInt16(BitConverter.ToUInt16(tcpAsyClBuffer, 0)); byte unit = tcpAsyClBuffer[6]; byte function = tcpAsyClBuffer[7]; byte[] data; // ------------------------------------------------------------ // Write response data if ((function >= (byte)EnumModbusFunctionCode.WriteSingleCoil) && (function != (byte)EnumModbusFunctionCode.ReadWriteMultipleRegisters)) { data = new byte[2]; Array.Copy(tcpAsyClBuffer, 10, data, 0, 2); } // ------------------------------------------------------------ // Read response data else { data = new byte[tcpAsyClBuffer[8]]; Array.Copy(tcpAsyClBuffer, 9, data, 0, tcpAsyClBuffer[8]); } // ------------------------------------------------------------ // Response data is slave exception if (function > 128) { throw ModbusException.GetModbusException(0xA1); } // ------------------------------------------------------------ // Response data is regular data else if (OnResponseData != null) { OnResponseData(id, unit, function, data); } }
/// <summary> /// Read Coils from Server device (FC1). /// </summary> /// <param name="startingAddress">First coil to read</param> /// <param name="quantity">Numer of coils to read</param> /// <returns>Boolean Array which contains the coils</returns> public Coils ReadCoils(int startingAddress, int quantity) { Logger.Info("FC1 (Read Coils from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity); if (modbusChannel == null) { throw new InvalidOperationException("No ModbusChannel initialized."); } if (startingAddress > 65535 || quantity > 2000) { throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 2000"); } var request = new ModbusRequest(ModbusFunctions.ReadCoils, startingAddress, quantity); var error = modbusChannel.SendReadCommand(request, out Coils coils); if (error != null) { throw ModbusException.FromProtocolException(error.ProtocolException); } return(coils); }
/// <summary> /// Read Holding Registers from Master device (FC3). /// </summary> /// <param name="startingAddress">First holding register to be read. Integer between 0 and 65535</param> /// <param name="quantity">Number of holding registers to be read. Integer between 0 and 125.</param> /// <returns>Int Array which contains the holding registers</returns> public HoldingRegisters ReadHoldingRegisters(int startingAddress, int quantity) { Logger.Info("FC3 Read Holding Registers from Master device), StartingAddress: " + startingAddress + ", Quantity: " + quantity); if (modbusChannel == null) { Logger.Error("ConnectionException Throwed"); throw new InvalidOperationException("No ModbusChannel initialized."); } if (startingAddress > 65535 || quantity > 125) { Logger.Error("ArgumentException Throwed"); throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125"); } var request = new ModbusRequest(ModbusFunctions.ReadHoldingRegisters, startingAddress, quantity); var error = modbusChannel.SendReadCommand(request, out HoldingRegisters holdingReg); if (error != null) { throw ModbusException.FromProtocolException(error.ProtocolException); } return(holdingReg); }