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

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: SCL: Problem beim Vergleich von zwei Datenwerten

  1. #1
    Registriert seit
    23.09.2010
    Beiträge
    19
    Danke
    11
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Guten Tag,

    ich versuche zur Zeit einen Baustein in SCL zu programmieren, den ich in Verbindung mit dem CountOh nutzen will.
    Der CountOh berechnet die Betriebsstunden für das aktuelle Jahr. Ich benötige aber diesen Wert auch für das letzte Jahr...

    Beispiel:
    2013: aktuell 200h (Ende des Jahres 480h)
    2012: 500h

    ---
    2014: aktuell 100h
    2013: 480h

    etc.

    Dieser Wert von dem aktuellen Jahr (OhActualYear) soll an jedem neuen Jahr am 1.1. um 00:00 Uhr in ein Variable Namens OhLastYear gespeichert werden.

    Ich habe bis jetzt so einiges programmiert, nur irgendwie klappt der Vergleich nicht, das, wenn die aktuelle Zeit größer als die Vergleichszeit ist, dass er den Wert von OhActualYear nach OhLastYear schreibt und den OhActualYear auf 0 setzt.

    Code:
    FUNCTION_BLOCK FB1111
    TITLE ='Speichert die Betriebsstunden aus dem letzten Jahr'
    NAME:'SaveOpH'
    AUTHOR:'Lukic'
    FAMILY:'TIME'
    VERSION: '1.0'
    
    
    
    
    // Typical-Attribute
    {
      S7_m_c:='true';
      S7_blockview:='big'
    }
    
    
    //Input: From Block CountOh
    VAR_INPUT  
        Days:       INT;
        Hours:      INT;
        Minutes:    INT; 
        ActDateTime: DATE_AND_TIME;
    END_VAR
    
    
    //Output
    VAR_OUTPUT
        //Operating hours of the actual year
        OhActualYear: REAL;    
        //Operating hours of the last year
        OhLastYear:   REAL;    
        //Date to save the operating hours to OhLastYear and reset OhActualYear
        CmpDate: DATE_AND_TIME;
        gr : BOOL;
    END_VAR
    
    
    VAR
        CmpDateTime: DATE_AND_TIME;
        arrayCmpDateTime AT CmpDateTime:
           STRUCT
            Jahr: Byte;
            Monat: BYTE;
            Tag: BYTE;
            Stunde: BYTE;
            Minute: BYTE;
            Sekunde: BYTE;
            MS_UND_WDAY: WORD;
        END_STRUCT;  
        
        DateTime: DATE_AND_TIME;
        arrayDateTime AT DateTime:
        STRUCT
            Jahr: Byte;
            Monat: BYTE;
            Tag: BYTE;
            Stunde: BYTE;
            Minute: BYTE;
            Sekunde: BYTE;
            MS_UND_WDAY: WORD;
       END_STRUCT;  
        
           thisYear:INT;
           tYear:INT;  
    END_VAR
    
    
    BEGIN
    
    
    tYear:=READ_CLK(CDT :=DateTime); 
    
    
    //Working Hours of the actual year
    OhActualYear:=(Days*24)+Hours+(INT_TO_REAL(Minutes)/60);
    
    
    thisYear:=BCD_TO_INT(arrayDateTime.Jahr);
    //next Year
    arrayCmpDateTime.Jahr := INT_TO_BYTE(thisYear+1);
    CmpDate:=CmpDateTime;
    
    
    gr:=GE_DT(DT1 := actDateTime,DT2 := CmpDate); // BOOL
    
    
    ;
        
    END_FUNCTION_BLOCK
    Der Code ist noch nicht vollständig. Bis jetzt will ich nur anhand einer Hilfsvariablen namens "gr" testen, ob der Vergleich funktioniert.
    Und das tut er nicht.

    Also mache ich irgendwas falsch.

    Oder kann man das ganze Problem deutlich einfacher verwirklichen?
    Zitieren Zitieren SCL: Problem beim Vergleich von zwei Datenwerten  

  2. #2
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.840
    Danke
    400
    Erhielt 2.427 Danke für 2.023 Beiträge

    Standard

    Hallo,
    was funktioniert denn nicht so, wie gewünscht ?
    Ich kenne jetzt den von dir verwendeten Baustein (GE_DT) nicht vom eigenen benutzen - für mich steht aber das GE in der Namens-Bezeichnung für "Greater or Equal" also "größer oder gleich".
    Je nachdem, wierum die beiden Operanden (DT1 und DT2) verglichen werden würdest du m.E. immer ein "TRUE" oder immer ein "FALSE" erhalten.

    Wegen vereinfachen : es läßt sich alles immer anders machen. Dein Ansatz ist aber so doch erstmal nicht verkehrt ...

    Gruß
    Larry

  3. #3
    Registriert seit
    23.09.2010
    Beiträge
    19
    Danke
    11
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hallo,

    mein Problem ist, dass beide Zeitwerte (aktuelle Zeit und Vergleichszeit) korrekt dargestellt werden, der Baustein GE_DT (du hast richtig vermutet, es ist ein greater or equal-Baustein) bei den zwei Zeitwerten aber nicht den korrekten Bool'schen Wert wiedergibt.

    Ich hatte die aktuelle Zeit mal Testweise auch an einen Ausgangspin übergeben, so dass ich mit dem Eingang "ActDateTime" irgendeinen Wert am Input zuweisen konnte, der an den Ausgang "OutActDateTime" übergeben wurde.

    Diesen "OutActDateTime" Ausgang und den "CmpDate" Ausgang hatte ich sogar testweise an den GE_DT händisch verschaltet. An den DT1 habe ich den OutActDateTime und an den DT2 den CmpDate-Pin verschaltet.

    Nun hatte ich folgende Werte getestet:

    OutActDateTime: 12-06-25-00:00:00 (so in etwa war die Schreibweise; stellt das Datum 25.06.2012 dar)
    CmpDate: 13-01-01-00:00:00 (-> 01.01.2013)

    Am GE_DT-Ausgang wurde (korrekt) eine 0 ausgegeben.

    Nun habe ich den OutActDateTime-Wert auf 14-06-25-00:00:00 (-> 25.06.2014) verändert und den CmpDate-Wert bei 01.01.2013 belassen.

    Der Ausgang von GE_DT hat sich nicht auf 1 geändert.


    Also stimmt irgendwas nicht mit der Übergabe oder der Variablendeklaration in meinem Quellcode.

  4. #4
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.293
    Danke
    543
    Erhielt 2.714 Danke für 1.961 Beiträge

    Standard

    Bei mir sieht die AT-Ansicht so aus:


    Code:
       datDate: DATE_AND_TIME;
       atdatDate AT datDate : STRUCT
                                 Jahr: BYTE;
                                 Monat: BYTE;
                                 Tag: BYTE;
                                 Stunde: BYTE;
                                 Minute: BYTE;
                                 Sekunde: BYTE;
                                 MSBLSB: BYTE;
                              END_STRUCT;
    MSBLSB ist ein Byte, nicht ein Word, wie in deinem Code. Vielleicht liegt es daran?
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  5. #5
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.840
    Danke
    400
    Erhielt 2.427 Danke für 2.023 Beiträge

    Standard

    @Ralle:
    Das ist zwar nicht schön, was der TE da mit dem Ding gemacht hat - stimmt aber. Bei dir fehlt noch ein Byte (das Millisekunden Teil 3 + Wochentag) in der Struct - Millisekunden sind 1,5 Byte und der Wochentag 0,5 Byte - also insgesamt ein WORD.

    Gruß
    Larry

  6. #6
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.840
    Danke
    400
    Erhielt 2.427 Danke für 2.023 Beiträge

    Standard

    @TE:
    was mir noch so aufgefallen ist :
    wo wird das CmpDatTime ("CmpDate:=CmpDateTime;") sinnvoll aufgefüllt ?
    Du beschreibst zwar das Jahr davon in der AT-Sicht, den Rest aber nicht und ggf. ist der restliche Inhalt nicht sinnvoll ...

    Gruß
    Larry

  7. #7
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.293
    Danke
    543
    Erhielt 2.714 Danke für 1.961 Beiträge

    Standard

    @Larry
    Du hast Recht, bei mir fehlt das letzte Byte mit LSB der Sekunden und dem Tag.
    Aber die AT-Ansicht funktioniert in meinem Programm trotzdem.
    Gut zu wissen, aber dann ist das leider nicht der Fehler im Programm des TE!
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  8. #8
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.496
    Danke
    933
    Erhielt 3.377 Danke für 2.731 Beiträge

    Standard

    Ich schätze, bei Deinen Tests hast Du irgendeine DT-Variable manipuliert, aber eine andere DT-Variable mit CmpDate verglichen. Oder OutActDateTime ein unzulässig formatiertes DT zugewiesen ...

    Unabhängig davon würde ich aber ein anderes Vorgehen vorschlagen. Falls die SPS-Uhr irgendwie synchronisiert oder verstellt wird und/oder die SPS zu Neujahr 0:00 Uhr gar nicht eingeschaltet ist, kann es zu fehlerhafter/mehrfacher Ausführung Deiner Datenübernahme als Vorjahresdaten kommen.

    Ich würde mir nur merken, wann das letzte Mal die Betriebsstunden als Vorjahresdaten umkopiert wurden - es reicht, sich die Jahreszahl zu merken. Unterscheidet sich die Jahreszahl (BYTE) des aktuellen Datums von der gemerkten Jahreszahl, dann die Betriebsstunden kopieren und die Jahreszahl des aktuellen Datums in den Jahresmerker kopieren.

    Etwa so:
    Code:
    IF ActualDate.Jahr <> lastSavedYear AND ActualDate.Monat = 1 THEN
      lastSavedYear := ActualDate.Jahr ;
      OhLastYear := OhActualYear ;
      OhActualYear := 0.0 ;
    END_IF ;
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  9. #9
    Registriert seit
    23.09.2010
    Beiträge
    19
    Danke
    11
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Zitat Zitat von Larry Laffer Beitrag anzeigen
    @TE:
    was mir noch so aufgefallen ist :
    wo wird das CmpDatTime ("CmpDate:=CmpDateTime;") sinnvoll aufgefüllt ?
    Du beschreibst zwar das Jahr davon in der AT-Sicht, den Rest aber nicht und ggf. ist der restliche Inhalt nicht sinnvoll ...

    Gruß
    Larry
    Hallo,

    in wiefern sinnvoll? Verstehe es nicht so ganz. Ich habe das Jahr des Arrays "arrayCmpDateTime" einfach um 1 erhöht, so dass das nächste Jahr reingeschrieben wird.

    Jetzt stellt sich mir nur die Frage, weil ich bei dem ganzen vorhaben in das Array nur das Jahr beschreibe, wie es mit den Monaten und Tagen ausschaut. Im CFC-Editor (arbeite ja mit PCS7) zeigt mir der Ausgang bei der Simulation z.B. den 01.01.2014 an. So will ich es auch. Nur könnte es evtl. sein, dass der 1.1 als Standardwert angezeigt wird, wenn der Inhalt nicht in Ordnung ist?

    @PN/DP:
    Der Ansatz ist nicht schlecht. Nur irgendwie müsste es auch mit dem Baustein GE_DT funtionieren. Zumindest funkioniert es, wenn ich die Zeiten und den Baustein mittels PCS7 simuliere. Also nicht meinen selbstgeschriebenen Baustein nehme.

    @Ralle:
    Danke für die Mühe. Den Aufbau des Structs hatte ich irgendwo (ich glaube sogar hier im Forum) gefunden.

  10. #10
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.840
    Danke
    400
    Erhielt 2.427 Danke für 2.023 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    @TE:
    Ich denke, dass die DATE-Darstellung das automatisch macht, da sie sich auf den Tag bezieht (Anzahl der Tage, die seit dem 01.01.1990 vergangen sind). In deinem Fall wäre aber die Datum-Zuweisung (und darauf wollte ich dich hinweisen) ggf. der 00.00.2014 - und das kann ggf. nicht verglichen werden.
    Deshalb hatte ich die auf die Zuweisung des CmpDateTime hingewiesen. Vielleicht checkst du das noch einmal gegen.

    Gruß
    Larry

Ähnliche Themen

  1. Antworten: 18
    Letzter Beitrag: 16.05.2013, 15:11
  2. Pointer Vergleich AWL -> SCL??
    Von Carsten77 im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 16.08.2011, 14:21
  3. Vergleich von zwei Programmen "TOOL"
    Von Rdata im Forum Simatic
    Antworten: 14
    Letzter Beitrag: 29.08.2008, 15:22
  4. Vergleich AWl <--> SCL
    Von nobug im Forum Programmierstrategien
    Antworten: 6
    Letzter Beitrag: 11.03.2008, 20:11
  5. Antworten: 9
    Letzter Beitrag: 16.12.2007, 21:20

Lesezeichen

Berechtigungen

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