2016-06-28 6 views
1

私は今、このModbus TCPライブラリ(https://github.com/stephanstricker/modbusTCP/tree/master/ModbusTCP/ModbusTCP)を使用しているプロジェクトと、Function 20(http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf)を参照するためのこのドキュメントで作業しています。問題は、機能コード20(一般的な参照/ファイルを読む)をサポートしていないことです。C#でModbus Function 20をどのように実装しますか?

private byte[] CreateReadFileHeader(ushort id, byte unit, byte count, ushort fileNumber, ushort recordNumber, ushort recordLength) 
{ 
    byte[] data = new byte[13]; 

    byte[] _id = BitConverter.GetBytes((short)id); 
    data[0] = _id[1];    // Transaction ID high byte 
    data[1] = _id[0];    // Transaction ID low byte 
    data[2] = 11;     // Packet Length 
    data[3] = unit;     // Slave address 
    data[4] = fctReadFile;    // Function code = 20 
    //byte[] _adr = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)startAddress)); 
    data[5] = 7;    // Byte Count 0x07 to 0xF5 bytes 
    data[6] = 6;    // Reference Type 
    byte[] _FileNum = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)fileNumber)); 
    data[7] = 0;  // File Number Hi 
    data[8] = 1;   // File Number Lo 
    byte[] _RecordNum = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder(10000)); 
    data[9] = _RecordNum[0];   // Record Number Hi 
    data[10] = _RecordNum[1];   // Record Number Lo 
    byte[] _RecordLength = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)recordLength)); 
    data[11] = 0;   // Record Length Hi 
    data[12] = 6;   // Record Length Lo 
    return data; 
} 
:今、私はちょうどそれを扱うことができ、私自身の関数を作成しようとしていますが、私が得る応答は、2バイトの10の配列と、ここで1

は、私が使用して試したリクエストヘッダです、

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) CallException(id, unit, write_data[7], excExceptionConnectionLost); 

      // ------------------------------------------------------------ 
      // Response data is slave exception 
      if (function > excExceptionOffset) 
      { 
       function -= excExceptionOffset; 
       CallException(id, unit, function, tcpSynClBuffer[8]); 
       return null; 
      } 
      // ------------------------------------------------------------ 
      // Write response data 
      else if ((function >= fctWriteSingleCoil) && (function != fctReadWriteMultipleRegister)&&(function!=fctReadFile)) 
      { 
       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) 
     { 
      CallException(id, write_data[6], write_data[7], excExceptionConnectionLost); 
     } 
    } 
    else CallException(id, write_data[6], write_data[7], excExceptionConnectionLost); 
    return null; 
} 

TCP同期バッファを返す[0,0,11,1,0,3,6,128,1,0,10,1,0:

そして、ここでは、要求を呼び出すコードであります0,0、...]

更新:

私はこれにリクエストヘッダを変更しました。

private byte[] CreateReadFileHeader(ushort id, byte unit, byte count, ushort fileNumber, ushort recordNumber, ushort recordLength) 
{ 
    byte[] data = new byte[17]; 

    byte[] _id = BitConverter.GetBytes((short)id); 
    data[0] = 0;//_id[1];    // Transaction ID high byte 
    data[1] = 0;//_id[0];    // Transaction ID low byte 
    byte[] _size = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)(11))); 
    data[2] = 0;    //Protocol identifier 
    data[3] = 0;    //Protocol identifier 
    data[4] = 0;    // Packet Length 
    data[5] = 11;     // Packet Length 
    data[6] = unit;     //Unit Identifier 
    data[7] = fctReadFile;    // Function code 
    //byte[] _adr = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)startAddress)); 
    data[8] = 0;    // Byte Count 0x07 to 0xF5 bytes 
    data[9] = 7;    // Byte Count 0x07 to 0xF5 bytes 
    data[10] = 6;    // Reference Type 
    byte[] _FileNum = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)fileNumber)); 
    data[11] = 0;  // File Number Hi 
    data[12] = 1;   // File Number Lo 
    byte[] _RecordNum = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder(10000)); 
    data[13] = _RecordNum[0];   // Record Number Hi 
    data[14] = _RecordNum[1];   // Record Number Lo 
    byte[] _RecordLength = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)recordLength)); 
    data[15] =0;   // Record Length Hi 
    data[16] =1;   // Record Length Lo 
    return data; 
} 

//I use this function to call the request 
    public void ReadFile(ushort id, byte unit, ref byte[] values) 
    { 
     byte[] write_data = CreateReadFileHeader(id, unit, 7, 1, 10000, 6); 
     tcpSynCl.Send(write_data, 0, write_data.Length, SocketFlags.None); 
     int result = tcpSynCl.Receive(tcpSynClBuffer, 0, tcpSynClBuffer.Length, SocketFlags.None); 
     values = tcpSynClBuffer; 
    } 

、それが今で返します。

[0,0,0,0,0,5,1,20,4,0,0,0、..]

答えて

1

私は考え出しそれを出す。私が行った更新は正しいヘッダーを作成しましたが、ファイルが破損している可能性がありますので、別のファイルを読むことに決めました。ここで

は私のコードです:

public void ReadFile(ushort id, byte unit, ref byte[] values) 
{ 
    byte[] write_data = CreateReadFileHeader(id, unit, 7, 2, 0, 56797); 
    byte[] Buffer = new byte[2048]; 
    tcpSynCl.Send(write_data, 0, write_data.Length, SocketFlags.None); 
    int result = tcpSynCl.Receive(Buffer, 0, Buffer.Length, SocketFlags.None); 
    values = Buffer; 

} 


private byte[] CreateReadFileHeader(ushort id, byte unit, byte count, ushort fileNumber, ushort recordNumber, ushort recordLength) 
{ 
    byte[] data = new byte[17]; 

    byte[] _id = BitConverter.GetBytes((short)id); 
    data[0] = _id[1];    // Transaction ID high byte 
    data[1] = _id[0];    // Transaction ID low byte 
    byte[] _size = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)(11))); 
    data[2] = 0; 
    data[3] = 0; 
    data[4] = 0;    // Packet Length 
    data[5] = 11;     // Packet Length 
    data[6] = unit;     // Slave address 
    data[7] = fctReadFile;    // Function code 
    //byte[] _adr = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)startAddress)); 
    byte[] _Count = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)count)); 
    data[8] = _Count[0];    // Byte Count 0x07 to 0xF5 bytes 
    data[9] = _Count[1];    // Byte Count 0x07 to 0xF5 bytes 
    data[10] = 6;    // Reference Type 
    byte[] _FileNum = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)fileNumber)); 
    data[11] = _FileNum[0];  // File Number Hi 
    data[12] = _FileNum[1];   // File Number Lo 
    byte[] _RecordNum = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder(10000)); 
    data[13] = _RecordNum[0];   // Record Number Hi 
    data[14] = _RecordNum[1];   // Record Number Lo 
    byte[] _RecordLength = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)recordLength)); 
    data[15] = _RecordLength[0];   // Record Length Hi 
    data[16] = _RecordLength[1];   // Record Length Lo 
    return data; 
} 

そして、ここでは、応答である:

[0,0,0,0,187,189,1,20,186,68,97,116,101,44,84,105,109,101,44,67 、97,115,101,95,84, 、44,68,57,95,84,44,68,49,95,84,44,65,109,98,95,84,44,82,72,44,68,80、 44,67,117,114 ,44,80,68,95,86,44,80,111,119,101,114,44,68,86,44,70,97,117,108,116,76,111,44,70 ,97,117,108,116,72,105,10,0,0,0、 0,0,0、.....]

これは、ModbusとC#で作業している人には便利だと思います。

関連する問題