2016-06-28 3 views
1

Ich habe gerade an einem Projekt mit dieser Modbus TCP-Bibliothek gearbeitet (https://github.com/stephanstricker/modbusTCP/tree/master/ModbusTCP/ModbusTCP) und diese Dokumentation für einen Verweis auf Funktion 20 (http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf). Das Problem ist, dass der Funktionscode 20 (allgemeine Referenz/Datei lesen) nicht unterstützt wird. Im Moment bin ich nur versucht, meine eigene Funktion zu erstellen, die damit umgehen kann jedoch die Antwort, die ich erhalten, ist eine Zwei-Byte-Array von 10 und 1.Wie implementieren Sie die Modbus-Funktion 20 mit C#?

Hier wird der Request-Header Ich habe versucht, mit:

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; 
} 

Und hier ist der Code, der die Anforderung aufruft:

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; 
} 

die TCP-Sync-Puffer zurückkehrt [0,0,11,1,0,3,6,128,1,0,10,1,0, 0,0, ...]

Update:

Ich änderte meine Anfrage Header zu diesem.

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; 
    } 

und es gibt jetzt:

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

Antwort

1

Ich dachte, es aus. Das Update, das ich gemacht habe, hat den korrekten Header erstellt, aber die Datei ist möglicherweise beschädigt worden, also habe ich mich entschieden, eine andere Datei zu lesen, und ich war erfolgreich.

Hier ist mein Code:

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; 
} 

Und hier ist die Antwort:

[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,11,44,70 , 97,117,108,116,72,105,100,0,0,0, 0,0,0, .....]

Ich hoffe, dass dies für jeden nützlich ist, der mit Modbus und C# arbeitet.

Verwandte Themen