TIA Hochregallager mit Array , abfrage etc.

Steven_85

Level-1
Beiträge
22
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen,

bin neu hier. Ich mache gerade eine Weiterbildung als SPS Techniker.

Arbeite beim Lehrgang mit TIA V14 und Factory I/O.

Ich habe jetzt für mich mal das Automatische Hochregallager ausgesucht.

Er lädt auch das ein.
Jetzt wollte ich das mit ein Array [1..54] lösen, dass er weiß welcher Regalplatz belegt ist und welcher nicht.
Aber ich tue mich irgendwie schwer?!
Habe den Array als DB angelegt

Mein Bsp. :
IF #S_Cran_Middle_Limit AND #"Place Pal Seq No" = 4 THEN
#Destination := #Destination + 1;
#"S_Cran_Target Pos" := #Destination;
#"Place Pal Seq No" := 5;
"Hilfs_V"."Time 1 Start" := TRUE;
END_IF;

Das Destination ersetze ich dann mit array?

Wie setze ich das um, dass er dann einen freien Platz sucht? Bsp. 20 , 21, 22, 24 sind belegt , und er soll bsp. automatisch in die 23 ablegen.

Danke schön im Voraus

Gruß Steven
 
Hallo Steven,
der Ansatz mit dem Array ist doch gut.
Ich nehme mal an, dass du ein Array of Bool hast bei dem ein TRUE am Element dann belegt heißt und ein FALSE dann frei (oder unbelegt).
Wenn du nun die Funktion "Einlagern" deines Bausteins startest dann läßt du einfach das Array in einer Schleife durchlaufen und den ersten Index suchen, der "unbelegt" sagt. Diesen Index speicherst du dir und brichst die Schleife ab. Nun kannst du an dem Index dann das TRUE setzen.
Beim "Auslagern" ist es ja ganz easy - da hast du ja den Index und musst nur überprüfen ob hier wirklich etwas liegt (der Index also TRUE ist).
Nun kannst du den Index auf FALSE setzen - andernfalls gibst du einen Fehler aus.
Einen Fehler müsstest du auch ausgeben wenn du beim "Einlagern" keinen freien Platz mehr findest.
Jetzt müsstest du dir allerdings noch ein weiteres Array bauen in das du reinschreibst was du eingelagert hast ...
 
Hallo Steven,
der Ansatz mit dem Array ist doch gut.
Ich nehme mal an, dass du ein Array of Bool hast bei dem ein TRUE am Element dann belegt heißt und ein FALSE dann frei (oder unbelegt).
Wenn du nun die Funktion "Einlagern" deines Bausteins startest dann läßt du einfach das Array in einer Schleife durchlaufen und den ersten Index suchen, der "unbelegt" sagt. Diesen Index speicherst du dir und brichst die Schleife ab. Nun kannst du an dem Index dann das TRUE setzen.
Beim "Auslagern" ist es ja ganz easy - da hast du ja den Index und musst nur überprüfen ob hier wirklich etwas liegt (der Index also TRUE ist).
Nun kannst du den Index auf FALSE setzen - andernfalls gibst du einen Fehler aus.
Einen Fehler müsstest du auch ausgeben wenn du beim "Einlagern" keinen freien Platz mehr findest.
Jetzt müsstest du dir allerdings noch ein weiteres Array bauen in das du reinschreibst was du eingelagert hast ...
Hallo Larry,

Ja genau habe ein Array of Bool angelegt.
Puh, wie mache ich das mit der Schleife ? Ist leider nicht wirklich der Bestandteil der Weiterbildung mit SCL.. ist nur ein Zusatz, weil "wir" schnell sind. Ich bin persönlich um Maschinenbau unterwegs und habe eigentlich mit so ein Regal nichts am "Hut" . Aber ich persönlich möchte das gerne mal programmieren, damit ich sowas auch schon mal gemacht habe.

Sprich mit den Array :


REGION Fahrt ins Regal
IF #S_Cran_Middle_Limit AND #"Place Pal Seq No" = 4 THEN
#Destination := #Destination + 1;
"Regal".Regallager[#Destination] := TRUE;
#"S_Cran_Target Pos" := #Destination;
#"Place Pal Seq No" := 5;
"Hilfs_V"."Time 1 Start" := TRUE;
END_IF;

END_REGION


REGION Heber Fahrt nach rechts ins Regal
IF (#"S_Cran_Moving X" = FALSE)
AND (#"S_Cran_Moving Z" = FALSE)
AND "Hilfs_V"."Timer 1 done"
AND #"Place Pal Seq No" = 5 THEN
#HilfsV_SC_Rechts := TRUE;
"Hilfs_V"."Time 1 Start" := FALSE;
#"Place Pal Seq No" := 6;
END_IF;

Die Schleife mache ich dann vor "Fahrt ins Regal" ?

Oder muss ich bei For ...to .. by .. Do.. noch definieren ?
Sorry , die Fragen wurde bestimmt 1000x gestellt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das sollte nur ein Beispiel sein, wie du aus deinem Array raussuchen kannst welcher Platz noch frei ist.
Du kannst dir einen Globalen DB anlegen in dem du solche Variablen anlegst, oder anstatt dem FC halt einen FB
 
Habe das im FC gemacht, da habe ich kein Static..
Das Array mit den Fachdaten sollte auf jeden Fall in einem globalen DB liegen, weil die Daten in der Praxis von vielen Funktionen benötigt werden.

Tip: verwende in Variablennamen keine Leerzeichen und keine Sonderzeichen, sondern nur Buchstaben, Ziffern und Unterstrich.

Harald
 
Tip: verwende in Variablennamen keine Leerzeichen und keine Sonderzeichen, sondern nur Buchstaben, Ziffern und Unterstrich.
Ja, ganz wichtig.

Und dann ist das Programm auch V18 kompatibel weil ab V18:
1669108156573-png.65079
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Array mit den Fachdaten sollte auf jeden Fall in einem globalen DB liegen, weil die Daten in der Praxis von vielen Funktionen benötigt werden.

Tip: verwende in Variablennamen keine Leerzeichen und keine Sonderzeichen, sondern nur Buchstaben, Ziffern und Unterstrich.

Harald
Den Array habe ich in ein DB angelegt :
Lager ( Array [1...54] of Bool
Danke für den Hinweis mit den Namen
 
Wie PN/DP und DeltaMikeAir schon geschrieben haben,

ist es zwingend erforderlich dass dein LagerArray in einem globalen DB angelegt ist....dieser vielleicht sogar Mehrdimensional. Für Daten wann wurde der Platz belegt oder wieder Freigegeben....Chargendaten etc....pp
Hierzu würde ich dann sogar einen UDT anlegen.

Dein Baustein mit dem Du diese Daten verarbeitest oder durchsuchst sollte dann ein SCL-FB sein. Da du dort auch mal Statische Variablen brauchst. Ganz schlecht wäre Zählervariablen irgendwo zu erzeugen und zu benutzen. Das führt nur dazu dass diese aus Versehen mehrfach benutzt werden...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe das im FC gemacht, da habe ich kein Static..

Du solltest das auf alle Fälle in einem FB machen.
Dort könntest du auch deine Array's anlegen und deine Schrittkette für den Ablauf.
Das Ganze könnte dann so aussehen :
Schritt 0 : warten auf Start-Befehl
Schritt 1 : Einlagern - scanne das Array in einer Schleife nach dem ersten freien Platz
-> wenn gefunden dann Schritt 2
-> wenn nicht gefunden dann Abbruch mit Fehler
Schritt 2 : fahre den Platz an
-> wenn Pos. erreicht Schritt 3
Schritt 3 ; Gabel heben
Schritt 4 : Gabel ausfahren
Schritt 5 : Gabel absenken + Platz als belegt markieren + Platz-Info setzen
Schritt 6 : Gabel zurückfahren
Schritt 7 : fertig melden


Das Ganze ist natürlich schön in SCL umzusetzen - aber das tust du ja schon ... ;)
 
Du solltest das auf alle Fälle in einem FB machen.
Dort könntest du auch deine Array's anlegen und deine Schrittkette für den Ablauf.
Das Ganze könnte dann so aussehen :
Schritt 0 : warten auf Start-Befehl
Schritt 1 : Einlagern - scanne das Array in einer Schleife nach dem ersten freien Platz
-> wenn gefunden dann Schritt 2
-> wenn nicht gefunden dann Abbruch mit Fehler
Schritt 2 : fahre den Platz an
-> wenn Pos. erreicht Schritt 3
Schritt 3 ; Gabel heben
Schritt 4 : Gabel ausfahren
Schritt 5 : Gabel absenken + Platz als belegt markieren + Platz-Info setzen
Schritt 6 : Gabel zurückfahren
Schritt 7 : fertig melden


Das Ganze ist natürlich schön in SCL umzusetzen - aber das tust du ja schon ... ;)
Ok, werde ich gleich mal nach der Mittagspause umsetzen (bzw. probieren)

Den ganzen SCL Code kann ich dann per txt einfügen oder ne PDF ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nutz den Code-Tag hier im Forum, für deinen Quell-Code ;). Zu finden bei den Symbolen, auf die 3 Punkte klicken.
AH Danke !! 👍


1677585909058.png


Das ist meine Static.

Code:
REGION Initialisierung
    IF "Sensor_Loading" = FALSE AND "Stacker_Crane_middle_Limit"
        AND #Sequenz = 0 THEN
        #Sequenz := 1;
        #Time_1_PT := T#0.5S;
        ;
    END_IF;
END_REGION

REGION Timer 1
    #IEC_Timer_0_Instance(IN:=#"Time _1_ Start",
                          PT:=#Time_1_PT,
                          Q=>#Timer_1_done,
                          ET=>#"Timer_ 1_Val");
   
   
END_REGION


REGION Palettenheber links ausfahren
    IF #Sequenz = 1 THEN
        "Hilfs_V".S_Cran_Links := TRUE;
        #Sequenz := 2;
    END_IF;
   
END_REGION

REGION Lift Anheben
    IF "Stacker_Crane_Left_Limit" AND #Sequenz = 2 THEN
        "Hilfs_V".S_Cran_Lift := TRUE;
        #"Time _1_ Start" := TRUE;
        #Sequenz := 3;
    END_IF;
   
END_REGION

REGION Heber zurück fahren
    IF #Sequenz = 3 AND #Timer_1_done THEN
        "Hilfs_V".S_Cran_Links := FALSE;
        #"Time _1_ Start" := FALSE;
        #Sequenz := 4;
    END_IF;
   
END_REGION

REGION Scanne Array
    FOR #Destination := 1 TO 54 DO
        IF #Lager[#Destination] = FALSE THEN
            #freiesFach := True;
            EXIT;
        END_IF;
        IF #freiesFach = TRUE THEN
            EXIT;
        ELSIF #freiesFach = FALSE THEN
            "HMI Meldungen".Error.%X0 := TRUE;
           
        END_IF;
    END_FOR;
           
   
END_REGION

REGION Fahrt ins Regal
    IF "Stacker_Crane_middle_Limit" AND #Sequenz = 4 AND #freiesFach = TRUE THEN
        #Destination := #Destination + 1;
        "Stacker_Crane_Target Pos" := #Destination;
        #Sequenz := 5;
        #"Time _1_ Start" := TRUE;
    END_IF;
   
END_REGION


REGION Heber Fahrt nach rechts ins Regal
    IF ("Stacker_Crane_Moving X" = FALSE)
        AND ("Stacker_Crane_Moving Z" = FALSE)
        AND #Timer_1_done
        AND #Sequenz = 5 THEN
        "Hilfs_V".S_Cran_Rechts := TRUE;
        #"Time _1_ Start" := FALSE;
        #Sequenz := 6;
    END_IF;
   
END_REGION

REGION Lift absenken & Platz belegt markieren
    IF "Stacker_Crane_right_Limit" AND #Sequenz = 6 THEN
        "Hilfs_V".S_Cran_Lift := FALSE;
        #Lager[#Destination] := TRUE;
        #"Time _1_ Start" := TRUE;
        #Sequenz := 7;
    END_IF;
END_REGION

REGION Zurück Fahrt zum Zentrum
    IF #Sequenz = 7 AND #Timer_1_done THEN
        "Hilfs_V".S_Cran_Rechts := FALSE;
        #"Time _1_ Start" := FALSE;
        #Sequenz := 8;
    END_IF;
   
END_REGION


REGION Zurückfahrt zur Home Position
    IF #Sequenz = 8 AND "Stacker_Crane_middle_Limit" THEN
        "Stacker_Crane_Target Pos" := 55;
        #Sequenz := 9;
        #"Time _1_ Start" := TRUE;
    END_IF;
   
END_REGION

REGION "Reset"
    IF ("Stacker_Crane_Moving X" = FALSE)
        AND ("Stacker_Crane_Moving Z" = FALSE)
        AND #Sequenz = 9
        AND #Timer_1_done THEN
        #Sequenz := 0;
        #"Time _1_ Start" := FALSE;
    END_IF;
   
END_REGION

So richtig ?

Merke gerade, er legt nur Regalfach 2 ab ..
 
Zuletzt bearbeitet:
Die Schrittkette könntest du (da Sequenz ja genau das ist) auch als CASE ausführen - es ist so aber auch nicht falsch.
Du hast die "Funktion" suche freies Array-Feld nicht mit programmiert - dafür hatte dir aber @QuaxBruchpilot in Beitrag #3 schon ein Beispiel gepostet ...
 
Zurück
Oben