Step 7 Ungewollte Beschreibung von Datenpunkten

WinniePooh

Level-1
Beiträge
102
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Kollegen,

folgende Sache die mir ein bißchen Mysteriös ist. Ich programmiere mit der STEP 7 5.5, S7-315 2PN/DP.
Ich habe eine Programm geschrieben indem ich mit großen Datenbereichen hantiere.
Die Datenbereiche übergebe ich als Pointer von FB zu FB usw. Schachtelungstiefe wird für die SPS nicht überschritten.
Programmiert wird komplett symbolisch.

Erst kommt der Auto Betrieb und dann steuert es die Aktoren.
Die Aktoren werden in SCL in Schleifen aufgerufen, Auto Programm in AWL.

Problem:
Wenn ich aus dem Auto einen Aktor ansteuer, kann sein, dass es manchmal alle Aktoren kurzzeitig angesteuert werden. (Status aller Aktoren ändert sich in der komplette For-Schleife, anstatt nur in einem Aktor).

An was könnte es liegen, dass mir das Programm über die Variablen werte verändert. Kann ich mir nicht erklären.

Für eure Hilfe wäre ich sehr dankbar, ich werde weitersuchen.

Gruß
Winnie
 
An was könnte es liegen, dass mir das Programm über die Variablen werte verändert. Kann ich mir nicht erklären.

Hallo,
ich vermute mal, dass es an deinem Script bzw. der Ausführung davon, liegt.
Pauschal lässt sich dazu nichts sagen - vielleicht stellst du das Script hier mal ein ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wer kommt nur immer auf sowas, mir fehlt gerade das Kopfschütteln-Smiley. :???:
Ist das eine Übung oder soll das in eine produktive Maschine?
SPS-Programme sollten klare Strukturen haben und es sollte möglichst immer (auch online!!!) nachzuvollziehen sein, warum was wann schaltet.
Mit deinen Schleifen bist du schon jetzt auf die Nase gefallen, glaub mir, das wird nach einem oder 2 Jahren eher Schlimmer als Besser. Und gerade Schleifen sind in SCL nicht zu beobachten, ohne die SPS in Stop zu schalten, sowas ist unwartbar, also bitte genau überlegen ob das nötig ist.
Ansonsten kann man kaum etwas sagen, ohne Code zu Gesicht zu bekommen...
 
@Ralle:
Nun mach mal halblang ... so schlimm ist dieses Vorhaben auch nicht. Aber du hast schon Recht wenn du sagst, dass man wissen muss was man tut und wie man es tun muss ...
Deshalb : Her mit dem Script !!!

Gruß
Larry
 
@Larry

Da hast du vielleicht Recht, aber ich hab halt viel Phantasie :) . Ich seh es schon vor mit, 150 Aktoren, die über eine Schleife inkl. Lauffzeitüberwachung etc. angesteuert werden.
Da hast du dann einen FB, einen FC, 2-200 DB, eine Schleife. Das kann man machen und es vereinfacht sicher das Programm, aber man sieht nicht mehr was wirklich passiert.
Wer das programmiert muß das schon akurat machen und die "nachfolgenden" Kollegen haben damit ganz sicher irgendwann ein Problem.
Außerdem sind solche Schleifen nicht wirklich das, was eine SPS mag.
Immerhin ist das i.d.R. ja nicht einfach nur ein Programm, man bewegt damit Maschinen, kann diese auch mal eben zerstören usw.
Deshalb bin ich da extrem konservativ und versuche die Programme nicht zu stark zusammenzufalten, sondern schreibe für 20 Autoren lieber 20 FC-Aufrufe mit allen Parametern daran.
Dann erkennt jeder, was da läuft, bzw. laufen soll.
Aber wenn man natürlich (wie in der Haustechnik) 250 Lampen hat, kann man schon mal über so eine Schleife nachdenken.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Ralle: Je es sind viele Aktoren die über die Schleifen aufgerufen werden. Getestet wird das System dauerhaft, wie auch jetzt und nun habe ich ein Problem gefunden welches mir aber unbekannt ist.
Eine Zykluszeit habe ich auch von ungefähr 60 MS, was meiner Meinung nicht übertrieben hoch ist.

Folgender Codeschnipselt vereinfacht:
OB 1
Code:
CALL AUTOMATIK PROGRAMM
 INOUT: AKTOREN // INOUT als ANY deklariert

CALL AKTOR_FB
....

AKTOR_FB: in AWL
Code:
INOUT: INOUT_MASCHINEACTUATOR :ANY

STAT: MASCHINE : UDT_MASCHINE
          FB_MASCHINE_01 : FB60
          FB_MASCHINE_02 : FB60

 
  L     P##INOUT_MASCHINEACTUATOR
      LAR1  
      L     B [AR1,P#0.0]               // Syntax-ID aus dem Any-Pointer auslesen
      T     #TEMPPOINTER.POINT_02.SyntaxID
      L     B [AR1,P#1.0]               // Bereichstyp auslesen (B#16#2 = Byte;  B#16#3 = Int; B#16#4 = Word;  B#16#7 = DInt; B#16#8 = DWord)
      T     #TEMPPOINTER.POINT_02.Bereichstyp
      L     W [AR1,P#2.0]               // Anzahl der zu übertragenden Werte (Byte/Word)
      T     #TEMPPOINTER.POINT_02.AnzahlWerte
      L     W [AR1,P#4.0]               // DB-Nummer auslesen
      T     #TEMPPOINTER.POINT_02.DBNR
      L     D [AR1,P#6.0]               // Pointer Startadresse auslesen
      T     #TEMPPOINTER.POINT_02.STARTADRESSE
      L     P##ANY_02
      LAR1  
      L     #TEMPPOINTER.POINT_02.SyntaxID
      T     B [AR1,P#0.0]               // Syntax-ID in den Any-Pointer schreiben
      L     #TEMPPOINTER.POINT_02.Bereichstyp
      T     B [AR1,P#1.0]               // Bereichstyp schreiben (B#16#2 = Byte; B#16#4 = Word)
      L     #TEMPPOINTER.POINT_02.AnzahlWerte
      T     W [AR1,P#2.0]               // Anzahl der zu übertragenden Werte (Byte/Word)
      L     #TEMPPOINTER.POINT_02.DBNR
      T     W [AR1,P#4.0]               // DB-Nummer schreiben
      L     #TEMPPOINTER.POINT_02.STARTADRESSE
      T     D [AR1,P#6.0]               // Pointer Startadresse schreiben
      CALL  "BLKMOV"
       SRCBLK :=#ANY_02
       RET_VAL:=#HF.iRETVALSFC20_03
       DSTBLK :=#MASCHINE

L PAR_MASCHIN
L 1
<I
SPB NO01
CALL FB_MASCHINE_01
INOUT_ACT_01: MASCHINE[1].ACT01  // die INOUT variable als ARRAY von dem AktorXX_UDT
INOUT_ACT_02: MASCHINE[1].ACT02 // die INOUT variable als ARRAY von dem AktorXX_UDT
INOUT_ACT_03: MASCHINE[1].ACT03 // die INOUT variable als ARRAY von dem AktorXX_UDT
NOP 0

NO01: L PAR_MASCHIN
  L 2
  <I 
  SPB NO02

CALL FB_MASCHINE_02
INOUT_ACT_01: MASCHINE[2].ACT01  // die INOUT variable als ARRAY von dem AktorXX_UDT
INOUT_ACT_02: MASCHINE[2].ACT02 // die INOUT variable als ARRAY von dem AktorXX_UDT
INOUT_ACT_03: MASCHINE[2].ACT03 // die INOUT variable als ARRAY von dem AktorXX_UDT
NOP 0

NO02: .....

      CALL  "BLKMOV"
       SRCBLK :=#MASCHINE
       RET_VAL:=#HF.iRETVALSFC20_04
       DSTBLK :=#ANY_02

FB_MASCHINE wird als Multiinstanz in dem FB aufgerufen:

Code:
CONST: MAX := 3; // JEDER ACTOR HAT SEINE KONSTANTE IST NUR VEREINFACHT FÜR DIE DARSTELLUNG
INOUT: INOUT_ACT_01 : ARRAY[1..MAX] OF UDT_AKTOR;
           INOUT_ACT_02 : ARRAY[1..MAX] OF UDT_AKTOR;

STAT: STAT_ACT: UDT_AKTOR;
FOR i:= 1 TO MAX BY 1 DO
STAT_ACT := INOUT_ACT_01[i]; // hier muss ich auf eine Statische variable springen, als tempspeicher da mir Siemens wegen der Übernahme mekert.
  CALL FC_ACT_01
  INOUT: STAT_ACT
INOUT_ACT_01[i] := STAT_ACT;
END_FOR;

FOR i:= 1 TO MAX BY 1 DO
STAT_ACT := INOUT_ACT_02[i]; // hier muss ich auf eine Statische variable springen, als tempspeicher da mir Siemens wegen der Übernahme mekert.
  CALL FC_ACT_02
  INOUT: STAT_ACT
 INOUT_ACT_02[i] := STAT_ACT;
END_FOR;

So sieht es aus von dem Ablauf...
 
P.S. Die Aktoren werden Richtig aufgerufen und der Ablauf funktioniert auch, wird alles in einer Simulation getestet mit einer richtigen SPS.
Als Simulation meine ich, dass Analoge und Rückmeldungen in einem Baustein direkt vorgegaukelt werden.
Es ist, wie von Geisterhand, das es Beschrieben wird oder der Status sich ändert aber angesteuert wird von allen aktoren in einer Schleife, aber halt durch die Ansteuerung eines bestimmten Aktors bleibt halt dieser in der Position und die anderen gehen auf die Ruheposition wieder.

Nun habe ich mal testweise mit einem Dummy Baustein, die STAT Variable nochmals genullt und es ist was besser geworden.
Aber warum benötige ich es, wenn es ehe vor dem FC Baustein mit komplett neuen Werten beschrieben wird?

Einen OB35 habe ich auch geladen, welcher alle 10 MS aufgerufen wird.
Könnnte da das Problem liegen, dass wenn dieser aufgerufen wird die Daten Übertragung von der Array Var zur STAT Var und umgekehrt Probleme entstehen.
 
@Winnie:
Bahnhof - Umsteigen - Kofferpacken ...?
Soll heissen : mir erschliesst sich der Sinn der Maßnahme komplett nicht - irgendwie fehlt mir da auch noch etwas. Vielleicht schreibst du mal etwas mehr dazu.
Bis wohin hast du denn noch dass, was du eigentlich haben willst ?

@Ralle:
Ich habe hier etwas komplett Anderes erwartet - vielleicht hast du mit deiner Eingangs-Bemerkung doch Recht. Ich hatte da jetzt an meinen eigenen Kram gedacht, wo ich auch eine Schleifen-Sammel-Auswertung mache.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Einen OB35 habe ich auch geladen, welcher alle 10 MS aufgerufen wird.
Könnnte da das Problem liegen, dass wenn dieser aufgerufen wird die Daten Übertragung von der Array Var zur STAT Var und umgekehrt Probleme entstehen.
Davon (und der Umsetzung) sehe ich in deinem Code nichts.
Aber 10ms OB35 und 60ms OB1 beisst sich natürlich eventuell "ein bißchen" wenn beide mit der gleichen Datenbasis arbeiten ...

Gruß
Larry
 
Tut mit Leid WinnPooh, ich bin raus. Das ist genau das, wo ich meine Zeit für vergeudet halte, in kryptischen Codeschnipseln ohne vernünftige Kommentierung rumsuchen, UDT hinundhergeschaufel, niemand kann sagen wo die Daten gerade wirklich sind und ob dein OB35 da nicht auch noch drinrumpokt. Ich würde mir diesen Ansatz wirklich nochmal genau überlegen! Ihr sucht euch in 5 Jahren einen Wolf, garantiert. Jede kleinste Codeänderung wird zum Mega-Even mit hohem Risiko, das nichts mehr geht, ganz zu schweigen von Siemens und seinem TIA-Portal.
 
also ich habe es gefunden.
es wird ein Befehl vom Automatikprogramm geschickt, wusste ich nicht, deswegen habe ich gar nicht im autoprogramm gesucht... soll wohl so sein, muss ich mit dem kollegen sprechen, welcher den autobereich geschrieben hat.
Ich weiß nicht was Ihr gegen diese Struktur habt,
Die Daten werden nur über die Parameter zueinander geschickt, die Maschine ist in Ihre Einzelteile einsehbar. Von außen - nach innen.
Und entweder wird die von außen mit dem Autoprogramm angesteuert oder von der Visu. Die greifen auf die Startbits.
In dem Baustein wo die Aktoren aufgerufen, können dann später komplett parametrierbar sein.
Wieviele Aktoren in den Maschinenteilen vorhanden sind und wieviel Maschinenteile in der kompletten Anlage vorhanden sind.
Die Aktortypen werden Sich nie ändern und wenn doch testet man im Büro mit die neue Ansteuerung bis es 100 pro klappt in jedem Zustand.
Und sie wird freigegeben und kann in die Anlage inbetriebgenommen werden.

Klar gibt es hier auch Nachteile, aber irgendwo muss man immer einen Tod sterben.
Mit der größe der neuen CPUs kann man die Anlage so ausbauen, dass diese auf Maximum programmiert ist (Array Endzähler höher setzen) und somit kann ich dann auch die komplette Anlage parametrieren.
Die Aktorprogrammierung entfällt dann komplett.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was man dagegen hat, hast du ohne es zu wollen selbst beantwortet ...

Selbst du als einer, der das Programm gut zu kennen scheint,
hat mehr oder minder null Ahnung warum bzw. woher in jenem Moment gerade was angesteuert wird oder nicht.
Von Fremden Leuten brauchen wir dann gar nicht erst anzufangen ... Instandhalter o.ä.
Eigentlich wird meistens die Devise hochgehalten, alles was zischt und klappert, sollte in Grundzügen auch noch jemand mit 3 Promille nachvollziehen können.

Mfg
Manuel
 
@Winnie:
Mein Problem dabei ist, dass ich mit dem, was du da geliefert hast, keinen sinnvollen Bezug zu irgendetwas mir Bekanntem herstellen kann.
Ich kann also auch nicht die Sinnhaftigkeit deines Tuns beurteilen - allerdings bin ich vermessen genug, behaupten zu wollen, dass die sich mir eigentlich hätte erschliessen sollen.
Vielleicht überdenkst du es also noch einmal - es ist nicht unbedingt immer sinnvoll, alles zu machen, was man machen könnte ...

Gruß
Larry
 
Es ist auch immer schwierig, keine halbwegs nachvollziehbaren Symbole zu haben. Wenn ein Aktuator (Greifer) nicht will, dann verfolgst du in deinem Programm einen "Geist" der heißt mal Aktuator_2, denn wieder Maschine[3].Aktuator_17 oder er wird gleich über einen Pointer versorgt. Das wird richtig fies im Fehlerfall.

PS. Jeder findet das immer besonders toll, was er selbst erfunden hat. Das geht mir auch so. Erst wenn andere es auch für gut befinden, hat es wirklich was. Aber das können wir mit dem wenigen Code nicht wirklich beurteilen, vielleicht läßt du mal jemand anderes (am besten auch nicht aus deiner Firma) seine Meinung zum Gesamtkunstwerk :) kundtun, das wird euch ganz sicher helfen. Ich wollte dich nicht runtermachen, nur zur Vorsicht "ermahnen". ;-)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ja danke für eure Kritik. Ich verstehe auch, dass der Code im Betrieb schwer nachzuverfolgen ist.
Man kann aber bei der IBN, besser im Büro den Code testen und für funktionell einstufen.
Und es später für die Inbetriebnehmer (auch mich ) :) freigeben.

Den Aufrufcharakter habe ich von einem Kollegen, welcher mit Codesys andere Anlagen programmiert.
Dieser hat einen ungefähr gleichen Ablauf (exakt geht leider nicht).
Ich versuche es so zu programmieren, dass auch er sich im Programm zurechtfindet, da er und ich alleine sind.
Bin ich weg, muss er es machen. Ist er weg muss ich seins machen.

Ich mache mir gerade paar Überlegungen, wie ich den Code in meiner Struktur öffnen kann um die Status nachzuverfolgen und in dem Ablauf zu bleiben.

@Ralle: Die Aktoren habe ich nur hier im Forum so genannt, damit man nicht durcheinander kommt. Es soll nur die Aufrufstruktur darstellen.
@Larry: Der Sinn der Sache, ich kann die Anlage parameterieren, somit dass nur ein Elektriker rausfährt die Parameter einstellt um was es sich handelt.
den Programmablauf A, B, C oder D freigibt und somit die komplette Anlage selber in Betrieb nimmt.
Der Programmierer fährt nur raus, wenn es was besonderes gibt, was man "nicht im Büro" testen kann.
 
Zurück
Oben