Step 7 AG_RECV (FC6) für Modbus TCP Verbindung

Zuviel Werbung?
-> Hier kostenlos registrieren
Folgendes hat sich nun eingestellt:

AG_SEND funktioniert fehlerfrei, gesendet wird der Header 12Byte
DB81_Tx.JPG

AG_RECV erzeugt eine Fehlermeldung (Auszug aus der Hilfe):
AG_RECV_ERR.JPG
der AG_RECV soll hier reinschreiben (9Byte)
DB82_Rx.JPG

Einen weiteren AG_RECV Aufruf habe ich gem. der Hilfe auch gemacht, hier sollen die Messwerte vom PAC empfangen werden
Empfangen.JPG

Die Frage stellt sich mir nun, warum der erste AG_RECV Aufruf mit einer Fehlermeldung "endet"?
Woher weiss ich wie groß der tatsächliche Datenbereich, der vom PAC zurückgegebenen wird, ist?

Gruß
Matze
 
Hallo Der Matze,

zwar hat du schon viele Hilfen bekommen und bist auch schon fast am Ziel. Trotzdem anbei meine Version zum Auslesen des PAC4200. Vielleicht hilft's Dir ja...

Anhang anzeigen 32230

Hallo und danke für das Beispiel,
wenn ich das so realisiere bekomme ich am AG_RECV das gleiche Fehlerbild wie unter #21...
Der AG_RECV gibt den Fehler 80b1(hex) aus. :?::sad:
Irgendwo hat sich nachwievor der Fehlerteufel versteckt.

Gruß
Matze
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn ich da hier so lese beginne ich mich zu fragen ob das mit dem AG_RCV überhaupt so geht.
Der AG_RECV wirft im Falle von Matze ja völlig legitim den 80B1.
Die empfangene Länge passt ja in keinem der beiden Aufrufe mit der Größe des Empfangs-Puffers zusammen.

Komischerweise wurden in dem Siemens-Beispiel das PN/DP gepostet hat die 4 Delimiter-Bytes auch einzeln byteweise mit 4 AG_RCV-Aufrufen entgegengenommen.

Könnte es sein dass der AG_RCV den 80B1 wirft sobald an RECV ein Datenbereich von mehr als 1 Byte angegeben ist und dieser dann nicht mit den empfangenen Daten zusammenpasst? Sonst hätte man im Siemens-Beispiel ja auch gleich alle 4 Bytes auf einen Schlag entgegen nehmen können.
 
Zuletzt bearbeitet:
Könnte es sein dass der AG_RCV den 80B1 wirft sobald an RECV ein Datenbereich von mehr als 1 Byte angegeben ist und dieser dann nicht mit den empfangenen Daten zusammenpasst? Sonst hätte man im Siemens-Beispiel ja auch gleich alle 4 Bytes auf einen Schlag entgegen nehmen können.
Somit ist die Fehlermeldung dann eine "Falschmeldung"?
Versatz in der Empfangsablage gab es dennoch.
 
Somit ist die Fehlermeldung dann eine "Falschmeldung"?
Nein das meinte ich nicht.
Es wird versucht eine Empfangsdatenlänge von 9Byte + angefragte Registeranzahl*2 einmal mit einem Empfangsfeld von 9 Byte (Problem - Siehe unten) und einmal mit einem Empfangsfeld von Registeranzahl*2 entgegen zu nehmen.
Passt in keinem der beiden Fälle zusammen und wirft somit legitim den Fehler 80B1.

Insofern wundert es mich wie es im Siemens Beispiel möglich ist, Daten eines längeren Telegramms mit einen Empfangsbereich mit Größe 1 entgegen zu nehmen, ohne ebenfalls den 80B1 zu bekommen. Daher meine Vermutung das entweder...
  • Der 80B1 auch im Siemens-Beispiel ignoriert wird.
  • Der AG_RCV bei angaben von Länge 1 im RECV keinen 80B1 wirft.

Da der AG_RCV dir trotzdem Daten in den DB schreibt kann man den 80B1 vielleicht ignorieren.
Der AG_RCV wird solange schreiben bis die Größe des angegeben Empfangspuffers erreicht ist und dann aufhören.
Vielleicht... weiß es nicht genau.

Mir ist aber gerade aufgefallen warum du auf jeden Fall einen Datenversatz bekommst.
Vergleiche meinen Aufbau des Rx-Headers mit deinem Aufbau.

Du hast den "Lenght of Payload" als INT spezifiziert was den Aufbau 10 Byte lang macht.
Damit empfängt auch der erste AG_RCV 10 Byte und der zweite dann die restlichen Bytes.
Somit hast du automatisch schon einen Versatz von einem Byte da der Modbus-Header nur 9 Byte lang ist.

Doch selbst wenn du den Rx-Header genauso aufbaust wie ich, wird ein Padding-Byte am Ende angefügt.
Der an AG_RCV übergebene ANY-Pointer hätte wieder einen Wiederholungsfaktor von 10.
Du müsstet den Wiederholungsfaktor des ANY manuell auf 9 korrigieren oder testweise den ANY-Pointer am ersten AG_RCV manuell angeben.
Also p#DB10.DBX0.0 Byte 9.

Die gegenseitige Verriegelung wirst du anders lösen müssen. Der erste AG_RCV wird dir wohl immer den 80B1 und somit kein ENO liefern.
Wie sehen denn die Daten in deinem "Rx".Rx_Header aus? Steht da in Byte0-8 etwas vernünftiges drin?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Mir ist aber gerade aufgefallen warum du auf jeden Fall einen Datenversatz bekommst.
Vergleiche meinen Aufbau des Rx-Headers mit deinem Aufbau.

Doch selbst wenn du den Rx-Header genauso aufbaust wie ich, wird ein Padding-Byte am Ende angefügt.
Der an AG_RCV übergebene ANY-Pointer hätte wieder einen Wiederholungsfaktor von 10.
Du müsstet den Wiederholungsfaktor des ANY manuell auf 9 korrigieren oder testweise den ANY-Pointer am ersten AG_RCV manuell angeben.
Also p#DB10.DBX0.0 Byte 9.

Die gegenseitige Verriegelung wirst du anders lösen müssen. Der erste AG_RCV wird dir wohl immer den 80B1 und somit kein ENO liefern.
Wie sehen denn die Daten in deinem "Rx".Rx_Header aus? Steht da in Byte0-8 etwas vernünftiges drin?

Hallo und danke für den Hinweis, habe ich übersehen.
Heute früh gab es kurzzeitig einen Lichtblick...
- Header angepasst
- Empfangsdatenbereich korrigiert (auf nun 604 Bytes = Empfangs-DB)
- Die 604 Bytes habe ich im Tx Header ebenfalls eingetragen
- AG_SEND: Tx-Header im DB81 12 Bytes
- AG_RECV: Rx-Header im DB82 9 Bytes
- AG_RECV: Messwerte in DB83 604 Bytes

AG_SEND.JPG
AG_RECV_1.JPG
AG_RECV_2.JPG

Es kamen die Messwerte ohne Versatz, allerdings wurden diese eingelesenaber nicht aktualisiert (zyklisch) :???:
Am AG_RECV wurde auch 80B1 ausgegeben.

Daten.JPG

Nachdem Versuch dass die Werte zyklisch aktualisiert werden, gibt es wieder einen Versatz. Und es lässt sich nicht mehr reproduzieren, dass die Werte wieder "passig" im Empfangs DB landen :confused:

Der Rx-Header sieht jetzt so aus:
Rx.JPG
Momentan habe ich dazu keine Idee aber das Ziel rückt näher!

Gruß
Matze
 
Zuletzt bearbeitet:
Hallo,

wollte nicht extra einen Thread auf machen. habe dazu auch eine Frage und zwar nutze ich den FC5 und FC6 zum Kontaktaustausch mit einer Wago 750-880 per TCP.
Ich habe mir zwart mal den FC 5 und FC 6 angeschaut, also Empfangen tue ich ich was von der Wago, wenn ich dort ab MW 62 was eintrage kann ich den im DB 32 lesen, dort habe ich noch einen DB31 zum schreiben. Frage ist, welches MW ich in der Wago schreiben tue, da ich bis jetzt nur lesen gebraucht habe.

hier mal mein FC5
Code:
 TAR1  #AR1_STORE
      TAR2  #AR2_STORE







      L     0
      T     #STATUS
      SET   
      R     #ERROR
      R     #DONE
      R     #STATIC
      R     #GEN_DS_LESEN
      R     #SEND_BUSY
      R     #SEND_CONF
      R     #SEND_IN_PROGRESS
      R     #OFFSETTING
      R     #READING







      L     1
      L     #ID
      >I    
      SPB   NKO
      L     16
      <=I   
      SPB   NOK

NKO:  L     W#16#8186
      SPA   ERRS








NOK:  L     #LADDR
      SLD   3

      LAR1  
      L     PEW [AR1,P#4.0]
      SRW   7
      SPZ   STAA
      SRW   1
      SPZ   GEN1


STAA: SET   
      S     #STATIC


















      L     #ID
      DEC   1
      SRW   2
      SLW   1
      L     #LADDR
      +I    
      INC   8
      SLD   3
      LAR1  




      L     #ID
      DEC   1
      SRW   2
      L     PEW [AR1,P#0.0]
      SPZ   UG
      SPA   M5

UG:   SRW   8
M5:   L     #ID
      SRW   1
      SPP   UGR

      TAK   
      SRW   6

      SPA   GER

UGR:  TAK   
      SRW   2

GER:  L     B#16#3
      UW    
      L     1
      ==I   
      SPB   BUSY
      TAK   
      L     2
      ==I   
      SPB   ABG
      TAK   
      L     0
      ==I   
      SPB   CONT


      U     #ACT
      L     W#16#8183
      SPB   ERRS
      SET   
      SAVE  
      L     0
      SPA   END









GEN1: L     #ID
      DEC   1
      L     1
      SLW   
      L     PED [AR1,P#10.0]
      T     #TEMP_DATA
      UW    
      SPP   SBSY
      SPA   NXT
SBSY: S     #SEND_BUSY
NXT:  TAK   
      L     #TEMP_DATA
      SRD   16
      UW    

      SPP   SCNF
      SPA   NXTT
SCNF: S     #SEND_CONF


NXTT: U     #SEND_BUSY
      U     #SEND_CONF
      S     #SEND_IN_PROGRESS

      SPB   CNT

      U     #SEND_BUSY
      SPB   BUSY

      U     #SEND_CONF
      SPB   ABG





CONT: U     #ACT
      SPB   CNT
      SET   
      SAVE  
      L     0
      SPA   END




CNT:  L     #ID
      L     15
      +I    
      T     #DS_NR
















      L     P##SEND
      LAR2  
      L     B [AR2,P#1.0]
      L     2
      <>I   
      TAK   
      SPB   WRD
      L     W [AR2,P#2.0]
      SPA   BITE
WRD:  L     4
      <>I   
      TAK   
      SPB   DWRD
      L     W [AR2,P#2.0]
      SLW   1
      SPA   BITE
DWRD: L     6
      ==I   
      TAK   
      SPB   TYDW
      L     W#16#8184
      SPA   ERRS
TYDW: L     W [AR2,P#2.0]
      SLW   2
BITE: T     #FC_DATA_LEN


















      L     #LEN

      L     #FC_DATA_LEN
      <=I   
      SPB   LVST
      L     W#16#8185
      SPA   ERRS


LVST: TAK   
      T     #FC_DATA_LEN
      SRD   16
      SPZ   LOKK
      L     W#16#8F22
      SPA   ERRS






LOKK: UN    #STATIC
      SPB   HSDL


      L     P##SEND
      LAR1  

      L     P##STORE
      LAR2  

      L     W#16#1002
      T     LW [AR2,P#0.0]

      L     W [AR1,P#4.0]
      T     LW [AR2,P#4.0]

      L     #FC_DATA_LEN
      T     LW [AR2,P#2.0]

      L     D [AR1,P#6.0]
      T     LD [AR2,P#6.0]

      U     #STATIC
      SPB   TTT













HSDL: L     #LADDR
      SLD   3
      LAR1  
      U     #READING
      L     B#16#76
      SPB   III
      L     B#16#7E
III:  L     #DS_NR
      SLW   8
      OW    
      SLD   16
      L     #FC_DATA_LEN
      OD    
      T     PAD [AR1,P#4.0]










      L     250
STRT: T     #LOOP_COUNT
      L     PED [AR1,P#4.0]
      T     #TEMP_DATA

      SRD   17
      SPZ   VAL




      SRW   3
      SPZ   RECX

      U     #READING
      SPB   WEIT
      SPA   DOKK
RECX: UN    #READING
      SPB   WEIT


DOKK: L     #TEMP_DATA

      SRD   21
      SPZ   DDD
      SPA   WEIT
DDD:  SRW   3
      L     #DS_NR
      <>I   
      SPB   WEIT

      SPA   LGBY

WEIT: L     #LOOP_COUNT
      LOOP  STRT

      L     W#16#80C4
      T     #RET_WT_STORE
      SPA   ERRR

















LGBY: L     #TEMP_DATA

      SRD   19

      SPZ   NSQ

      SET   
      S     #OFFSETTING
      SPA   ERRR
NSQ:  L     #TEMP_DATA
      T     #RET_WT_STORE
      SPA   ERRR











VAL:  SET   
      L     #TEMP_DATA


      SRD   20



      SPZ   RECV

      U     #READING
      UN    #SEND_IN_PROGRESS
      L     W#16#80C2
      SPB   ERRS
      U     #READING
      SPB   BUSY
      SPA   DOK
RECV: UN    #READING
      UN    #SEND_IN_PROGRESS
      L     W#16#80C2
      SPB   ERRS
      UN    #READING
      SPB   BUSY

DOK:  L     #TEMP_DATA
      SRD   24
      L     #DS_NR
      ==I   
      SPB   DSOK
      U     #SEND_IN_PROGRESS
      SPB   BUSY
      L     W#16#80C2
      SPA   ERRS

DSOK: U     #READING
      SPB   RET1





      L     #FC_DATA_LEN

      L     #TEMP_DATA
      T     #OFFSET
      -I    
      T     #DIFF


      L     240
      <=I   
      SPB   BBC

      T     #DIFF












BBC:  L     P##SEND
      LAR1  

      L     P##STORE
      LAR2  


      L     W#16#1002
      T     LW [AR2,P#0.0]

      L     #DIFF
      T     LW [AR2,P#2.0]

      L     W [AR1,P#4.0]
      T     LW [AR2,P#4.0]

      L     D [AR1,P#6.0]
      L     #OFFSET
      SLD   3
      +D    
      T     LD [AR2,P#6.0]



TTT:  CALL  "WR_REC"
       REQ    :=TRUE
       IOID   :=B#16#54
       LADDR  :=#LADDR
       RECNUM :=#DS_NR
       RECORD :=#STORE
       RET_VAL:=#RET_WT_STORE
       BUSY   :=#LBUSY




      L     #RET_WT_STORE
      L     W#16#F00
      UW    
      TAK   
      SPZ   EEA
      L     W#16#F00
      OW    
      T     #RET_WT_STORE



EEA:  U     #STATIC
      SPB   LLL

      U     #LBUSY
      =     #OFFSETTING

      L     #RET_WT_STORE
      L     0
      ==I   
      SPB   BUSY




SFCE: L     #LADDR
      SLD   3
      LAR1  
      L     PED [AR1,P#4.0]
      SRD   18
      L     #RET_WT_STORE
      SPZ   ERRS






















ERRR: L     #LADDR
      SLD   3
      LAR1  

      UN    #OFFSETTING
      SPB   GGG
      U     #READING
      L     B#16#74
      SPB   HHH

      L     B#16#7C
      SPA   HHH

GGG:  U     #READING
      L     B#16#70
      SPB   HHH

      L     B#16#78
HHH:  L     #DS_NR
      SLW   8
      OW    
      SLD   16
      L     #FC_DATA_LEN
      OD    
      T     PAD [AR1,P#4.0]









      L     250
STR2: T     #LOOP_COUNT
      L     PED [AR1,P#4.0]
      T     #TEMP_DATA

      SRD   17
      SPZ   STA

      SRW   4
      SPZ   STA

      SPA   BREK

STA:  L     #TEMP_DATA
      SRD   20

      SPZ   RECC
      U     #READING
      SPB   BREK
      SPA   DROK

RECC: UN    #READING
      SPB   BREK

DROK: SRW   4
      L     #DS_NR
      <>I   
      SPB   BREK

      L     #LOOP_COUNT
      LOOP  STR2

      L     W#16#80C4
      SPA   ERRS

BREK: U     #OFFSETTING
      SPB   BUSY
      L     #RET_WT_STORE
      SPA   ERRS







LLL:  U     #LBUSY
      SPB   BUSY

      L     0
      L     #RET_WT_STORE
      ==I   
      SPB   BUSY
      SPA   ERRS

      SPA   END





ABG:  S     #READING



      L     #ID
      L     31
      +I    
      T     #DS_NR




      U     #STATIC
      SPB   RET1


      L     1
      T     #FC_DATA_LEN










      SPA   HSDL

















RET1: CALL  "RD_REC"
       REQ    :=TRUE
       IOID   :=B#16#54
       LADDR  :=#LADDR
       RECNUM :=#DS_NR
       RET_VAL:=#RET_WT_STORE
       BUSY   :=#LBUSY
       RECORD :=#CON_INF

      U     #STATIC
      SPB   KKK


      U     #LBUSY
      =     #OFFSETTING


      L     #RET_WT_STORE
      L     0
      <>I   
      SPB   SFCE



      SPA   REOK


KKK:  U     #LBUSY
      SPB   BUSY

      L     0
      L     #RET_WT_STORE
      ==I   
      SPB   REOK
      L     W#16#F00
      UW    
      TAK   
      SPZ   ERRS
      L     W#16#F00
      OW    
      SPA   ERRS

REOK: L     0
      L     #CON_INF
      ==I   
      SPB   NUL




      L     B#16#83
      ==I   
      L     W#16#8183
      SPB   ERRS
      L     #CON_INF
      L     W#16#8300
      OW    
      SPA   ERRS



NUL:  SET   
      U     #STATIC
      SPB   AOK
      L     #LADDR
      SLD   3
      LAR1  
      L     250
NX:   T     #LOOP_COUNT
      L     #ID
      DEC   1
      L     1
      SLW   
      L     PED [AR1,P#10.0]
      SRD   16
      UW    
      SPZ   AOK
      L     #LOOP_COUNT
      LOOP  NX

      L     W#16#80C4
      SPA   ERRS

AOK:  SET   
      S     #DONE
      SAVE  
      L     0
      SPA   END










ERRS: SET   
      S     #ERROR
      CLR   
      SAVE  
      SPA   END








BUSY: SET   
      SAVE  
      L     W#16#8181






END:  T     #STATUS



      LAR1  #AR1_STORE
      LAR2  #AR2_STORE



      BEA

FC6

Code:
     TAR1  #AR1_STORE
      TAR2  #AR2_STORE







      L     0
      T     #STATUS
      T     #LEN
      T     #OFFSET
      SET   
      R     #ERROR
      R     #STATIC
      R     #NDR
      R     #OFFSETTING
      R     #LBUSY







      L     1
      L     #ID
      >I    
      SPB   NKO
      L     16
      <=I   
      SPB   NOK

NKO:  L     W#16#8186
      SPA   ERRS








NOK:  L     #LADDR
      SLD   3

      LAR1  
      L     PEW [AR1,P#4.0]
      SRW   7
      SPZ   STAA
      SRW   1
      SPZ   GEN1


STAA: SET   
      S     #STATIC
























      L     #ID
      DEC   1
      SRW   2
      SLW   1
      L     #LADDR
      +I    
      INC   8
      SLD   3
      LAR1  





      L     #ID
      DEC   1
      SRW   2
      L     PEW [AR1,P#0.0]
      SPZ   UG
      SPA   M5

UG:   SRW   8
M5:   L     #ID
      SRW   1
      SPP   UGR
      TAK   
      SRW   4
      SPA   GER
UGR:  TAK   

GER:  L     B#16#3
      UW    
      L     0
      ==I   
      SPB   CONT
      TAK   
      L     1
      ==I   
      SPB   BUSY
      TAK   
      L     2
      ==I   
      L     W#16#8184
      SPB   ERRS
      L     W#16#8183
      SPA   ERRS











GEN1: L     #ID
      DEC   1
      L     1
      SLW   
      L     PEW [AR1,P#14.0]
      UW    
      SPP   BUSY









CONT: L     #ID
      L     15
      +I    
      T     #DS_NR

















      L     P##RECV
      LAR2  
      L     B [AR2,P#1.0]
      L     2
      <>I   
      TAK   
      SPB   WRD
      L     W [AR2,P#2.0]
      SPA   BITE
WRD:  L     4
      <>I   
      TAK   
      SPB   DWRD
      L     W [AR2,P#2.0]
      SLW   1
      SPA   BITE
DWRD: L     6
      ==I   
      TAK   
      SPB   TYDW
      L     W#16#8184
      SPA   ERRS
TYDW: L     W [AR2,P#2.0]
      SLW   2
BITE: T     #FC_DATA_LEN





      U     #STATIC
      SPB   BBB

      L     0
      <I    
      TAK   
      L     W#16#8F23
      SPB   ERRS
      TAK   
      L     0
      ==I   
      L     W#16#8F7F
      SPB   ERRS










      L     #LADDR
      SLD   3
      LAR1  

      L     B#16#76
      L     #DS_NR
      SLW   8
      OW    
      SLD   16
      L     #FC_DATA_LEN
      OD    
      T     PAD [AR1,P#4.0]












      L     250
STRT: T     #LOOP_COUNT
      L     PED [AR1,P#4.0]
      T     #TEMP_DATA
      SRD   17
      SPZ   VAL



      SRW   3
      SPZ   JJJ
      SPA   WEIT
JJJ:  SRW   1
      SPZ   DDD
      SPA   WEIT
DDD:  SRW   3
      L     #DS_NR
      <>I   
      SPB   WEIT

      SPA   LGBY

WEIT: L     #LOOP_COUNT
      LOOP  STRT

      L     W#16#80C4
      T     #RET_WT_STORE
      SPA   ERRR

















LGBY: L     #TEMP_DATA
      SRD   19

      SPZ   NSQ

      SET   
      S     #OFFSETTING
      SPA   ERRR
NSQ:  L     #TEMP_DATA
      T     #RET_WT_STORE
      SPA   ERRR












VAL:  L     #TEMP_DATA



      SRD   20

      SPZ   OKK
      SPA   BUSY

OKK:  SRW   4
      L     #DS_NR
      <>I   
      SPB   BUSY








      L     PEW [AR1,P#8.0]
      T     #FC_DATA_LEN

      L     #TEMP_DATA
      T     #OFFSET
      -I    
      T     #DIFF


      L     240
      <=I   
      SPB   BBB

      T     #DIFF











BBB:  L     P##RECV
      LAR1  

      L     P##STORE
      LAR2  

      L     W [AR1,P#4.0]
      T     LW [AR2,P#4.0]

      U     #STATIC
      SPB   JJU


      L     W#16#1002
      T     LW [AR2,P#0.0]

      L     #DIFF
      T     LW [AR2,P#2.0]

      L     D [AR1,P#6.0]
      L     #OFFSET
      SLD   3
      +D    
      T     LD [AR2,P#6.0]

      L     #DIFF
      L     0
      ==I   
      SPB   ERRR

      SPA   JJR

JJU:  L     D [AR1,P#0.0]
      T     LD [AR2,P#0.0]

      L     D [AR1,P#6.0]
      T     LD [AR2,P#6.0]



JJR:  CALL  "RD_REC"
       REQ    :=TRUE
       IOID   :=B#16#54
       LADDR  :=#LADDR
       RECNUM :=#DS_NR
       RET_VAL:=#RET_WT_STORE
       BUSY   :=#LBUSY
       RECORD :=#STORE




      U     #LBUSY
      U     #STATIC
      SPB   BUSY

      L     #RET_WT_STORE
      L     W#16#F00
      UW    
      TAK   
      SPZ   EEA
      L     W#16#F00
      OW    
      T     #RET_WT_STORE
EEA:  U     #LBUSY
      =     #OFFSETTING

      L     #RET_WT_STORE
      L     0
      <>I   
      UN    #STATIC
      SPB   SFCE
      <>I   
      TAK   
      SPB   ERRS

      U     #STATIC
      SPB   REOK

      L     #OFFSET
      L     #DIFF
      +I    
      L     #FC_DATA_LEN

      >=I   

      TAK   
      T     #LEN

      SPB   LOK

      SPA   BUSY

SFCE: L     #LADDR
      SLD   3
      LAR1  
      L     PED [AR1,P#4.0]
      SRD   18
      L     #RET_WT_STORE
      SPZ   END

















ERRR: L     #FC_DATA_LEN
      L     #TEMP_DATA
      -I    
      T     #DIFF

      L     240
      <=I   
      SPB   KOSE
      T     #DIFF
KOSE: L     #DIFF
      L     0
      <>I   
      SPB   WEER
      S     #OFFSETTING
WEER: L     #LADDR
      SLD   3
      LAR1  

      UN    #OFFSETTING
      SPB   GGG
      L     B#16#74
      SPA   HHH
GGG:  L     B#16#70
HHH:  L     #DS_NR
      SLW   8
      OW    
      SLD   16
      L     #FC_DATA_LEN
      OD    
      T     PAD [AR1,P#4.0]









      L     250
STR2: T     #LOOP_COUNT
      L     PED [AR1,P#4.0]
      T     #TEMP_DATA
      SRD   17
      SPZ   STA

      SRW   4
      SPZ   STA

      SPA   BREK

STA:  L     #TEMP_DATA
      SRD   20
      SPZ   AAA
      SPA   BREK


AAA:  SRW   4
      L     #DS_NR
      <>I   
      SPB   BREK


      L     #LOOP_COUNT
      LOOP  STR2

      L     W#16#80C4
      SPA   ERRS

BREK: L     #DIFF
      L     0
      ==I   
      SPB   LOK

      U     #OFFSETTING
      SPB   BUSY

      L     W#16#8181
      L     #RET_WT_STORE
      <>I   
      SPB   ERRS
      TAK   
      SPA   END












REOK: L     #LADDR
      SLD   3
      LAR1  


      L     PEW [AR1,P#6.0]
      SRW   8
      T     #LEN
      L     #FC_DATA_LEN
      <=I   
      SPB   LOK




      L     W#16#8185
      SPA   ERRS









LOK:  SET   
      S     #NDR
      SAVE  
      L     0
      SPA   END











ERRS: SET   
      S     #ERROR
      CLR   
      SAVE  
      SPA   END







BUSY: SET   
      SAVE  
      L     W#16#8180





END:  T     #STATUS



      LAR1  #AR1_STORE
      LAR2  #AR2_STORE



      BEA

mfg babylon05
 
Nachdem Versuch dass die Werte zyklisch aktualisiert werden, gibt es wieder einen Versatz. Und es lässt sich nicht mehr reproduzieren, dass die Werte wieder "passig" im Empfangs DB landen :confused:

Update:
nach einem CPU Neustart stehen die Werte nun wieder passig im Empfangs DB
aber werden nach wie vor nicht aktualisiert :confused::confused::confused:

am zweiten AG_RECV wird der Status:

Error.JPG

ausgegeben.

Wie verriegele ich fie beiden AG_RECV Aufrufe am besten/einfachsten
das Bit ENO & NDR fällt dafür nun leider aus, da am ersten AG_RECV nach wie vor die 80B1 angezeigt wird, was anscheinend aber für das Empfangen egal ist - da die MW ja kommen

Der Rx Header Inhalt sieht jetzt auch anders aus...

Rx_nach Neustart.JPG


Gruß
Matze
 
Zuletzt bearbeitet:
Zur Sicherheit mal die Nachfrage, ob Deine Gerätschaften aktuell sind. Was benutzt Du?
- CPU 315: 6ES7315-.......... Firmware V.....
- CP343-1: 6GK7343-.......... Firmware V.....
- FC6 AG_RECV ist V4.7?
- FC5 AG_SEND ist V4.2?

Der Fehler 80B1 kommt imho von der SFC59 RD_REC und tritt da angeblich nur bei alten CP auf.
(Oder vielleicht auch bei Firmware-Problemen oder Inkompatibilitäten?)



Es ist bei CP343-1 definitiv möglich mit mehreren verschiedenen verriegelten AG_RECV-Aufrufen zu arbeiten (z.B. zur Erhöhung der Verständlichkeit des Programms), ich verstehe allerdings nicht, wieso Du da so große Probleme mit hast. Doch wenn Du das nicht in den Griff bekommst - die gute Nachricht: es geht auch mit nur 1 AG_RECV "für alles".

Eigentlich ist es gar nicht nötig, das Antwort-Telegramm vom PAC zu zerstückeln und abwechselnd über verschiedene AG_RECV-Aufrufe zu empfangen. Die Länge der PAC-Antwort ist nicht wirklich dynamisch variabel, sondern steuerbar/bekannt. Man muß nur geschickt dafür sorgen, daß alle 3 Antworten gleich lang sind und schon reicht 1 AG_RECV mit nur 1 konstantem RECV-Buffer-ANY für alles.
Bei solchen Kommunikations-Aufgaben nehme ich mir üblicherweise zuerst ein Blatt Papier und einen Stift und entwerfe die Lösung, statt per trial-and-error loszuprogrammieren. :cool:

Zuerst: Warum liest Du eigentlich die Register bis 302 vom PAC3200? Brauchst Du die wirklich? Was erwartest Du in den Registern 223 bis 302? Ist das irgendwo dokumentiert, ob und was da drin steht? Die fertigen Siemens-Bausteine lesen diese Register nicht.

Um das Ausleseprogramm zu vereinfachen und ohne Schrittkette auszukommen, würde ich wohl folgendermaßen vorgehen:
  • bei PAC3200 nur die Register 1 bis 222 lesen
  • bei PAC4200 zusätzlich die Register 223 bis 370 lesen (falls tatsächlich Bedarf)
Dies läßt sich in genau 3 bzw 5 Anforderungen von jeweils 74 Registern aufteilen, wodurch das RX-Telegramm vom PAC immer 9 + 148 = 157 Byte lang ist --> es kann für alle Anfragen mit nur 1 AG_RECV gearbeitet werden.

  • in die PAC-Abfragen einen Identifizerungs-Code im Header-Transaction-Identifier einbauen, den der PAC zurückgibt, dann kann man die AG_SEND und AG_RECV völlig unabhängig voneinander programmieren. Man kann alleine am TI im RX-Telegramm-Header erkennen was es enthält:
Code:
Transaction Identifier TI    Empfangsdaten Payload    --> speichern in DB83
----------------------------------------------------------------------------
1 = Register   1 -  74       RECV-Buffer Byte 9 .. 156    DBB0   - DBB147
2 = Register  75 - 148       RECV-Buffer Byte 9 .. 156    DBB148 - DBB295
3 = Register 149 - 222       RECV-Buffer Byte 9 .. 156    DBB296 - DBB443

4 = Register 223 - 296       RECV-Buffer Byte 9 .. 156    DBB444 - DBB591
5 = Register 297 - 370       RECV-Buffer Byte 9 .. 156    DBB592 - DBB739

Dies kann einfach in AWL mit direkter Angabe der absoluten Adressen runterprogrammiert werden (ähnlich dem Programm von kassla #24).
Wenn man will kann man es mit etwas mehr Aufwand auch symbolisch lösen, wobei da das größte Problem ist, daß in S7 Structs nicht auf ungeraden Adressen anfangen können. Ich würde da vermutlich mit ANY-Pointern arbeiten, welche ich zunächst symbolisch entgegennehmen würde und dann um 1 Byte kürzer (für AG_RECV) oder 1 Byte früher (für BLKMOV) manipuliert in ANY-Variablen speichern würde.

  • alle 9 Bytes im RX-Header auf Korrektheit prüfen, insbesondere die Längenangaben im Byte 5 und Byte 8
Wenn nicht korrekt, dann RX-Telegramm verwerfen, wenn mehrere aufeinanderfolgende RX-Telegramme Fehler haben (z.B. durch Verschiebungen im RECV-Buffer oder Fehlermeldung des PAC), dann mit FC10 AG_CNTRL CMD 2 CN_RESET die Verbindung beenden und neu aufbauen lassen.


Ich habe leider keine PAC zum testen zur Verfügung (wir benutzen Janitza UMG96RM), sonst hätte ich statt vieler Worte lieber das Programm zusammengetippt. Doch vielleicht finde ich noch Zeit dazu..

Harald
 
Zur Sicherheit mal die Nachfrage, ob Deine Gerätschaften aktuell sind. Was benutzt Du?
- CPU 315: 6ES7315-.......... Firmware V.....
- CP343-1: 6GK7343-.......... Firmware V.....
- FC6 AG_RECV ist V4.7?
- FC5 AG_SEND ist V4.2?

Das ist meinem (Test-)aufbau
CPU: 6ES7 315-2AF03-0AB0 Firmware 1.2.1 (alte Schreibtisch CPU:ROFLMAO:)
CP: 6GK7 343-1EX30-0XE0 Firmware 3.0

Die Bausteine
AG_SEND: Version 4.2
AG_RECV: Version 4.7

Es soll später mit einer 6ES7 315-2AG10-0AB0 Firmware:2.6 laufen, der CP ist der o.g.

Der Fehler 80B1 kommt imho von der SFC59 RD_REC und tritt da angeblich nur bei alten CP auf.
(Oder vielleicht auch bei Firmware-Problemen oder Inkompatibilitäten?)

"imho" = :confused:

Das trifft ja für den o.g. CP nicht zu?

Es ist bei CP343-1 definitiv möglich mit mehreren verschiedenen verriegelten AG_RECV-Aufrufen zu arbeiten (z.B. zur Erhöhung der Verständlichkeit des Programms), ich verstehe allerdings nicht, wieso Du da so große Probleme mit hast. Doch wenn Du das nicht in den Griff bekommst - die gute Nachricht: es geht auch mit nur 1 AG_RECV "für alles".

Der Übersicht wegen, möchte ich es aufteilen.
Wenn die Probleme nicht in den Griff zu bekommen sind, verfolge ich die Möglichkeit alles mit einem AG_RECV zu realisieren. Das liest sich aber recht kompliziert, da ich bislang mit AG_SEND/AG_RECV sowie ModbusTCP noch nichts zu tun hatte :-|


Warum liest Du eigentlich die Register bis 302 vom PAC3200? Brauchst Du die wirklich? Was erwartest Du in den Registern 223 bis 302? Ist das irgendwo dokumentiert, ob und was da drin steht?

Es soll erstmal alles gelesen werden was vom PAC verfügbar ist. Was letztendlich weiter ausgewertet oder benötigt wird ist in dem momentanen Statium noch nicht ersichtlich. Du weißt doch bestimmt auch wie das ist "...mach erstmal alles was geht..."

Aus dem Beispielprogramm von Lars ist ein DB mit den Empfangsregistern zum PAC3200 enthalten - an diesem Aufbau habe ich mich orientiert, darum diese Registeranzahl

Gruß
Matze
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Dermatze

Hier ist ein Beispiel Programm für Modus Client.
Ist nicht getestet für PAC aber du Sollt damit zumindest die Kommunikation zum PAC am Laufen kriegen.
Hab auch getestet mit alter Büro Hardware.

Server ist in Test eine CTI plc mit ECC Ethernet Module wo CTI data gemapped ist zum modbus Registers.
315 mit CP leset und schreibt data, CTI PLC mit ECC Module ist passive (modbus Server)

Für PAC sollt Dan nur Job 4 reichen modbus Funktion 3( read multiple holding registers).
OB1 =>FC99=>FB11,IDB71 Register DB = DB11.
In FB11 FC5 AG_SEND , FC6 AG_RECEIVE, SFC24 Test DB,SFC21 FILL.

Ist original eine sehr alte Siemens Modbus FB und hat dann nur Funktion 3 und 16.
Hab diese von jemand bekommen wobei know how protect entfernt war. Habe dann zum Übung diese erweitert für Modbus function 2 und 15 und mit eine registers DB nach beispiel von Lars Weiß seine Modbus TCP server baustein.

Siehe auch die Bilder das Kommunikation mit CTI plc damit lauft.

Entschuldigung fuhr meine nicht zu gute deutche Sprache

Gruß
Henny

status 1.jpgstatus 2.jpgAnhang anzeigen 32310status 4.jpgstatus5.jpg
 

Anhänge

  • Modbus_client_CP343_443.zip
    1,2 MB · Aufrufe: 32
... du Sollt damit zumindest die Kommunikation zum PAC am Laufen kriegen.
Die Kommunkiation steht ja, aber die zwei AG_RECV Aufrufe machen mir zuschaffen.

...nur Job 4 reichen modbus Funktion 3( read multiple holding registers).
OB1 =>FC99=>FB11,IDB71 Register DB = DB11.
In FB11 FC5 AG_SEND , FC6 AG_RECEIVE, SFC24 Test DB,SFC21 FILL.

Danke, ich werde mir das mal ansehen und testen.
 
Zurück
Oben