// ------------------------------------------------------------------------
 // Write asynchronous data acknowledge
 private void OnSend(System.IAsyncResult result)
 {
     if (result.IsCompleted == false)
     {
         throw ModbusException.GetModbusException(0xFD);
     }
 }
Beispiel #2
0
        /// <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);
            }
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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);
        }