S5 115 - Profibus - S7 312

Zuviel Werbung?
-> Hier kostenlos registrieren
Der erste falsche Wert 33685509 (2020005 Hex), hat der in Hex zufällig Ähnlichkeit mit deinem Versuchswert 20200 dezimal? Könnte das irgendeine Fehlermeldung, ein Wertüberlauf oder Ähnliches sein, die nicht korrekt abgefangen wird?
 
20200 ist Zufall.

Leider nein. Dieser Wert ist zufällig so ähnlich.
Ich habe nin den FMS-Teil bearbeitet. DIeser schreibd ei Daten in ZwischenDBs. Nur wenn NDR ansteht werden die Daten mit BlockMove in die DBs kopiert aus denen die Leitstelle liest.
Somit habe ich den Siemens-Einwand entkräftet daß korrupte Daten während eines FMS-LeseZyklus von der Leitstelle über Passive Fetch gelesen werden.
Es kommen immernoch Glitches.
Hätte mich auch gewundert. Wenn ich dort Text-Dateien verschicken würde, dann würde das Argument ziehen. Aber diese Zählwerte ändern sich in 30 Sekunden um eine 1 nach oben. Selbst wenn der FMS gerade in den Baustein schreiben würde hätte ich keine derartige Korruption. Der maximal vorstellbare Fehler wäre daß der alte Wert wenige Milisekunden vor der Aktualisierung gelesen wird. Dann wäre er aber um 1 zu klein (was keine Rolle spielt) und nicht um 3 Mrd ( und ein paar Zequetschte) zu groß.
.....

Mist, ich habe gerade meine Merkebits kontrolliert, die mir Entartungen im DB zeigen sollen. Diesmal haben sie angesprochen. Die Werte sind also doch schon im DB defekt, also von der FMS-Seite fehlerhaft. Das hatte ich eigentlich schon ausgeschlossen..... ich glaub ich hab wieder zu lange auf die Zahlen von Step7 geschaut. Mache Schluss für heute.

Gruß,
Aksels
 
Zuviel Werbung?
-> Hier kostenlos registrieren
FMS-Seite.

Ich hab grad noch auf der FMS-Seite ein paar Dinge kontrolliert.
Dabei ist mir aufgefallen:

Die Daten werden doch mit Adressen wie <120> angefordert.
Die Rückmeldung beinhaltet doch bestimmt auch solche Zeichen, oder?
Habt Ihr Euch mal das kaputte mittlere Päckchen angeschaut?
da steht dort wo die Zählwerte sein sollen

<122>

Ulkig, was?

Wenn es nun doch auf dem FMS-Seite fehlerhaft ist (Mann, da muss ich beim Testen aber schon ganz schön überarbeitet gewesen sein)?


So sieht der Code aus:
OB1:
Code:
 CALL  "Read120"
      CALL  "Read121"
      CALL  "Read122"
      CALL  "Write123"
      CALL  "Write124"
      CALL  "Read130"
      CALL  "Read131"
      CALL  "Read132"
      CALL  "Write133"
      CALL  "Write134"

Beispielhaft Read 122:

Code:
//*
// Only execute job when no other job is active.
//*
      O     "Ix130".Read_REQ
      O     "Ix131".Read_REQ            //    REQ=1, READ is still active      SPB   ende
      O     "Ix132".Read_REQ
      O     "Ix133".Write_REQ
      O     "Ix134".Write_REQ
      O     "Ix120".Read_REQ            //    REQ=1, READ is still active      SPB   ende
      O     "Ix121".Read_REQ
      O     "Ix123".Write_REQ
      O     "Ix124".Write_REQ
      SPB   ende
 
//*
//Calling the READ job:                                       
//*
      CALL  "READ" , DB302
       REQ   :="Ix122".Read_REQ
       ID    :="Ix122".Read_ID
       VAR_1 :="Ix122".Read_VAR_Index
       RD_1  :="ZwspBaustein1".Data.Zae
       NDR   :="Ix122".Read_NDR
       ERROR :="Ix122".Read_Error
       STATUS:="Ix122".Read_Status
//*
//Query job status
//*
      U     "Ix122".Read_REQ            //   REQ=1 => Job active, query errors
      SPB   fehl
//*
      UN    "Ix122".Read_REQ            //   REQ=1 => Job completed
      S     "Ix122".Read_REQ            //   REQ neu setzten / Set REQ again
      SPA   ende
//*
//Error handling
//*
fehl: UN    "Ix122".Read_Error          // Error=0 => No error occurred
      SPB   ok
//*
      U     "Ix122".Read_Error          // Error=1 => Error occurred
      L     "Ix122".Read_Status         // load error status
      T     "Ix122".Read_Statusspeicher // Save in buffer
      R     "Ix122".Read_REQ            //   Reset REQ
      SPA   ende
//*
//Query job status
//*
ok:   UN    "Ix122".Read_NDR            //  Done=0 => Job still active
      SPB   ende
//*
      U     "Ix122".Read_NDR            //  Done=1 => Job complete without error
      R     "Ix122".Read_REQ            //  Reset REQ
//*
      CALL  "BLKMOV"
       SRCBLK :="ZwspBaustein1".Data.Zae
       RET_VAL:="mw100"
       DSTBLK :="S5KR2Rd".Data.Zae
      NOP   0
ende: BE


Beispiel Write123

Code:
//*
//Only execute job when no other job is active.
//*
      O     "Ix130".Read_REQ
      O     "Ix131".Read_REQ            //    REQ=1, READ is still active      SPB   ende
      O     "Ix132".Read_REQ
      O     "Ix133".Write_REQ
      O     "Ix134".Write_REQ
      O     "Ix120".Read_REQ            //    REQ=1, READ is still active      SPB   ende
      O     "Ix121".Read_REQ
      O     "Ix122".Read_REQ
      O     "Ix124".Write_REQ
      SPB   ende
//Calling the READ job:                                       
      CALL  "WRITE" , DB303
       REQ   :="Ix123".Write_REQ
       ID    :="Ix123".Write_ID
       VAR_1 :="Ix123".Write_VAR_Index
       SD_1  :="S5KR2Wr".Data.Bef
       DONE  :="Ix123".Write_NDR
       ERROR :="Ix123".Write_Error
       STATUS:="Ix123".Write_Status
 
 
//*
//Query job status
//*
      U     "Ix123".Write_REQ           //  REQ=1 => Job active, query errors 
      SPB   fehl
      UN    "Ix123".Write_REQ           //  REQ=1 => Job completed 
      S     "Ix123".Write_REQ           //  Set REQ again
      SPA   ende
//*
//Error handling
//*
fehl: UN    "Ix123".Write_Error         // Error=0 => No error occurred
      SPB   ok
//*
 
      U     "Ix123".Write_Error         // Error=1 => Error occurred 
      L     "Ix123".Write_Status        //Load error status
      T     "Ix123".Write_Statusspeicher    // Save in buffer
      R     "Ix123".Write_REQ           //   Reset REQ
      SPA   ende
//*
//Query job status
//*
ok:   UN    "Ix123".Write_NDR           //  Done=0 => Job still active
      SPB   ende
      U     "Ix123".Write_NDR           //  Done=1 => Job complete without error
      R     "Ix123".Write_REQ           //  Reset REQ
ende: BE


Vielleicht fällt jemandem noch etwas auf........



Gruß,
Aksels

P.S. Hat jemand noch nen Tip für meine einige Posts frühere Frage, wie ich das in einen universal FB bekomme?
 
Mir ist etwas aufgefallen ...

Hallo,

Aksels schrieb:
Vielleicht fällt jemandem noch etwas auf........

Du darfst die Aufrufe der "Call read, DB xxx" und "Call write, DB xxx " nicht überspringen. Es ist doch nicht gesagt, dass der Baustein mit dem Auftrag im nächsten Zyklus der CPU schon fertig ist. Dann kann es vorkommen, dass der Baustein nicht mehr bearbeitet wird und der Auftrag nicht abgeschlossen wird.
Bearbeite alle diese Aufrufe zyklisch. Dann stosse den ersten Request an. Wenn der mit Fehler oder Done beendet wird, den nächsten Request setzen, u.s.w.

Gruß

Question_mark

Nachtrag : Der Status von "REQ" hat für Dich zu keinem Zeitpunkt irgendeinen Aussagewert über den Status des Lese/Schreibauftrags !!!
Dafür sind andere Parameter beim Bausteinaufruf zuständig.
 
Zuletzt bearbeitet:
Nochwas aufgefallen

Hallo,

Code:
ok:   UN    "Ix123".Write_NDR           //  Done=0 => Job still active
      SPB   ende
      U     "Ix123".Write_NDR           //  Done=1 => Job complete without error
      R     "Ix123".Write_REQ           //  Reset REQ

Und das ist eigentlich überflüssig, der "REQ" wird vom Baustein selbst zurückgesetzt, nach meiner Erinnerung auch dann, wenn der Auftrag noch nicht beendet ist, also nach dem ersten Durchlauf mit der erkannten positiven Flanke von "REQ".

Gruß

Question_mark
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Noch einen ???

Hallo,

Code:
      U     "Ix122".Read_REQ            //   REQ=1 => Job active, query errors
      SPB   fehl
//*
      UN    "Ix122".Read_REQ            //   REQ=1 => Job completed  [B]<--- Überflüssig[/B]
      S     "Ix122".Read_REQ            //   REQ neu setzten / Set REQ again
      SPA   ende

Die Anweisung UN Ix122.Read_Req ist hier völlig überflüssig, da nach dem SPB an dieser Stelle das VKE sowieso auf "1" gesetzt ist.:rolleyes:

Gruß

Question_mark
 
Nach Kritik mal was konstruktives

Hallo,

mein Vorschlag zur Lösung Deines Problems (jedenfalls so, wie ich es von Anfang an programmiert hätte) :

Rufe alle Read/Write Aufträge zyklisch auf. Lege ein Merkerwort für alle "REQ" fest., z.B. MW 100 und ordne die Bits wie folgt zu :
Bit 0 = REQ für Ix122.Read_Req
Bit 1 = REQ für Ix123.Read_Req
Bit 2 = Req für Ix133.Write_Req und so weiter ....
Lege ein zweites MW für einen Schiebtakt fest, z.B. MW 102
Setze dieses Merkerwort 102 bei Neustart der CPU auf $0001 (hex)
Wenn M102.0 = "1" dann setze M 100.0 --> "1"
Dadurch wird Auftrag Ix122 bearbeitet.
Wenn Ix122 Done oder Error, schiebe das Merkerwort 102 mit SLW 1 nach links.
Wenn M102.1 = "1" dann setze M 100.1 --> "1"
Dadurch wird Auftrag Ix123 bearbeitet.
Wenn Ix123 Done oder Error, schiebe das Merkerwort 102 mit SLW 1 nach links.

und so weiter ....
Die Bits im MW 100 werden von den "Read" und "Write" Bausteinen sowieso gelöscht, darum brauchst Du dich nicht zu kümmern.
Sagen wir mal, du hast 10 Aufträge (bin zu faul um nachzuzählen :ROFLMAO: ). Dann vergleichst Du Dein Merkerwort nach dem letzten Auftrag (Ix12x) mit der Maske $0200 (hex) und setzt das MW 102 wieder auf $0001 (hex) und das ganze geht wieder von vorne los.
Dadurch ist gewährleistet, dass immer nur ein Auftrag gleichzeitig bearbeitet wird und auch abgeschlossen ist, bevor der nächste angestossen wird.
Mach das so und es wird funktionieren, aber programmieren darfst Du das selber :ROFLMAO: :ROFLMAO:
Der Vorteil ist dabei, egal was passiert mit den Read/Write Aufträgen, diese Abfolge kriegst Du nicht aus dem Tritt, kann sich nicht aufhängen und läuft sicher durch solange die CPU im RUN-Modus ist.

Gruß

Question_mark
 
Zuletzt bearbeitet:
Ncm com 5431

Hallo Männers,

habe ein Problem benötige um eine CP zu programmieren und somit die von dort aus weiterführende Peripherie abzuschalten die oben genannte Software genau ein Mal.Kann mir da jemand weiterhelfen? PS:
Denke mal wenn du jetzt so mit deiner S7 Anschaltung probiert hast wirst du diese Software besitzen?
Im Voraus danke für die Antworten
 
Zurück
Oben