In TIA Bausteinausgänge über Index ansprechen

sunny22

Level-2
Beiträge
259
Reaktionspunkte
52
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen Zusammen,

ich habe gerade ein Problem für das ich keine schöne Lösung finde.
Ein Funktionsbaustein hat 10 Bool Ausgänge. Im Programm sollen die über einen Index mit Werten versorgt werden. Früher hätte ich das einfach mit einem Pointer im Instanz DB gemacht. Aber sowas gehört sich ja heute nicht mehr. Ich habe es mit der AT-Sicht mit einem ARRAY auf den ersten Ausgang versucht, das geht aber nicht.
Wie macht man das am besten?

Grüße Oliver
 
Entweder bereits die Ausgänge als Array anlegen, oder intern mit einem Array arbeiten und dann den Ausgängen zuweisen, 10 Zeilen sind ja echt überschaubar.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Array am Ausgang geht nicht weil der Baustein in FUP beschaltet werden soll. Das andere ist ne Krücke. Sowas in der Art mach ich wenn's keine bessere Lösung gibt. Vielleicht gibt es ja noch andere Ideen.
 
Vorneweg:
Der Beitrag ist nicht persönlich gemeint!

So manchesmal frage ich mich, wer dann solche Programme nachvollziehen oder verstehen soll.
Ein Instandhalter mit normalen SPS-Kenntnissen kann dann daran verzweifeln.
Und das letztlich wegen 10 Zeilen mehr Aufwand.
Liebe Kollegen wir schreiben Software nicht für uns, sondern für die Mitarbeiter beim Kunden!
 
Liebe Kollegen wir schreiben Software nicht für uns, sondern für die Mitarbeiter beim Kunden!
Also das kann ich so nicht bestätigen:
1. Ich schreibe Software um meine Familie zu ernären, also schon für mich (irgendwie).
2. Ich schreibe Software damit der Kunde eine Anlage betreiben kann und das möglichst effizient und mit hoher Verfügbarkeit.
3. Ich schreibe keine Software für Instandhalter, das macht einfach keinen Sinn. Die Anlagen werden immer komplizierter und umfangreicher die Anforderungen immer höher, die Instandhaltungen werden immer unquallifizierter, einfacher gestrickt.

Weder die Ausbildung noch Weiterbildung kommt da auch nur annähernd mit.
Der Schwachsinn nur FUP/KOP zu lehren macht's nur noch schlimmer
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich war 10 Jahre in der Instandhaltung und nun in der Planung. Ich würde keine Anlage abnehmen in der das Programm keiner lesen kann außer der Lieferant. In Projekten von Kollegen weiß ich, dass in der zugehörigen Schulung eine Einweisung in die Software verlangt wurde
 
1. ...
2. ...
3. ...
Und 4. für die InbetriebNehmer, die chronisch die Software bis zur Unkenntlichkeit "optimieren".
Ich habe mal auf Kundenwunsch für einen "manuellen" FräskopfWechsel einen Zyklus (G-Code) geschrieben, mit dem man eine Schrittkette vor- und rückwärts durchtackern konnte, inkl. dem Positionieren der Achsen und der SpindelIndexierung und ggfs GetriebeStufenWechsel.
Das war dem InbetriebNehmer zu kompliziert und er hat alles "Überflüssige" herausgestrichen ... und der Kunde war sauer, dass wir nicht das Versprochene geliefert hatten.
 
Und 4. für die InbetriebNehmer, die chronisch die Software bis zur Unkenntlichkeit "optimieren".
Ich habe mal auf Kundenwunsch für einen "manuellen" FräskopfWechsel einen Zyklus (G-Code) geschrieben, mit dem man eine Schrittkette vor- und rückwärts durchtackern konnte, inkl. dem Positionieren der Achsen und der SpindelIndexierung und ggfs GetriebeStufenWechsel.
Das war dem InbetriebNehmer zu kompliziert und er hat alles "Überflüssige" herausgestrichen ... und der Kunde war sauer, dass wir nicht das Versprochene geliefert hatten.
ja, wärst Du mal lieber selber zur Inbetriebnahme gefahren ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
3. Ich schreibe keine Software für Instandhalter, das macht einfach keinen Sinn. Die Anlagen werden immer komplizierter und umfangreicher die Anforderungen immer höher, die Instandhaltungen werden immer unquallifizierter, einfacher gestrickt.

Tja, das wird vielleicht zum Wettbewerbsnachteil :)
Schönes Beispiel aus den letzten Wochen:
  • Sicherheitskreis an einer Fördertechnik lässt sich nicht quittieren.
  • Fehler FDBACK-Baustein im F-Programm. Rückführung fehlt.
  • Rückführung ist ein Bit aus einem Instanz-DB.
  • Im entsprechenden FB sind zig weitere Datenbits per Slice.Zugriff verknüpft
  • Bis hierhin kam die Instandhaltung, dann musste ich mit ins Boot.
  • Der entsprechende Datenbereich kommt per DPRD_DAT (SFC14)
  • In der Hardwarekonfig einen G120 gefunden. Datenaustausch per anwenderdefinierten Telegramm
  • Startdrive geöffnet und die Bico-Beschaltung für das Bit im Telegramm gesucht.
  • Digital-Eingang des G120 ist darauf verschalten.
  • Nichts im Schaltplan verzeichnet :-( Also Verdrahtung kontrollieren.
  • Motorschutzschalter Meldekontakt hängt dran.
  • Fehler Digital-Eingang des G120 ist defekt
  • Umrichter getauscht und Startdrive-Paametrierung eingespielt.
  • Anlage lässt sich einschalten ... FU geht bei Start sofort auf Störung.
  • Motorparameter kontrolliert. Die ergeben eigentlich keinen Sinn.
  • Also Motorinbetriebnahme und alles eingestellt.
  • Anlage läuft und endlich ist auch der Hersteller erreichbar :)
  • In der Störmeldung für den Motorschutzschalter war noch ein Tippfehler darum keine Anzeige der ursächlichen Störung.
  • Für die Einstellung der Motorparameter hat der Hersteller ein passwortgeschütztes Servicemenü auf dem Panel. Parameter liegen im DB und müssen übertragen werden. Daher keine Sicherung im TIA-Projekt.

Ich bilde mir ein, dass ich über deutlich mehr TIA-Wissen als ein normaler Instandhalter verfüge. Bis die Anlage wieder lief habe auch ich 4 Stunden gebraucht.
 
Sehr einfach.
Wenn du die Ausgänge nicht als ein Array Deklarieren willst, dann deklariere ein statischen 'Schmier-Array' und arbeite damit.
Am ende von die Baustein aktualisierst du die Ausgänge:
#Ausgang_1 := #Ausgang_array ;
#Ausgang_2 := #Ausgang_array[i+1] ;
#Ausgang_3 := #Ausgang_array[i+2] ;
Kannst ud machen in KOP, FUP oder SCL wie du willst.

Zum Thema Auslieferung von die Software an die Endkunde.
Wir geben unsere Programme für Standardmaschinen nicht aus.
Sonderanlagen die für eine Kunde erstellt sind gebe wir die Programme aus, inkl. Einweisung in wie das Programm strukturiert ist.
 
2. Ich schreibe Software damit der Kunde eine Anlage betreiben kann und das möglichst effizient und mit hoher Verfügbarkeit.
3. Ich schreibe keine Software für Instandhalter, das macht einfach keinen Sinn.
Hohe Verfügbarkeit erfordert aber leicht nachvollziehbaren Code für schnelle Ursachensuche im Problemfall. (Oder perfekte Software, wo es nie unerklärliche Probleme gibt ;) ) Dann schreibe eben Deine Software verständlich für Deine Kollegen, damit deren Support nicht durch unnötig unverständliche Software erschwert wird.

Oder sind die von Dir programmierten Anlagen eher nicht so wichtig, daß der Kunde sich drauf einlassen kann, daß im Fall eines unerklärlichen Anlagenstillstands deutschlandweit nur ein einziger Programmierer in dem Programm durchsieht und die Problemursache in einer Stunde finden kann, falls der denn 24/7 geschwind ans Telefon geht und nicht gerade schläft oder gar Urlaub hat ... ?

Harald
 
Ich kann zwar gerade nicht nachvollziehen wieso meine Frage so eine OT-Welle auslöst. Zumal die Diskusion wie "richtig" programmiert wird so überflüssig ist wie ein Kropf. Frag 10 Programmierer und du bekommst 10 Meinungen wie's richtig gemacht wird und wieso das was der andere programmiert hat total doof ist. Aber egal...
Zusammenfassend bleibt also festzuhalten dass es offenbar keine Möglichkeit gibt die Bausteinausgänge direkt über einen Index zu adressieren sondern dass man irgendwie einen Workaround basteln muss.
 
Zusammenfassend bleibt also festzuhalten dass es offenbar keine Möglichkeit gibt die Bausteinausgänge direkt über einen Index zu adressieren sondern dass man irgendwie einen Workaround basteln muss.
Wenn du die Ausgänge nicht als ein Array Deklarieren willst, dann deklariere ein statischen 'Schmier-Array' und arbeite damit.
Am ende von die Baustein aktualisierst du die Ausgänge:
#Ausgang_1 := #Ausgang_array ;
#Ausgang_2 := #Ausgang_array[i+1] ;
#Ausgang_3 := #Ausgang_array[i+2] ;
Kannst ud machen in KOP, FUP oder SCL wie du willst.
Es gibt nur einen Umweg, den hat Jesper Dir genannt.
Oder man nutzt die Ausgänge aus dem IDB direkt zur Verschaltung. Dann ohne Umweg aber nicht innerhalb FUP verschaltet.
 
Also ich mache das öfters wie von Jesper auch beschrieben, dass ich die Eingänge in ein temp-Array kopiere, verarbeite. und dann die Daten dort wieder heraushole. Vor allem wenn ich mehrere Eingänge identisch verarbeite und dann in einer For-Schleife verarbeite.

Ich wüsste auch keinen Grund warum der Code dann schwieriger zu Verstehen sein soll, im Gegenteil sogar. Denn ich habe doch den gleichen Code eben nur einmal mit Array-Index und nicht z.B. 10 mal. Wenn ohne Array müsste ich zudem prüfen, ob sich nicht bei der Kopiererei vielleicht jemand mal vertippt hat und bei der Verarbeitung von 7 doch eine 1 stehen hat.

Bei einer For-Schleife hat man aber den Nachteil, dass sich das Online nur schlecht beobachten lässt. Davon hat der TO aber nichts geschrieben.
 
Lesen kann es doch jeder, verstehen ist aber noch einmal etwas anderes.
Das Problem ist doch eigentlich:
Eine Firma:
Instandhalter A - kann nur KOP
Instandhalter B - kann nur AWL und FUP
Instandhalter C - kann nur FUP, dreht bei KOP durch
Instandhalter D - kann alles ausser SCL
Instandhalter E - kann nur SCL und FUP
Chef vons Ganze: Schreibt ein Programm das übersichtlich geschrieben ist und von unserem Personal auch nutzbar ist.
Einkäufer: Wo sind die %%?
Ich: ???

Also, für wen programmiert man nun?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
dass ich die Eingänge in ein temp-Array kopiere, verarbeite. und dann die Daten dort wieder heraushole. Vor allem wenn ich mehrere Eingänge identisch verarbeite und dann in einer For-Schleife verarbeite.

Ich wüsste auch keinen Grund warum der Code dann schwieriger zu Verstehen sein soll
Ich denke, es geht eher um das Rumgepointere im IDB... da findest dann rückwärts über Querverweise garnix... Und falls jemand mal den IDB erweitert... oje...🙈

Mein Ansatz ist seit Langem "Einheitlichkeit geht vor Schönheit" also möglichst lange und in möglichst vielen Anlagen den identischen Programmierstil verwenden. Man könnte auch Standardisierung dazu sagen, dann kommen auch die Leute damit klar.
Nichts ist schlimmer als an jeder Anlage die Welt neu zu erfinden und Jugend forscht zu betreiben, nur weil man sich selbst verwirklichen will und alles noch optimaler besser schöner anders... zu machen...

Wenn in nem Werk bei 500 SPSn das Bitmeldeverfahren benutzt wird, dann fang ich jetzt nicht mit Programmalarm an, nur weils grad cool ist. Nur um mal ein Beispiel zu nennen...

Und wenns in dem ganzen Werk nur Spaghetticode gibt, dann krigt die nächste neue Anlage eben auch Spaghetticode...🤷‍♂️

Wo kommt eigentlich die Eingenart her, dass die Automatisierer auf biegen und brechen immer 10 Codezeilen zu 3 Codezeilen die keiner versteht optimieren wollen? Ist vermutlich ne Berufskrankheit 😂
 
Zuletzt bearbeitet:
Hab es jetzt so umgesetzt wie vorgeschlagen. Hier mal worum es überhaupt geht. Ein Baustein der nacheinander eine MPI Verbindung zu maximal 10 Stationen aufbaut und dort Daten liest und schreibt.

Code:
IF #stationen[#Station].MPI <> 0 THEN
    IF #"W/R" THEN
        #tANY_1 := p#DB1.DBx0.0 byte 1;
        #atANY_1."DB-Nr" := #stationen[#Station]."Master-In-DBNr";
        #tInt := TEST_DB(DB_NUMBER := #stationen[#Station]."Master-In-DBNr", DB_LENGTH => #atANY_1.Len, WRITE_PROT => #tBool);
        IF #tInt = 0 THEN
            #tANY_2 := p#DB1.DBx0.0 byte 1;
            #atANY_2."DB-Nr" := #stationen[#Station]."Slave-In-DBNr";
            #atANY_2.Len := #atANY_1.Len;
            #tInt := X_PUT(REQ := TRUE, CONT := FALSE, DEST_ID := #stationen[#Station].MPI, VAR_ADDR := #tANY_2, SD := #tANY_1, BUSY => #busy);
        END_IF;
        IF #busy THEN
            RETURN;
        ELSE
            #"W/R" := NOT #"W/R";
            #ComStörungSchreiben := #tInt;
        END_IF;
    ELSE
        #tANY_1 := p#DB1.DBx0.0 byte 1;
        #atANY_1."DB-Nr" := #stationen[#Station]."Master-Out-DBNr";
        #tInt := TEST_DB(DB_NUMBER := #stationen[#Station]."Master-Out-DBNr", DB_LENGTH => #atANY_1.Len, WRITE_PROT => #tBool);
        IF #tInt = 0 THEN
            #tANY_2 := p#DB1.DBx0.0 byte 1;
            #atANY_2."DB-Nr" := #stationen[0]."Slave-Out-DBNr";
            #atANY_2.Len := #atANY_1.Len;
            #tInt := X_GET(REQ := TRUE, CONT := FALSE, DEST_ID := #stationen[#Station].MPI, VAR_ADDR := #tANY_1, BUSY => #busy, RD => #tANY_2);
        END_IF;
        IF #busy THEN
            RETURN;
        ELSE
            #"W/R" := NOT #"W/R";
            #ComStörungLesen := #tInt;
        END_IF;
    END_IF;
    #ComStör[#Station] := (#ComStörungLesen < 0) OR (#ComStörungSchreiben < 0);
ELSE
    #ComStör[#Station] := false;
END_IF;

IF #Station = 9 THEN
    #Station := 0;
ELSE
    #Station := #Station + 1;
END_IF;
#ComStörungS1 := #ComStör[0];
#ComStörungS2 := #ComStör[1];
#ComStörungS3 := #ComStör[2];
#ComStörungS4 := #ComStör[3];
#ComStörungS5 := #ComStör[4];
#ComStörungS6 := #ComStör[5];
#ComStörungS7 := #ComStör[6];
#ComStörungS8 := #ComStör[7];
#ComStörungS9 := #ComStör[8];
#ComStörungS10 := #ComStör[9];
 
Ich denke, es geht eher um das Rumgepointere im IDB... da findest dann rückwärts über Querverweise garnix...

Querverweis bzw.. das „Finden“ steht für mich auch im Mittelpunkt.
Wenn sich an einer Anlage im Ablauf nichts mehr weiter bewegt und du an Hand der Diagnose nicht weiterkommst, dann ist der Einstieg in die Fehlersuche eben die Hardware-Adresse eines Aktors. Ganz besonders, wenn man noch nie in die Software schauen musste, weil die Anlage sonst perfekt läuft.
Wenn man nun über Querweise nichts findet, weil ein Programmierer z.B nur die Startadresse einer gesamten Station als Parameter übergibt und intern ohne jeden Bezug zur Hardware verknüpft, dann wird’s halt übel.
Besonders wenn noch sparsam kommentiert wurde.
 
Zurück
Oben