예제 #1
0
 /// <summary>
 /// Creates a new ModebusDevice with one initial interface.
 /// </summary>
 /// <param name="intf">Initial interface.</param>
 /// <param name="deviceAddress">Device address. Must be between 1 and 247 for RTU and should be 248 for TCP.</param>
 /// <param name="syncObject">Optional object for communication interface synchronization.</param>
 /// <remarks>
 /// More interfaces can be add or removed by AddInterface and RemoveInterface methods.
 /// </remarks>
 protected ModbusDevice(IModbusInterface intf, byte deviceAddress, object syncObject = null) :
     this(deviceAddress, syncObject)
 {
     intf.PrepareRead();
     _interfaces.Add(intf);
     _buffer = new byte[intf.MaxTelegramLength];
 }
예제 #2
0
 /// <summary>
 /// Creates a new ModebusDevice with one initial interface.
 /// </summary>
 /// <param name="intf">Initial interface.</param>
 /// <param name="deviceAddress">Device address. Must be between 1 and 247 for RTU and should be 248 for TCP.</param>
 /// <param name="syncObject">Optional object for communication interface synchronization.</param>
 /// <remarks>
 /// More interfaces can be add or removed by AddInterface and RemoveInterface methods.
 /// </remarks>
 protected ModbusDevice(IModbusInterface intf, byte deviceAddress, object syncObject = null) :
    this(deviceAddress, syncObject)
 {
    intf.PrepareRead();
    _interfaces.Add(intf);
    _buffer = new byte[intf.MaxTelegramLength];
 }
예제 #3
0
        /// <summary>
        /// Sends a modbus telegram over the interface and waits for a response
        /// </summary>
        /// <param name="deviceAddress">Modbus device address.</param>
        /// <param name="fc">Function code.</param>
        /// <param name="timeout">Timeout in Milli seconds.</param>
        /// <param name="telegramLength">Total length of the telegram in bytes</param>
        /// <param name="desiredDataLength">Length of the desired telegram data (without fc, cs, ...) of the response in bytes. -1 for unknown.</param>
        /// <param name="telegramContext">Interface specific context of the telegram</param>
        /// <param name="dataPos">Index of the response data in the buffer.</param>
        /// <returns></returns>
        protected virtual short SendReceive(byte deviceAddress, ModbusFunctionCode fc, int timeout, short telegramLength, short desiredDataLength,
                                            object telegramContext, ref short dataPos)
        {
            lock (_SyncObject)
            {
                try
                {
                    _Interface.SendTelegram(_Buffer, telegramLength);
                    _Interface.PrepareRead();

                    if (deviceAddress == ModbusConst.BroadcastAddress)
                    {
                        return(0);
                    }

                    byte  responseDeviceAddress;
                    byte  responseFc = 0;
                    short dataLength = 0;

                    while (timeout > 0)
                    {
                        var ts = DateTime.Now.Ticks;

                        if (!_Interface.ReceiveTelegram(_Buffer, desiredDataLength, timeout, out telegramLength))
                        {
                            throw new ModbusException(ModbusErrorCode.Timeout);
                        }

                        timeout -= (int)((DateTime.Now.Ticks - ts) / 10000);

                        // if this is not the response we are waiting for wait again until time runs out
                        if (_Interface.ParseTelegram(_Buffer, telegramLength, true, ref telegramContext,
                                                     out responseDeviceAddress,
                                                     out responseFc,
                                                     out dataPos, out dataLength) &&
                            responseDeviceAddress == deviceAddress &&
                            (responseFc & 0x7f) == (byte)fc)
                        {
                            break;
                        }
                        if (timeout <= 0)
                        {
                            throw new ModbusException(ModbusErrorCode.Timeout);
                        }
                    }

                    if ((responseFc & 0x80) != 0)
                    {
                        // error response
                        throw new ModbusException((ModbusErrorCode)_Buffer[dataPos]);
                    }
                    return(dataLength);
                }
                finally
                {
                    _Interface.PrepareWrite();
                }
            }
        }
예제 #4
0
 /// <summary>
 /// Adds an additional interface to be polled for incoming messages.
 /// </summary>
 /// <param name="intf">Interface to add.</param>
 public void AddInterface(IModbusInterface intf)
 {
     lock (this.syncObject) {
         if (this.Buffer1 == null || intf.MaxTelegramLength > this.Buffer1.Length)
         {
             this.Buffer1 = new byte[intf.MaxTelegramLength];
         }
         intf.PrepareRead();
         this.interfaces.Add(intf);
     }
 }
예제 #5
0
 /// <summary>
 /// Adds an additional interface to be polled for incoming messages.
 /// </summary>
 /// <param name="intf">Interface to add.</param>
 public void AddInterface(IModbusInterface intf)
 {
     lock (_syncObject)
     {
         if (_buffer == null || intf.MaxTelegramLength > _buffer.Length)
         {
             _buffer = new byte[intf.MaxTelegramLength];
         }
         intf.PrepareRead();
         _interfaces.Add(intf);
     }
 }
예제 #6
0
 /// <summary>
 /// Adds an additional interface to be polled for incoming messages.
 /// </summary>
 /// <param name="intf">Interface to add.</param>
 public void AddInterface(IModbusInterface intf)
 {
    lock (_syncObject)
    {
       if (_buffer == null || intf.MaxTelegramLength > _buffer.Length)
       {
          _buffer = new byte[intf.MaxTelegramLength];
       }
       intf.PrepareRead();
       _interfaces.Add(intf);
    }
 }
예제 #7
0
      private short SendReceive(IModbusInterface masterInterface, byte[] buffer, byte deviceAddress, ModbusFunctionCode fc, int timeout, short telegramLength, short desiredDataLength,
                                          object telegramContext, ref short dataPos)
      {
         lock (masterInterface)
         {
            masterInterface.SendTelegram(buffer, telegramLength);

            if (deviceAddress == ModbusConst.BroadcastAddress)
            {
               return 0;
            }

            try
            {
               masterInterface.PrepareRead();

               byte responseDeviceAddress;
               byte responseFc = 0;
               short dataLength = 0;

               while (timeout > 0)
               {
                  var ts = DateTime.Now.Ticks;
                  if (!masterInterface.ReceiveTelegram(buffer, desiredDataLength, timeout, out telegramLength))
                  {
                     throw new ModbusException(ModbusErrorCode.Timeout);
                  }
                  timeout -= (int) ((DateTime.Now.Ticks - ts)/10000);

                  // if this is not the response we are waiting for wait again until time runs out
                  if (masterInterface.ParseTelegram(buffer, telegramLength, true, ref telegramContext,
                     out responseDeviceAddress,
                     out responseFc,
                     out dataPos, out dataLength)
                      && responseDeviceAddress == deviceAddress
                      && (responseFc & 0x7f) == (byte) fc)
                  {
                     break;
                  }
                  if (timeout <= 0)
                  {
                     throw new ModbusException(ModbusErrorCode.Timeout);
                  }
               }
               if ((responseFc & 0x80) != 0)
               {
                  // error response
                  throw new ModbusException((ModbusErrorCode) buffer[dataPos]);
               }
               return dataLength;
            }
            finally
            {
               masterInterface.PrepareWrite();
            }
         }
      }