# IEC 60870-5-104 Datenübertragung gestört



## Netwalker (22 November 2010)

Ich muss ein Beckhoff CP66 an eine IDS-SPS Acos 750 mittels der Schnittstelle IEC 60870-5-104 anbinden. Die Kommunikation steht, allerdings ist das Senden von Daten mittels Bckhoff CPs noch fehlerhaft. Auf Seiten der IDS-SPS müsste alles korrekt eingerichtet sein, da ich mit der ganzen Sache bei IDS vorort war und das mit einem IDS-Servicetechniker durchgegangen bin.

Kann jemand erkennen wo der fehler liegt? Nachfolgend liste ich die Nötigen Infos zur Kommunikation:

Ich habe ein Szenario durchgespielt bei dem ich einen Befehl von dem Beckhoffpanel an die Ids-SPS schickte und anschliesend eine Meldung von der Ids-SPS an das Beckhoff Panel. Das Senden der Meldung funktionierte, das Senden des Befehls allerdings nicht korrekt. Den ganzen Verkehr auf der Schnittstelle habe ich mit einem Programm von Ids(IEC Tester) siehe unten. Durchgeführt habe ich das ganze mit dem SPS-Beispielprogramm _MiniMasterSample_(von Beckhoff Website, Programm siehe unten). Am Ende des Test-Szenarios habe ich von dem IEC-Tester aus nochmals einen Befehl auf die Ids-SPS gesendet, welcher dort erfolgeich empfangen wurde.



Aktuelle Einstellungen des Projekts:​

Einstellungen die auf beiden Geräten gleich sind:
max. unquitierte ADPUs bei Übertragung (k) : 12
max. empfangene ADPUs bei Übertragung (w) : 8
Verbindungstimeout (t0): 30s
Quittierungstimeout (t1): 15s
Quittierungstimeout (t2): 10s
Verbindungstest Timeout (t3): 20s
Übertragungsursache (Cause of Transfer size): 2 octets
Geräteadressengröße (Common ASDU address size): 2 octets
Informationsobjektadressengröße (Information object adress size): 3 octets
Geräteadresse (Common ASDU adress): 40​ 
auf Beckhoffseite ist des weiteren folgendes eingestellt (wofür ich auf IDS Seite keine Einstellmöglichkeit fand):
Originator address: 1
Max. APDU length: 253 (muss dieser Wert bei beiden gleich sein? ich konnte keine Einstellmöglichkeit finden)
Local port address: 2404
Local host adress: 192.168.253.97 (dies ist die eigene IP des Slave Bedienteils)​ 

auf IDS-Seite ist des weiteren folgendes eingestellt:
Max. APDU length: 112 (muss dieser Wert bei beiden gleich sein? ich konnte keine Einstellmöglichkeit finden)
IP des Master(Zieladresse): 192.168.253.97
Eigene IP-Adresse: 192.168.253.99​ 


Das Programm der Beckhoff SPS CP66:

```
PROGRAM MAIN
VAR
 AODB  : ARRAY[0..1] OF ST_IEC870_5_101AODBEntry;
 hTable  : T_HAODBTable;
 client  : FB_IEC870_5_104Master;
 init   : BOOL := TRUE;
 asduAddr : DWORD := 40; (* Common ASDU address of remote (slave) station *)
 SPI   AT%MX0.0 : BOOL;(* Single point information (data point used in monitoring direction slave->master) *)
 SCS   AT%MX1.5 : BOOL;(* Single command state (data point used in control direction master->slave) *)
 fbCloseAll : FB_SocketCloseAll;
END_VAR
 
 
 
fbCloseAll( bExecute := init );
IF fbCloseAll.bBusy AND NOT init THEN
 RETURN;
END_IF
IF init THEN
 init := FALSE;
 (* Configure protocol parameter *)
 client.protPara.sRemoteHost := '192.168.253.99'; (* IP address of remote (slave) station *)
 client.protPara.nRemotePort := 2404; (* Port number (default) of remote (slave) station *)
 (* Configure system parameter *)
 client.sysPara.dbgMode := IEC870_DEBUGMODE_DEVSTATE; (* Enable debug output of device state change *)
 client.sysPara.asduAddr := asduAddr; (* common ASDU address of remote (slave) station *)
 
 F_iecCreateTableHnd( ADR( AODB ), SIZEOF( AODB ), hTable );(* Initialize database handle *)
 
 (* Configure one single point in monitoring direction *)
 F_iecAddTableEntry( M_SP_NA_1, (* type is single point *)
      asduAddr, (* common ASDU address *)
      4400, (* information object address *)
      IEC870_GRP_INROGEN, (* interrogation group *)
      0,(* multiplier (not used) *)
      MAP_AREA_MEMORY,(* map this single point value TO PLC memory area (buffer) *)
      0, (* map TO byte offset *)
      0, (* map TO bit offset *)
      0, (* not used *)
      hTable );(* database handle *)
 (* Configure one single command in control direction *)
 F_iecAddTableEntry( C_SC_NA_1, (* type is single command *)
      asduAddr, (* common ASDU address *)
      25577,(* information object address *)
      0, (* group (not used) *)
      0, (* multiplier (not used) *)
      MAP_AREA_MEMORY, (* map this single command value FROM PLC memory area (buffer) *)
      1, (* map FROM byte offset *)
      5, (* map FROM bit offset *)
      0, (* not used *)
      hTable );(* database handle *)
ELSE
 client( pAOEntries := ADR( AODB ),
   cbAOEntries := SIZEOF( AODB ),
   pInputs  := 0, (* not used *)
   cbInputs  := 0, (* not used *)
   pOutputs  := 0, (* not used *)
   cbOutputs  := 0, (* not used *)
   pMemory  := ADR( %MB0 ),
   cbMemory  := 2,(* 2 byte size *)
   pData   := 0, (* not used *)
   cbData   := 0, (* not used *)
   bEnable  := TRUE,
   hTable   := hTable );
 
 (* Check for device errors, remove them and log message to the TwinCAT System Manager log view *)
 REPEAT
  client.system.device.errors.RemoveError( );
  IF client.system.device.errors.bOk THEN
   ADSLOGSTR( ADSLOG_MSGTYPE_ERROR OR ADSLOG_MSGTYPE_LOG,
      'IEC60870-5-104 master error: 0x%s',
      DWORD_TO_HEXSTR( client.system.device.errors.getError.nErrId, 8, FALSE) );
  END_IF
 UNTIL NOT client.system.device.errors.bOk
 END_REPEAT
END_IF
```
 
Log der Schnittstelle (interpretiert):






Log des Systemmanagers von Beckhoff:






Screenshot der Fehlermeldung des Funktionsbausteins _F_iecAddTableEntry (_Diese besagt laut Fehlertabelle, dass das Applikationsobjekt nicht in der Datenbank sei)





Ich weis das is nicht das einfachste Rätsel, aber vielleicht weis ja ein Crack rat? Ich verzweifle nämlich bald


----------



## Netwalker (22 November 2010)

Hier noch als nachtrag den Log der Schnittstelle (hexadezimal):

```
Log-Start: 22.11.2010 10:24:15
10:27:15.699 L7TX: 87 00 40 00 00 87 00 00 00 00 AA 01 00 04 00 10 00 10 09 FC 9E DE 00 46 AB 5F 00 
10:27:15.088 L7RX: 87 00 40 00 00 87 00 00 28 00 01 AA 00 0D 00 11 01 02 03 01 00 28 70 07 00 10 C7 
10:27:50.062 L7RX: 09 01 03 00 28 00 02 20 00 0E 00 00 
10:27:50.072 L7RX: 09 01 03 00 28 00 08 20 00 03 00 00 
10:28:10.012 L7RX: 09 01 03 00 28 00 04 20 00 00 00 00 
10:28:10.017 L7RX: 09 01 03 00 28 00 04 20 00 00 00 00 
10:28:31.077 L7RX: 1E 01 03 00 28 00 12 08 00 00 76 2F 1C 0A 16 0B 0A 
10:28:31.085 L7RX: 1E 01 03 00 28 00 11 02 00 00 A2 2F 1C 0A 16 0B 0A 
10:28:31.094 L7RX: F3 01 03 00 28 00 00 00 00 34 D3 2F 1C 0A 16 0B 0A 81 02 00 00 E0 00 00 00 D0 
10:28:32.000 L7RX: 1E 01 03 00 28 00 26 02 00 01 FC 2F 1C 0A 16 0B 0A 
10:28:32.006 L7RX: 1E 01 03 00 28 00 26 02 00 00 02 30 1C 0A 16 0B 0A 
10:28:32.012 L7RX: 1E 01 03 00 28 00 8B 02 00 01 07 30 1C 0A 16 0B 0A 
10:28:32.019 L7RX: 1E 01 03 00 28 00 8B 02 00 00 10 30 1C 0A 16 0B 0A 
10:28:36.096 L7RX: 1E 01 03 00 28 00 26 02 00 01 8F 43 1C 0A 16 0B 0A 
10:28:37.005 L7RX: 1E 01 03 00 28 00 26 02 00 00 90 43 1C 0A 16 0B 0A 
10:28:37.021 L7RX: 1E 01 03 00 28 00 8B 02 00 01 90 43 1C 0A 16 0B 0A 
10:28:37.026 L7RX: 67 01 47 00 28 00 00 00 00 73 43 1C 0A 16 0B 0A 
10:28:37.039 L7RX: 1E 01 03 00 28 00 8B 02 00 00 90 43 1C 0A 16 0B 0A 
10:28:37.046 L7RX: 64 01 07 01 28 00 00 00 00 14 
10:28:37.056 L7RX: 01 8A 14 00 28 00 EE 00 00 80 80 00 01 00 00 00 01 00 00 
10:28:37.073 L7RX: 01 C0 14 00 28 00 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
10:28:37.097 L7RX: 01 11 14 00 28 00 5A 00 00 00 60 00 00 00 61 00 00 00 65 00 00 00 70 00 00 00 71 00 00 00 75 00 00 00 7C 00 00 80 82 00 00 00 FE 00 00 00 FF 00 00 00 11 02 00 00 26 02 00 00 27 02 00 00 8B 02 00 00 00 04 00 01 30 11 00 00 
10:28:38.013 L7RX: 09 88 14 00 28 00 01 20 00 00 00 00 0E 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 03 00 00 
10:28:38.027 L7RX: 64 01 0A 01 28 00 00 00 00 14 
10:28:38.040 L7RX: 65 01 07 01 28 00 00 00 00 05 
10:28:38.054 L7RX: 65 01 0A 01 28 00 00 00 00 05 
10:28:51.059 L7RX: 3A 01 07 01 28 00 E9 63 00 01 C7 7B 1C 0A 36 0B 0A 
10:28:51.074 L7RX: 3A 01 0A 01 28 00 E9 63 00 01 EF 7B 1C 0A 36 0B 0A 
10:28:59.085 L7RX: 09 01 03 00 28 00 03 20 00 14 00 00 
10:29:06.023 L7RX: 3A 01 07 01 28 00 E9 63 00 00 5B B5 1C 0A 36 0B 0A 
10:29:06.028 L7RX: 3A 01 0A 01 28 00 E9 63 00 00 83 B5 1C 0A 36 0B 0A 
10:29:32.079 L7RX: 01 01 03 00 28 00 30 11 00 01 
10:29:38.077 L7RX: 1E 01 03 00 28 00 26 02 00 01 AE 49 1D 0A 16 0B 0A 
10:29:39.032 L7RX: 1E 01 03 00 28 00 26 02 00 00 B0 49 1D 0A 16 0B 0A 
10:29:39.040 L7RX: 1E 01 03 00 28 00 8B 02 00 01 B2 49 1D 0A 16 0B 0A 
10:29:39.048 L7RX: 1E 01 03 00 28 00 8B 02 00 00 B2 49 1D 0A 16 0B 0A 
10:29:43.056 L7RX: 01 01 03 00 28 00 30 11 00 00 
10:29:43.093 L7RX: 1E 01 03 00 28 00 26 02 00 01 6B 5D 1D 0A 16 0B 0A 
10:29:44.003 L7RX: 1E 01 03 00 28 00 26 02 00 00 6D 5D 1D 0A 16 0B 0A 
10:29:44.013 L7RX: 1E 01 03 00 28 00 8B 02 00 01 70 5D 1D 0A 16 0B 0A 
10:29:44.021 L7RX: 1E 01 03 00 28 00 8B 02 00 00 73 5D 1D 0A 16 0B 0A 
10:29:44.035 L7RX: 67 01 47 00 28 00 00 00 00 47 5D 1D 0A 16 0B 0A 
10:29:44.058 L7RX: 64 01 07 01 28 00 00 00 00 14 
10:29:44.069 L7RX: 01 8A 14 00 28 00 EE 00 00 80 80 00 01 00 00 00 01 00 00 
10:29:44.084 L7RX: 01 C0 14 00 28 00 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
10:29:45.008 L7RX: 01 11 14 00 28 00 5A 00 00 00 60 00 00 00 61 00 00 00 65 00 00 00 70 00 00 00 71 00 00 00 75 00 00 00 7C 00 00 80 82 00 00 00 FE 00 00 00 FF 00 00 00 11 02 00 00 26 02 00 00 27 02 00 00 8B 02 00 00 00 04 00 01 30 11 00 00 
10:29:45.016 L7RX: 09 88 14 00 28 00 01 20 00 00 00 00 0E 00 00 14 00 00 00 00 00 01 00 00 00 00 00 00 00 00 03 00 00 
10:29:45.024 L7RX: 64 01 0A 01 28 00 00 00 00 14 
10:29:45.037 L7RX: 65 01 07 01 28 00 00 00 00 05 
10:29:45.053 L7RX: 65 01 0A 01 28 00 00 00 00 05 
10:30:09.189 L7TX: 2D 01 06 00 28 00 E9 63 00 0D 
10:30:09.043 L7RX: 3A 01 07 00 28 00 E9 63 00 0D 27 C1 1D 0A 36 0B 0A 
10:30:14.316 L7TX: 2D 01 06 00 28 00 E9 63 00 0C 
10:30:14.055 L7RX: 3A 01 07 00 28 00 E9 63 00 0C 27 D5 1D 0A 36 0B 0A
```


----------



## Netwalker (26 November 2010)

Ich habe die Vermutung, dass mein Problem bei der unterschiedlichen APDU Längem liegt. Meine Annahme:
Die Zentralstation hat eine größere ADPU Länge als die Unterstation. Deshalb können die kleineren Frames der Unterstation von der Zentralstation sauber ausgewertet werden. Andersrum ist jedoch der Frame größer als die Länge die ausgewertet werden. Der Grund warum ich Daten in Monitordirection empfangen kann, jedoch das senden in Controldirection nicht empfangen kann. => Somit muss ich die APDU Länge der Kommunikation anpassen.

*Kann mir jemand sagen, wo ich die APDU Länge auf Beckhoff-SPS oder IDS-SPS anpassen kann?*


----------



## Netwalker (8 Dezember 2010)

Hier des Rätsels Lösung:

Die Fehler auf dem Telegramm lagen an der abweichenden ADPU Länge. Sprich der größe des Datenframes, der übertragen wird.

Das dieser auf IDS-Seiten auf 120 begrenzt ist, habe ich dies auf Seiten folgendermasen Beckhoff angepasst:


```
client.protPara.APDULength:=120;
```

Um zunächst nicht viel Datenverkehr auf der Schnittstelle zu haben, können die häufigen Generalabfragen auch abgestellt werden:


```
client.acqPara.arrGenro[0].bEnable:=FALSE;
```

somit konnte ich eine saubere Verbindung herstellen *ACK*


----------



## Lars Weiß (8 Dezember 2010)

Wird im IEC-Profil eingestellt. Im INA-File steht dann:


```
[IECProfil]
ASDULen = 2 
CauseLen = 2 
AddressLen = 3 
TimeStampLen = 7
MaxTelLen = 112 
Knoten = 0
```
Und in ACOS-ET siehts so aus:


----------



## Lars Weiß (8 Dezember 2010)

Nur, die max.APDU gilt eigentlich nur für 101...meine ich zumindest


----------

