# In TIA Bausteinausgänge über Index ansprechen



## sunny22 (12 März 2022)

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


----------



## TP-Inc (12 März 2022)

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.


----------



## sunny22 (12 März 2022)

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.


----------



## Blockmove (12 März 2022)

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!


----------



## NBerger (12 März 2022)

> 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


----------



## C_wie_Cäsar (12 März 2022)

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


----------



## Heinileini (12 März 2022)

NBerger schrieb:


> 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.


----------



## ducati (12 März 2022)

Heinileini schrieb:


> 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


----------



## Blockmove (12 März 2022)

NBerger schrieb:


> 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.


----------



## JesperMP (12 März 2022)

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._


----------



## PN/DP (12 März 2022)

NBerger schrieb:


> 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


----------



## Heinileini (12 März 2022)

ducati schrieb:


> ja, wärst Du mal lieber selber zur Inbetriebnahme gefahren


Ich hatte den Zyklus beim Kunden schon erfolgreich in Betrieb genommen, bevor der InbetriebNehmer dann kreativ wurde ...


----------



## sunny22 (12 März 2022)

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.


----------



## escride1 (12 März 2022)

sunny22 schrieb:


> 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.





JesperMP schrieb:


> 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] ;
> ...


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.


----------



## DeltaMikeAir (12 März 2022)

C_wie_Cäsar schrieb:


> Ich würde keine Anlage abnehmen in der das Programm keiner lesen kann


Lesen kann es doch jeder, verstehen ist aber noch einmal etwas anderes.


----------



## Thomas_v2.1 (12 März 2022)

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.


----------



## escride1 (12 März 2022)

DeltaMikeAir schrieb:


> 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?


----------



## ducati (13 März 2022)

Thomas_v2.1 schrieb:


> 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 😂


----------



## sunny22 (13 März 2022)

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.


```
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];
```


----------



## Blockmove (13 März 2022)

ducati schrieb:


> 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.


----------



## ducati (13 März 2022)

sunny22 schrieb:


> 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.
> 
> 
> ```
> ...


Hmm, irgendwie gibts da keinen einzigen Kommentar in dem Code...
Aber das Ende ist sicher so, wie Jesper das gemeint hat.


----------



## Blockmove (13 März 2022)

@sunny22


ducati schrieb:


> Hmm, irgendwie gibts da keinen einzigen Kommentar in dem Code...
> Aber das Ende ist sicher so, wie Jesper das gemeint hat.


Variablennamen sind auch nicht gerade aussagekräftig.
Mein erster Chef hätte mir da einen Einlauf verpasst.


----------



## Onkel Dagobert (13 März 2022)

Funktioniert es denn? 
PUT und GET kann man simulieren. Aber läuft X_PUT und X_GET auch im Simulator?


----------



## sunny22 (13 März 2022)

Na was ein Glück dass ich die Anlage selbst Projektiere, Programmiere und betreibe. Meinem Chef ist das ziemlich egal was ich da mache. Liegt vielleicht daran das er es sowieso nicht versteht. Wichtig ist, dass es am Ende funktioniert. Ich denke auch in SCL ist es jetzt nicht soo schwer nachzuvollziehen was da passiert, auch ohne Kommentare.
Ob es funktioniert werd ich dann morgen an Testaufbau ergründen. Von der Programmsteuerung sieht es im Simulator aber erstmal ganz OK aus.


----------



## ducati (13 März 2022)

Naja, Du fragst doch hier unter Programmierstrategien, wie man etwas eleganter programmieren könnte...
Und grundsätzlich kannst Du ja auch mal krank sein oder kündigen, dann muss nen anderer da durchsteigen. Von daher wären Kommentare hilfreich. Und warum soll jemand da etwas nachvollziehen müssen, wenn Du auch einfach drüber schreiben könntest, was die nachfolgenden Zeilen machen 🙄
Ansonsten ist PUT immer mit Vorsicht zu genießen, weil wenn bei Deinem Code irgendwas nicht so passt, dann schreibst Du in irgendeine SPS irgendwas irgendwo rein...


----------



## escride1 (13 März 2022)

sunny22 schrieb:


> Ob es funktioniert werd ich dann morgen an Testaufbau ergründen


^^ Viel Erfolg.


----------



## hucki (13 März 2022)

Wie erfolgt denn


sunny22 schrieb:


> Array am Ausgang geht nicht weil der Baustein in FUP beschaltet werden soll.


Wie sieht denn eigentlich diese Beschaltung aus?
Vielleicht lässt sich ja diese Übergabe an Dein ursprünglich gewünschtes Array anpassen?


----------



## sunny22 (13 März 2022)

Die Ausgänge sind mit DB-Bit's für ein HMI beschaltet. Ich würde die Zustände beim beobachten im FUP gerne direkt sehen. Daher die einzelnen Ausgänge.


----------



## sunny22 (13 März 2022)

ducati schrieb:


> ... Von daher wären Kommentare hilfreich....


Wahrscheinlich hast Du Recht. Eine Kurze Funktionsbeschreibung kann nicht schaden. Werd ich dann noch machen wenn das Programm soweit läuft.


----------



## hucki (13 März 2022)

sunny22 schrieb:


> Die Ausgänge sind mit DB-Bit's für ein HMI beschaltet. Ich würde die Zustände beim beobachten im FUP gerne direkt sehen. Daher die einzelnen Ausgänge.



Beobachten der Einzelbits geht ja auch im DB und muss man auch nur mal temporär.
Ich sehe da jetzt noch nicht den wirklichen Vorteil gegenüber einer Arrayübergabe an den DB.


----------



## sunny22 (14 März 2022)

Was dann wieder meine Theorie aus #13 bestätigt.

Auf jeden Fall tut es jetzt das was es soll. Danke für eure Unterstützung!


----------

