Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: SCL Nummern-Buffer

  1. #1
    Join Date
    16.11.2019
    Posts
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hey,
    habe aktuell ein Problem mit meiner Programmierung.
    Zum Fall:
    Habe 4 Datensätze (String) am Eingang
    Wenn alle 4 Datensätze vorhanden sind, kein Problem. Alles läuft wunderbar.
    Wenn jetzt aber kein Datensatz da ist und am ersten Datensatz kommen wieder Daten, dann wird mir dies am Ausgang "nächste" nicht raus gegeben. Erst wenn die vierte Stelle wieder belegt ist.
    Vielleicht kann mir ja ein SCL Profi oder Laie hier weiter helfen.
    Hier mal der Code:
    PIN 1-4 sind die Eingänge
    Nächste Pin ist der Ausgang

    #PIN_an_Band[0] := #PIN_1;
    #PIN_an_Band[1] := #PIN_2;
    #PIN_an_Band[2] := #PIN_3;
    #PIN_an_Band[3] := #PIN_4;






    REGION Circular_buffer
    (******* Flankenbildung ******************************************************)
    #R_TRIG_Ink_Puffer(CLK := #Benutzt_Naechste_PIN);
    IF #R_TRIG_Ink_Puffer.Q THEN
    FOR #i := 1 TO 3 BY 1 DO
    #PIN_FM[4 - #i] := #PIN_FM[3 - #i];
    END_FOR;

    #PIN_FM[0] := #Naechste_PIN;

    END_IF;


    END_REGION






    REGION Nechste_PIN


    // PIN
    IF #Naechste_PIN = '' THEN

    FOR #j := 1 TO 4 BY 1 DO
    #Kein_Arbeit := FALSE;
    #Tmp_String := '';

    FOR #i := 1 TO 4 BY 1 DO
    #Tmp_String := LEFT(IN:=#PIN_an_Band[4 - #j],L:=1);
    IF #PIN_an_Band[4 - #j] = #PIN_FM[#i - 1] AND #Kein_Arbeit = FALSE AND #Naechste_PIN = ''
    AND #PIN_an_Band[4 - #j] <> '' AND #Tmp_String <>' ' THEN
    #Kein_Arbeit := true;
    END_IF;
    END_FOR;
    IF #Kein_Arbeit = FALSE AND #Naechste_PIN = '' THEN
    #Naechste_PIN := #PIN_an_Band[4 - #j];
    END_IF;
    END_FOR;

    END_IF;

    // Reset PIN van gehet raus von arbeit platz
    IF #Naechste_PIN <> '' THEN

    #Reset_N_PIN := false;
    FOR #i := 1 TO 4 BY 1 DO
    IF #PIN_an_Band[4 - #i] = #Naechste_PIN THEN
    #Reset_N_PIN := true;
    END_IF;
    END_FOR;

    IF #Reset_N_PIN = false OR #Benutzt_Naechste_PIN THEN
    #Naechste_PIN := '';
    END_IF;
    END_IF;

    END_REGION


    #Naechste_PIN_Num := #Naechste_PIN;
    Reply With Quote Reply With Quote SCL Nummern-Buffer  

  2. #2
    Join Date
    05.06.2018
    Location
    Landkreis Osnabrück
    Posts
    325
    Danke
    30
    Erhielt 57 Danke für 44 Beiträge

    Default

    Hallo Florian,

    ich gehe davon aus das Du das TIA-Portal benutzt. Würdest Du dafür bitte einen Rechtsklick auf Deinen Baustein ausführen, dann Quelle aus Bausteinen generieren - nur selektierte Bausteine und den Inhalt der Datei dann anschließend innerhalb von code-Tags preisgeben? Das ist sehr viel übersichtlicher.

    Evtl. ein bisschen mehr Kommentar was Du an welcher Stelle versuchen willst wäre hilfreich. Glaub nicht das heute noch so viele Lust haben das gerade auseinanderzunehmen.

  3. #3
    Join Date
    22.06.2009
    Location
    Sassnitz
    Posts
    15,182
    Danke
    1,243
    Erhielt 4,469 Danke für 3,603 Beiträge

    Default

    Quote Originally Posted by Florian0511 View Post
    Hier mal der Code:
    PIN 1-4 sind die Eingänge
    Nächste Pin ist der Ausgang
    Du meinst #Naechste_PIN_Num ist ein OUTPUT? #Naechste_PIN wird mehrmals etwas zugewiesen und auch gelesen - das wäre sehr schlechter Programmierstil, wenn das ein OUTPUT ist.

    Service: der Programmcode in [CODE]-Tags und ein bisschen farbig:
    Code:
    #PIN_an_Band[0] := #PIN_1;
    #PIN_an_Band[1] := #PIN_2;
    #PIN_an_Band[2] := #PIN_3;
    #PIN_an_Band[3] := #PIN_4;
    
    
    REGION Circular_buffer
        (******* Flankenbildung ******************************************************)
        #R_TRIG_Ink_Puffer(CLK := #Benutzt_Naechste_PIN);
        IF #R_TRIG_Ink_Puffer.Q THEN
            FOR #i := 1 TO 3 BY 1 DO
                #PIN_FM[4 - #i] := #PIN_FM[3 - #i];
            END_FOR;
            
            #PIN_FM[0] := #Naechste_PIN;
            
        END_IF;
    
    END_REGION
    
    REGION Nechste_PIN
    
        // PIN
        IF #Naechste_PIN = '' THEN
            
            FOR #j := 1 TO 4 BY 1 DO
                #Kein_Arbeit := FALSE;
                #Tmp_String := '';
                
                FOR #i := 1 TO 4 BY 1 DO
                    #Tmp_String := LEFT(IN:=#PIN_an_Band[4 - #j],L:=1);
                    IF #PIN_an_Band[4 - #j] = #PIN_FM[#i - 1] AND #Kein_Arbeit = FALSE AND #Naechste_PIN = ''
                        AND #PIN_an_Band[4 - #j] <> '' AND #Tmp_String <>' ' THEN
                        #Kein_Arbeit := true;
                    END_IF;
                END_FOR;
                IF #Kein_Arbeit = FALSE AND #Naechste_PIN = '' THEN
                    #Naechste_PIN := #PIN_an_Band[4 - #j];
                END_IF;
            END_FOR;
            
        END_IF;
        
        // Reset PIN van gehet raus von arbeit platz
        IF #Naechste_PIN <> '' THEN
            
            #Reset_N_PIN := false;
            FOR #i := 1 TO 4 BY 1 DO
                IF #PIN_an_Band[4 - #i] = #Naechste_PIN THEN
                    #Reset_N_PIN := true;
                END_IF;
            END_FOR;
            
            IF #Reset_N_PIN = false  OR #Benutzt_Naechste_PIN THEN
                #Naechste_PIN := '';
            END_IF;
        END_IF;
        
    END_REGION
    
    #Naechste_PIN_Num := #Naechste_PIN;
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  4. #4
    Join Date
    22.06.2009
    Location
    Sassnitz
    Posts
    15,182
    Danke
    1,243
    Erhielt 4,469 Danke für 3,603 Beiträge

    Default

    In Deinem Programmstück spielen so viele unbekannte Variablen mit und er ist relativ umständlich formuliert, da ist es ziemlich schwer, denn Sinn zu erfassen (was der Code tun soll) und zu sehen, wo der Fehler ist.

    Übrigens: FOR-Schleifen kann man auch "rückwärts" laufen lassen und muß dann in der Schleife nicht so verwirrend rechnen, z.B. anstatt
    Code:
    FOR #i := 1 TO 3 BY 1 DO
        #PIN_FM[4 - #i] := #PIN_FM[3 - #i];
    END_FOR;
    kann man verständlicher und effizienter programmieren:
    Code:
    FOR #i := 3 TO 1 BY -1 DO
        #PIN_FM[#i] := #PIN_FM[#i - 1];
    END_FOR;
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  5. #5
    Join Date
    25.06.2017
    Location
    Oerlinghausen
    Posts
    2,525
    Danke
    262
    Erhielt 477 Danke für 392 Beiträge

    Default

    Quote Originally Posted by Florian0511 View Post
    Alles läuft wunderbar. ... aber ...
    ... selbst nach Haralds Mühen, das Programm augenfreundlicher zu gestalten, ... bleibt es schwer, zu ergründen, was es tut ... und noch viel schwerer, zu erahnen, was es tun soll.
    Vielleicht meinst Du mit "circular buffer" tatsächlich RingPuffer, aber den finde ich im Code nirgends.
    Die 4 ArrayElemente werden in jedem Zyklus aus denselben 4 Variablen vorbesetzt. Ist das Absicht oder Versehen?
    Der Abschnitt "FlankenBildung" schiebt 3 der 4 ArrayElemente in das jeweils vorhergehende Element. Das Element 3 bleibt dabei unverändert, aber das Element 0 wird sofort wieder zunichte gemacht und mit dem Inhalt von "#Naechste_PIN" überschrieben. Ist das Absicht oder Versehen?
    U.s.w., ein Rätsel jagt das nächste.
    Bitte erklär uns, was das Programm tun soll!

  6. #6
    Florian0511 is offline Neuer Benutzer
    Themenstarter
    Join Date
    16.11.2019
    Posts
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default

    Guten Morgen,
    sorry für die recht umständliche oder wenige Beschreibung.
    Also folgender Zustand.

    Vorne kommen immer von einer Station am laufenden Band immer neue PIN Nummern rein. Jeder Eingang ist für eine Station.
    Hinten soll immer die nächste raus kommen. Zu meinem Problem: Wenn alle 4 Stationen Belegt sind kommt auch hinten immer die nächste raus. Habe ich aber eine Lücke oder das Band ist Leer, dann soll, sobald an Station 1 wieder eine PIN ankommt, die auch direkt wieder hinten raus kommen. In PIN FM speicher ich mir immer die letzten, die schon abgearbeitet wurden.
    Ist immer schwierig so etwas auf zu schreiben
    Code:
    
    FUNCTION_BLOCK "FB_naechste_Wagen"
    { S7_Optimized_Access := 'TRUE' }
    VERSION : 0.1
       VAR_INPUT 
          PIN_1 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
          PIN_2 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
          PIN_3 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
          PIN_4 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
          Benutzt_Naechste_PIN { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
       END_VAR
    
       VAR_OUTPUT 
          Naechste_PIN_Num : String;
       END_VAR
    
       VAR_IN_OUT 
          PIN_FM : Array[0..3] of String;
       END_VAR
    
       VAR 
          Kein_Arbeit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;   //  Wagen nicht fuer Arbeit
          Reset_N_PIN : Bool;
          i { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int;
          j { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int;
          PIN_an_Band { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..3] of String;
          R_TRIG_Ink_Puffer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "R_Trig";   //  Positive Flanke fuer inkrementirungspuffer
          Naechste_PIN { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
          Tmp_String { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
       END_VAR
    
    
    BEGIN
        
        #PIN_an_Band[0] := #PIN_1;
        #PIN_an_Band[1] := #PIN_2;
        #PIN_an_Band[2] := #PIN_3;
        #PIN_an_Band[3] := #PIN_4;
        
        
        
        REGION Circular_buffer
            (******* Flankenbildung ******************************************************)
            #R_TRIG_Ink_Puffer(CLK := #Benutzt_Naechste_PIN);
            IF #R_TRIG_Ink_Puffer.Q THEN
                FOR #i := 1 TO 3 BY 1 DO
                    #PIN_FM[4 - #i] := #PIN_FM[3 - #i];
                END_FOR;
                
                #PIN_FM[0] := #Naechste_PIN;
                
            END_IF;
        
        END_REGION
        
        
        
        REGION Nechste_PIN
        
            // PIN
            IF #Naechste_PIN = '' THEN
                
                FOR #j := 1 TO 4 BY 1 DO
                    #Kein_Arbeit := FALSE;
                    #Tmp_String := '';
                    
                    FOR #i := 1 TO 4 BY 1 DO
                        #Tmp_String := LEFT(IN:=#PIN_an_Band[4 - #j],L:=1);
                        IF #PIN_an_Band[4 - #j] = #PIN_FM[#i - 1] AND #Kein_Arbeit = FALSE AND #Naechste_PIN = ''
                            AND #PIN_an_Band[4 - #j] <> '' AND #Tmp_String <>' ' THEN
                            #Kein_Arbeit := true;
                        END_IF;
                    END_FOR;
                    IF #Kein_Arbeit = FALSE AND #Naechste_PIN = '' THEN
                        #Naechste_PIN := #PIN_an_Band[4 - #j];
                    END_IF;
                END_FOR;
                
            END_IF;
            
            // Reset PIN van gehet raus von arbeit platz
            IF #Naechste_PIN <> '' THEN
                
                #Reset_N_PIN := false;
                FOR #i := 1 TO 4 BY 1 DO
                    IF #PIN_an_Band[4 - #i] = #Naechste_PIN THEN
                        #Reset_N_PIN := true;
                    END_IF;
                END_FOR;
                
                IF #Reset_N_PIN = false  OR #Benutzt_Naechste_PIN THEN
                    #Naechste_PIN := '';
                END_IF;
            END_IF;
            
        END_REGION
        
        #Naechste_PIN_Num := #Naechste_PIN;
    END_FUNCTION_BLOCK
    Last edited by Florian0511; 17.11.2019 at 08:30.

  7. #7
    Join Date
    05.06.2018
    Location
    Landkreis Osnabrück
    Posts
    325
    Danke
    30
    Erhielt 57 Danke für 44 Beiträge

    Default

    Hi,

    Deine Beschreibung kommt mir bekannt vor ^^, habe daher mal etwas rausgesucht. Du meinst nicht zufällig sowas oder?

    Code:
    FUNCTION_BLOCK "Arbeitsplatzüberwachung"
    { S7_Optimized_Access := 'TRUE' }
    VERSION : 0.1
       VAR_INPUT 
          EAN_IN : Array[1..8] of String[13];
          Max_Places : Int;
          used : Bool;
       END_VAR
    
    
       VAR_OUTPUT 
          EAN_OUT_Go : String[13];
          Station_to_delete : Int;
       END_VAR
    
    
       VAR 
          Index : Int;
          Trig_P : Bool;
          done : Bool;
       END_VAR
    
    
    
    
    BEGIN
    	// Abfrage der EAN, Ausgabe des Bearbeitungsp0latzes, von vorne neu aufrollbar, Übersprung bei leerer EAN, 
    	// Eingangs-EAN sind selbstständig zu löschenwenn Station_to_delete angelegt wird.
    	
    	IF NOT #done THEN
    	    #Index := #Index + 1;
    	    IF #Index > #Max_Places THEN
    	        #Index := 1;
    	    END_IF;
    	        IF #EAN_IN[#Index] <> '' THEN
    	            #EAN_OUT_Go := #EAN_IN[#Index];
    	            #done := true;
    	            #Station_to_delete := #Index;
    	        END_IF;
    	    END_IF;
    	IF #used AND NOT #Trig_P THEN
    	    #done := false;
    	END_IF;
    	#Trig_P := #used;
    	        
    	
    END_FUNCTION_BLOCK
    Funktion: Wenn aktiv werden bis zu Anzalh Maxstations=8 Stationen abgefragt und der Zähler bleibt dann bei dem ersten gefundenen EAN in diesem Fall stehen. Es erfolgt eine Ausgabe welcher EAN nun zu nutzen ist und welche Stationsnummer nun zu löschen ist. Dann sollte used triggern und die nächste wird genommen.

    Ist ein Konzept bei der mehrere Arbeitsplätze, belegt oder nicht, bei Ausgabe dann an einen anderen Arbeitsplatz mitteilen von wo das nächste Teil kommen soll um immer reihum zu arbeiten. Bei nicht vorhandenen Stationen (EAN='') würde diese nicht ausgewertet.

    Irgendwie verstehe ich sonst Deinen Code nicht so ganz.

  8. #8
    Florian0511 is offline Neuer Benutzer
    Themenstarter
    Join Date
    16.11.2019
    Posts
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default

    Folgendes:
    Ich habe ein Band, aufgeteilt in 4 Stationen.
    Vorne kommt immer ein Neuer Datensatz rein, und hinten geht ein alter weg.
    Ich habe 2 Schrauber. Schrauber 1 soll Pin 1 bekommen, Schrauber 2 soll Pin 2 bekommen. Wenn Schrauber 1 fertig, dann soll Schrauber 1 Pin 3 bekommen und Schrauber 2 PIN4
    Und so soll es immer weiter laufen, dieses funktioniert auch soweit, wenn das Band voll ist. Habe ich aber eine Lücke oder das Band ist Leer, dann kommt vorne an Pin 1 eine Pin an, wird dann weiter geschoben (durch das Band) an Pin 2 usw... und in meinem Baustein bekomme ich dann hinten immer erst einen Ausgang wenn die PIN an Platz 4 angekommen ist
    Last edited by Florian0511; 17.11.2019 at 13:02.

  9. #9
    Join Date
    17.03.2010
    Location
    Bonn
    Posts
    437
    Danke
    4
    Erhielt 101 Danke für 93 Beiträge

    Default

    je mehr hier erklärt wird , je schlimmer wird es
    Band mit 4 Stationen , es werden 4 PINs an die 4 Stationen verteilt , dann tauchen auch noch 2 Schrauber auf , die mit den PINs irgendwas machen, wenn der Schrauber1 fertig ist werden neue PINs verteilt (ob Schrauber 2 fertig ist spielt scheinbar keine Rolle ) .

    ich verstehe das nicht

    eins der größten Probleme ist , wenn man nicht beschreiben kann was man will

  10. #10
    Florian0511 is offline Neuer Benutzer
    Themenstarter
    Join Date
    16.11.2019
    Posts
    4
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Also vorne am Baustein kann man sich ein Band vorstellen, an dem von oben nach unten die PINs fortlaufend durchlaufen. Eingang 1- Station 1; Eingang 2- Station 2; Eingang 3- Station 3 usw
    Das heißt die Pin wandert immer von Station eins nach Station 4 und fährt raus.
    Schrauber 1 bekommt PIN (wenn Band voll dann von Station 4) (wenn Band Leer und vorne kommt eine neue rein dann von Station 1)
    Ich brauche also am Ausgang immer die "nächste" PIN aus 4 Plätzen.
    Vorne am Eingang sind leer strings wenn keine Daten vorhanden sind. Sobald aber eine Pin nach kommt weil das Band sich wieder füllt, will ich diese auch am Ausgang haben

Similar Threads

  1. sysfileread - Daten Zeilenweise in Buffer schreiben
    By SY50 in forum CODESYS und IEC61131
    Replies: 7
    Last Post: 03.10.2015, 11:55
  2. Step 7 OSCAT LIB Buffer to String
    By silverfreaky in forum Simatic
    Replies: 0
    Last Post: 11.09.2015, 19:29
  3. RCV_PTP Buffer Probleme
    By carki in forum Simatic
    Replies: 2
    Last Post: 15.03.2012, 16:10
  4. Replies: 5
    Last Post: 19.01.2011, 15:01
  5. Timer-Nummern
    By charlie in forum Simatic
    Replies: 6
    Last Post: 13.06.2006, 19:53

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •