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

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 28

Thema: Funktion wird nicht in einem Zyklus durchlaufen

  1. #1
    Registriert seit
    29.08.2009
    Beiträge
    776
    Danke
    25
    Erhielt 3 Danke für 3 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo, ich habe folgendes Problem.

    Ich rufe in einer CASE Struktur im CASE 104 einen FC auf, welcher mir verschiedene Umwandlungen durchführt.
    Wenn er fertig ist, ändert sich eine Variable von 0.0 auf -999.999.
    Wenn ich den Case 104 durchlaufe und direkt nach dem aufrufen des FC´s in den CASE 105 laufe, dann schreibt er mir allerdings die Variable nicht auf -999.999, sonder verändert garnichts.
    Es ist so, als würde die Funktion nicht durchlaufen.
    Wenn ich allerdings nicht weiter laufe und im case 104 verharre, ändert sich die Variable auf -999.999. Es kommt mir irgendwie so vor, als würde die Funktion mehr als einen Zyklus brauchen.
    Ich habe sie auch schon in FUB aufgerufen und den aufruf mit dem AUSgang ENO zurückgenommen, dann sollte sie ja auf jeden Fall durchlaufen sein, aber dort ist es der gleiche effekt. erst wenn ich sie dauernd aufrufe, dann funktioniert es. hat jemand ne idee?
    Zitieren Zitieren Funktion wird nicht in einem Zyklus durchlaufen  

  2. #2
    Registriert seit
    15.01.2005
    Ort
    In der Mitte zwischen Bayreuth/Weiden
    Beiträge
    6.735
    Danke
    321
    Erhielt 1.523 Danke für 1.283 Beiträge

    Standard

    Wenn du jetzt noch sagen würdest welche Funktion du da aufrufst,
    diese evtl. sogar posten kannst, dann wäre schon viel Grundlage einer vernünftigen Antwort geschaffen.

    Mfg
    Manuel
    Warum denn einfach, wenn man auch Siemens einsetzen kann!

    Wer die grundlegenden Freiheiten aufgibt, um vorübergehend ein wenig Sicherheit zu bekommen, verdient weder Freiheit noch Sicherheit (B. Franklin).

  3. #3
    Bensen83 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    29.08.2009
    Beiträge
    776
    Danke
    25
    Erhielt 3 Danke für 3 Beiträge

    Standard

    Also habe die jetzt nicht hier am rechner, aber es ist eien slbst geschriebene SCl Funktion.
    Diese wandelt einen RS232 Lesepuffer, welcher in einem DB steht in ein Array von Strings um. DIese Umwandlung erfolgt durch indirektes lesen und schreiben der DBs. Hilf dir das etwas weiter?

  4. #4
    Registriert seit
    09.06.2008
    Beiträge
    138
    Danke
    16
    Erhielt 13 Danke für 13 Beiträge

    Standard

    Nein.
    Ohne etwas Code wird das wahrscheinlich nichts.

  5. #5
    Bensen83 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    29.08.2009
    Beiträge
    776
    Danke
    25
    Erhielt 3 Danke für 3 Beiträge

    Standard

    Also ich Rufe die Funktion "Keyence to real" hier in der Case auf: ( Step 104)

    Code:
      //  Abfrage ob neue Daten vorhanden sind   
        104:
            IF  "Steuerung_Keyence".Austausch.Lesen.Allgemein.Neue_Daten_vorhanden = TRUE THEN
                
                    "Steuerung_Keyence".Austausch.Lesen.Allgemein.anfordern := FALSE;
            END_IF;
            
            IF  "Keyence_Lesebereich".Lesebyte[1] = "Steuerung_Keyence".Konstanten.ASCII_M AND
                "Keyence_Lesebereich".Lesebyte[2] = "Steuerung_Keyence".Konstanten.ASCII_A AND
                "Keyence_Lesebereich".Lesebyte[3] = "Steuerung_Keyence".Konstanten.ASCII_Komma THEN
                    
                    
                    "Daten_Keyence".Lesungen.Hand.Anzahl_Werte := Keyence_to_Real(Laenge_Paket :=  "Steuerung_Keyence".Austausch.Lesen.Allgemein.Laenge// IN: INT
                    ,DB_Paket :=  "Keyence_Lesebereich"// IN: BLOCK_DB
                    ,Startbyte_Paket :=  0// IN: INT
                    ,DB_Real :=  "REALTEST"// IN: BLOCK_DB
                    ,Startbyte_Real :=  0// IN: INT
                    ); // INT
                     
                   
                    IF  "REALTEST".REAL_01 = -999.999 THEN 
                        
                        //"Steuerung_Keyence".Umwandeln.Hand.Start := FALSE;
                        "Steuerung_Keyence".Allgemeines.State := 0;
                    ELSE
                        "Steuerung_Keyence".Test := "Steuerung_Keyence".Test + 1;
                    END_IF;
            END_IF;
    Habe jetzt eine Abfrage auf -999 rein gemacht, bis dies erreicht ist, wird eine testvariable hochgezählt, welche mir die Zyklen Zählt. die Funktion braucht im Moment ca. 5-7 Zyklen, bis sie die Werte raus gibt.

    Hier die Funktion:

    Code:
    FUNCTION FC951 : INT
    
    // Diese Baustein konvertiert ein vom Keyence Messystem empfangenes Datenpaket in Reals
    VAR_INPUT
       Laenge_Paket : INT;
       DB_Paket : BLOCK_DB;
       Startbyte_Paket : INT;
       DB_Real : BLOCK_DB;
       Startbyte_Real : INT; 
    END_VAR
    VAR_TEMP
        
        Modus : INT;                // 1 = MA --> Es wurde nur eine Messung abgerufen
        Kanal : INT;                // 2 = AD --> Es wurden mehrere Messungen abgerufen   
        Realzahl : REAL;            // Errechnete Realzahl
        Teiler_Realzahl : REAL;     // Gibt an, durch welchen Faktor die Zahl geteilt werden soll
        Zaehler : INT;              // Zaehler für Schleifenindex
        Index_Real : INT;           // Index für die Realzahl
        Freigabe_addieren : BOOL;   // Freigeb zum Aufaddieren der einzelnen Werte
        Zwischenint : INT;          // Wird zur Zwischenspeicherung benötigt
        Zahl_positiv : BOOL;        // Wird gesetzt, wenn die Zahl Positiv ist
    END_VAR
        // Abfragen des Modus, welcher gefahren wird.
        IF  DB_Paket.DB[Startbyte_Paket + 0] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_M) AND
            DB_Paket.DB[Startbyte_Paket + 1] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_A) AND
            DB_Paket.DB[Startbyte_Paket + 2] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_Komma) THEN
        
                Modus := 1;
                        
        END_IF;
        
        Realzahl := 0.0;
        Teiler_Realzahl := 1.0;
        Index_Real := 0;
        Zahl_positiv := TRUE;        
                
        CASE Modus OF
            
            // Hier wird Modus eins Durchlaufen
            1: 
                FOR Zaehler := Startbyte_Paket + 3 TO Startbyte_Paket + Laenge_Paket BY 1 DO
                    
                    // Rücksetzen der Freigabe Addition
                    Freigabe_addieren := FALSE;
                                   
                    IF  DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_0) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_1) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_2) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_3) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_4) THEN
                            
                            Freigabe_addieren := TRUE;
                                
                    END_IF;
                    
                    IF  DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_5) OR 
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_6) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_7) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_8) OR
                        DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_9) THEN
                        
                            Freigabe_addieren := TRUE;
                                
                    END_IF;     
                    
                    IF  Freigabe_addieren = TRUE THEN
                        
                        Zwischenint := BYTE_TO_INT(DB_Paket.DB[Zaehler]);
                        Realzahl := Realzahl + INT_TO_REAL(Zwischenint - 48)/ Teiler_Realzahl;
                        //Realzahl := Realzahl + INT_TO_REAL(BYTE_TO_INT((DB_Paket.DB[Zaehler]))/Teiler_Realzahl;
                        IF Teiler_Realzahl > 1.0 THEN
                            Teiler_Realzahl := Teiler_Realzahl * 10.0;
                        END_IF;
                        
                    END_IF;
                
                    IF  DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_Punkt) THEN
                    
                            Teiler_Realzahl := Teiler_Realzahl * 10.0;     
                    
                    END_IF; 
                    
                    IF  DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_Minus) THEN
                    
                            Zahl_positiv := FALSE;    
                    
                    END_IF;
                    
                     // Die Abfrage auf 0 bis 9 musste auf 2 Abfrage aufgeteilt werden (SIEMENS !!! ;-) )
                    IF  DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_F) THEN
                    
                        Realzahl := 999.999;
                    
                    END_IF;
                
                    IF  DB_Paket.DB[Zaehler] = CHAR_TO_BYTE("Steuerung_Keyence".Konstanten.ASCII_Komma) OR
                        Zaehler = Startbyte_Paket + Laenge_Paket THEN
                                                   
                            DB_Real.DD[Startbyte_Real + Index_Real] := REAL_TO_DWORD(Realzahl);
                            IF Zahl_positiv = FALSE THEN
                            
                                DB_Real.DD[Startbyte_Real + Index_Real] := REAL_TO_DWORD(Realzahl * -1.0);    
                             
                            END_IF;
                                    
                            Index_Real := Index_Real + 4;                        
                            Realzahl := 0.0;
                            Teiler_Realzahl := 1.0;
                            Zahl_positiv:= TRUE;
                    END_IF; 
                    
                END_FOR;
        END_CASE;
        
        FC951 := Index_Real/4;        
    END_FUNCTION
    Woran kann das liegen?
    Zitieren Zitieren Hier der Code  

  6. #6
    Registriert seit
    20.02.2008
    Beiträge
    332
    Danke
    16
    Erhielt 40 Danke für 37 Beiträge

    Standard

    Also, was ich sehe, ist:
    Bevor Du die Funtion aufrufst, vergleichst Du die Lesebytes 1-3 auf eine Wertfolge. In der Funktion wird die Variable Modus auf 1 gesetzt, wenn die Lesebytes 0-2 die selben Werte habe. Und erst wenn Modus = 1 ist, wird die Case-Bedingung abgearbeitet. D.h. Modus kann nie 1 werden, weil die Abfragen kollidieren - ausser es hilft jemand nach. Und dann bleibt Modus auch auf 1, Die Case-Bedingung kann abgearbeitet werden. Der erste Teil in der Funktion ist also erstmal sinnfrei...

    Zu Deiner Frage: Ich würde sagen, das Du die Abarbeitung bereits startest, bevor der Empfangspuffer komplett geschrieben ist. Darum braucht es mehrere Zyklen, bevor Du ein brauchbares Ergebnis bekommst. Kopierst Du die Daten direkt in den "DB_Paket" oder mit Blockmove oder so was ähnlichem?

    Vielleicht kannst Du das Protokollende abprüfen, um sicherzustellen, das der Empfangspuffer vollständig ist, bevor Du die Funktion aufrufst. Oder die Anzahl der mindest zu empfangenen Zeichen erhöhen.

    Oder Du musst damit leben und Dein Programm umstricken, das es mehrere Zyklen verträgt.

  7. #7
    Registriert seit
    09.08.2006
    Beiträge
    3.629
    Danke
    912
    Erhielt 656 Danke für 542 Beiträge

    Standard

    ohne jetzt den Code genau gelesen zu haben, aber ne Abfrage einer real-Variablen auf Gleichheit (IF "REALTEST".REAL_01 = -999.999 THEN) ist schon mal problematisch: Siehe hier:

    http://www.sps-forum.de/showthread.p...132#post369132

    schönes Wochenende.

  8. #8
    Bensen83 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    29.08.2009
    Beiträge
    776
    Danke
    25
    Erhielt 3 Danke für 3 Beiträge

    Standard

    Also das mit dem Lesebyte 1 und Lesebyte 0 was du geschrieben hast ist nicht richtig.
    Ich vergleiche Zwar Lesebyte[1] bis Lesebyte[3] dies sind aber Symbolische Variablen.
    Diese liegen auf dem Selben Speicherbereich wie indirekt adressiert 0 - 2.
    Das ARRAY Lesebyte fängt bei 1 an hat aber die Adresse 0

    Ich dachte wenn der P RCV der mir die Daten in den DB läd Fertig meldet wäre der schreibvorgang beendet aber dem scheint ja nicht so zu sein. Wie bekomme ich raus, wann er wiklich fertig ist und wie kann man große daten mit ihm empfangen?
    Zitieren Zitieren Erklärung  

  9. #9
    Registriert seit
    20.02.2008
    Beiträge
    332
    Danke
    16
    Erhielt 40 Danke für 37 Beiträge

    Standard

    OK, dann nehme ich das erst mal zurück. Ich wusste nicht, das das eine Array mit 1 beginnt.

    Frage: Wie prüfst Du das Ende des Empfangs ab? Mit .NDR oder .LEN > X?
    Ich kann mich dunkel erinnern, das ich mit dem .NDR auch solche Probleme hatte und habe dan auf .LEN > X geprüft.

  10. #10
    Bensen83 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    29.08.2009
    Beiträge
    776
    Danke
    25
    Erhielt 3 Danke für 3 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    ich frage im Moment das NDR ab.
    Auf was sollte ich denn .LEN abfragen?
    Also ich weis ja vorher nicht wie lange die Daten sind. Verändert sich .LEN noch, wenn NDR schon ansteht?
    Und kannst du mir vielleicht sagen wie man mehr als 1024 Bytes empfangen kann, bzw. woran man erkennt, dass mehr als 1024 Bytes vom Gegenüber gesendet wurden.

Ähnliche Themen

  1. Wann wird ein Merker im SPS Zyklus gesetzt
    Von Olbrich1983 im Forum Simatic
    Antworten: 13
    Letzter Beitrag: 03.04.2014, 11:42
  2. Antworten: 5
    Letzter Beitrag: 18.08.2009, 14:11
  3. Funktion in einem FC nicht klar
    Von roman79 im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 18.02.2009, 10:03
  4. DB beschreiben in einem Zyklus
    Von Anonymous im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 20.04.2005, 14:04
  5. Archiv Funktion bei einem TP170B
    Von gonzom im Forum HMI
    Antworten: 3
    Letzter Beitrag: 25.03.2004, 11:04

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •