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

Ergebnis 1 bis 4 von 4

Thema: Probleme mit FC

  1. #1
    Registriert seit
    10.08.2010
    Beiträge
    770
    Danke
    1
    Erhielt 14 Danke für 13 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo

    habe mal eine Grundlegende Frage zu den FC s

    Ich habe einen FC mit dem ich Sonnenaufgang und Sonnenuntergang berechne. Damit der FC nicht Permanent den Algorithmus durchläuft habe ich eine In Out variable wann der Letzte Tag der Berechnung war. Soweit funktioniert der Baustein auch.

    Wenn ich die CPU Stoppe und wieder Starte bekomme ich im DB wo sich die Werte befinden den Zeitwert 00:00:00.000 . Im Speicher steht aber noch der Letzte Tag. Erst bei Tageswechsel wird wieder Berechnet.

    Ligt das an der In_Out Variable SP_BERECHNUNG_TAG ?

    Code:
    (*****************************************************************************************************************************************************)
    FUNCTION SUN_TIME:VOID
    TITLE = 'Berechnung Sonnenzeiten'
    (*****************************************************************************************************************************************************)
    // Benötigte Bausteine
    // FC131 UHRZEIT
    
    
    VAR_INPUT
        Aktuelle_Zeit                 :TOD;
        JahresTag                     :INT; // Jahres Tages Nummer
        Zeitzone                      :TIME;//
        geographische_Lange           :REAL;// Länge von Stadt Sandberg ist 10
        geographische_Breite          :REAL;// Breitengrad von Stadt Sandberg ist 50.35
        Daemmerung                    :INT; // 0=geometrische Dämerung, 1=bürgerlicher Dämmerung,2=nautische Dämmerung, 3=Astro Dämerung
    END_VAR
    
    VAR_OUTPUT
        Aufgang                       :TOD;
        Untergang                     :TOD;
        Tag                           :BOOL;
        Nacht                         :BOOL;
        SonnenStunden                 :TOD;
    END_VAR
    
    VAR_IN_OUT
        SP_BERECHNUNG_TAG             :INT; // Speicher letzte Berechnung TagesNummer
    END_VAR
        
    VAR_TEMP
            
        TEMP_INT                      :INT;
        AKT_DT                        :DT;
        DT_TIME                       :DT;
        AKT_DATE                      :DATE;
        Jahr_anfang_DATE              :DATE;
        i2                            :INT;
        i3                            :INT;
        Timer1                        :TOD;
        YEAR                          :INT;
        WOZ                           :REAL;
        MOZ                           :REAL;
        T                             :REAL;
        Pi                            :REAL;
        Aufgang_Ortszeit              :REAL;
        Untergang_Ortszeit            :REAL;
        Zeitgleichung                 :REAL;
        Deklination                   :REAL;
        Zeitdifferenz                 :REAL;
        B                             :REAL;
        h                             :REAL;
        D                             :REAL;
               
        END_VAR
     
     BEGIN
     
             
      IF SP_BERECHNUNG_TAG <> JahresTag THEN           
    // Berechnung ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
       Pi :=3.14159265359; // Pi
       
    // Horizonthöhe Dämmerung  
        CASE Daemmerung OF
            0 : D:=-0.833;
            1 : D:=-6    ;
            2 : D:=-12   ;
            3 : D:=-18   ;
         ELSE:
            D:=-0.833    ;
        END_CASE;
     
       T:=INT_TO_REAL (JahresTag);
       B:= Pi *geographische_Breite / 180 ;
       h:=D /57.29578;
       Zeitgleichung := -0.171*SIN(0.0337 * T + 0.465) - 0.1299*SIN(0.01787 * T - 0.168); 
       Deklination := 0.4095*SIN(0.016906*(T-80.086)) ;
       Zeitdifferenz := 12.0*ACOS((SIN(h) - SIN(B)*SIN(Deklination)) / (COS(B)*COS(Deklination)))/Pi;
    
       Aufgang_Ortszeit := 12.0 - Zeitdifferenz - Zeitgleichung;
       Untergang_Ortszeit := 12.0 + Zeitdifferenz - Zeitgleichung;
       
       Aufgang:=(DINT_TO_TOD (REAL_TO_DINT   ((Aufgang_Ortszeit - (geographische_Lange /15.0) ) *3600000)))+Zeitzone;
       Untergang:=(DINT_TO_TOD (REAL_TO_DINT   ((Untergang_Ortszeit - (geographische_Lange /15.0) ) *3600000)))+Zeitzone;
       
       SonnenStunden:=DINT_TO_TOD (TOD_TO_DINT (Untergang)-TOD_TO_DINT (Aufgang));
       
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      // Speicher wann letzte berechnung war  
       SP_BERECHNUNG_TAG := JahresTag;  
       
    END_IF;
       
       // Abfrage Tag oder Nacht 
       IF Aktuelle_Zeit > Aufgang AND Aktuelle_Zeit < Untergang THEN
          TAG:=TRUE;
          NACHT:=FALSE;
       ELSE
          TAG:=FALSE;
          NACHT:=TRUE;
       END_IF;      
    
                  
     END_FUNCTION
    Zitieren Zitieren Probleme mit FC  

  2. #2
    Registriert seit
    06.10.2003
    Beiträge
    3.411
    Danke
    451
    Erhielt 505 Danke für 408 Beiträge

    Standard

    Hallo Emilio,

    meinen Respekt wenn's funktioniert! Die Ausgänge einer FC müssen immer zyklisch beschrieben werden. Mache aus den Ausgängen IN_OUTs oder aus der FC einen FB.


    Gruß, Onkel
    Es gibt viel mehr Leute, die freiwillig aufgeben, als solche, die echt scheitern.
    Henry Ford

  3. #3
    Registriert seit
    10.08.2010
    Beiträge
    770
    Danke
    1
    Erhielt 14 Danke für 13 Beiträge

    Standard

    Habe jetzt erst mal im OB 100 den Speicher Wert auf 0 gesetzt.

    Ja das Programm funktioniert. Man benötigt allerdiengs diesen Baustein für die Zeiten usw.

    Ist deine meinung nach der Aufbau Ok oder zu umständlich ?

    Code:
    (*****************************************************************************************************************************************************)
    DATA_BLOCK AKTUELLE_ZEIT
    (*****************************************************************************************************************************************************)
    
        STRUCT
              
        DatumUhrzeit                          :DT;
        DatumUhrzeit_set                      :DT;
        Datum                                 :DATE;
        Lokalzeit                             :TOD;
        UTC                                   :TOD;
        UTC_Zeitzone                          :TIME:=T#1H;// Berlin
        Zeitzone                              :TIME:=T#1H; //Lokalzeit +1 Winterzeit
        Jahr                                  :INT;
        Jahres_Tag                            :INT;
        Monat                                 :INT;
        Monats_Tag                            :INT;
        Wochen_Tag                            :INT;
        Stunde                                :INT;
        Minute                                :INT;
        Sekunde                               :INT;
        Umstellungs_Sommerzeit                :DT;
        Umstellungs_Winterzeit                :DT;
        Sommerzeit                            :BOOL;
        Winterzeit                            :BOOL;
        P_Sommerzeit                          :BOOL;
        P_Winterzeit                          :BOOL;
        Edge_flag_pos1                        :BOOL;
        Edge_flag_pos2                        :BOOL;  
        HMI_Uhr_Stellen                       :BOOL;
        SOMMER_TO_WINTER                      :BOOL;    
                
        END_STRUCT
    BEGIN
     
    
    END_DATA_BLOCK
    
    
    FUNCTION UHRZEITEN : VOID
    
    VAR_TEMP
        
        TEMP_INT                      :INT;
        TEMP_SFC0                     :INT;
        AKT_DT                        :DT;
        DT_TIME                       :DT;
        DT_TIME1                      :DT;
        Umstellung_Time               :TIME;
    
        Jahr_anfang_DATE              :DATE;
        Timer1                        :TOD;
        TAG_Sommerzeit                :INT;
        TAG_Winterzeit                :INT;
            
        AT_AKT_DT AT AKT_DT:
                  STRUCT 
                    JAHR             : BYTE;
                    MONAT            : BYTE;
                    TAG              : BYTE;
                    STUNDE           : BYTE;
                    MINUTE           : BYTE;
                    SEKUNDE          : BYTE;
                    MS_MSD           : BYTE;                          
                    MS_LSD           : BYTE;
                END_STRUCT;
                
         AT_DT_TIME AT DT_TIME:
                 STRUCT 
                    JAHR             : BYTE;
                    MONAT            : BYTE;
                    TAG              : BYTE;
                    STUNDE           : BYTE;
                    MINUTE           : BYTE;
                    SEKUNDE          : BYTE;
                    MS_MSD           : BYTE;                          
                    MS_LSD           : BYTE;
                END_STRUCT;
        
        AT_DT_TIME1 AT DT_TIME1:
                 STRUCT 
                    JAHR             : BYTE;
                    MONAT            : BYTE;
                    TAG              : BYTE;
                    STUNDE           : BYTE;
                    MINUTE           : BYTE;
                    SEKUNDE          : BYTE;
                    MS_MSD           : BYTE;                          
                    MS_LSD           : BYTE;
                 END_STRUCT;
            
                
                
           
           
    
    END_VAR
    
        BEGIN
        
        // Uhr Manuell Stellen
        IF AKTUELLE_ZEIT.HMI_Uhr_Stellen THEN    
           TEMP_SFC0:=SET_CLK(PDT :=AKTUELLE_ZEIT.DatumUhrzeit_set);
           AKTUELLE_ZEIT.HMI_Uhr_Stellen:=False;
        END_IF;
    
            
        // Aktuelle Systemzeit lesen
        TEMP_INT := READ_CLK(CDT := AKT_DT);
        
        // Aktuelles Datum
        AKTUELLE_ZEIT.Datum :=DT_DATE(IN :=AKT_DT); 
        
        // Datum und Zeit in DB verschieben
        AKTUELLE_ZEIT.DatumUhrzeit :=AKT_DT;
        
        // Lokalzeit Berechnen
        AKTUELLE_ZEIT.Lokalzeit:=DT_TOD(IN :=AKT_DT); 
    
        
        // Jahr in DB verschieben
        AKTUELLE_ZEIT.Jahr:=BCD_TO_INT (AT_AKT_DT.JAHR);   
            
        // Jahrestag Berechnen und in DB verschieben
        Jahr_anfang_DATE:=D#2010-01-01;
        DT_TIME:=D_TOD_DT(IN1 :=Jahr_anfang_DATE,IN2 := Timer1);                   // Jahres anfang auslesen und in DT umwandeln T=Platzhalter
        AT_DT_TIME.JAHR  := AT_AKT_DT.JAHR;                                        // Aktuelle Jahreszahl in AT Sicht Jahr schreiben
        Jahr_anfang_DATE  :=DT_DATE(IN :=DT_TIME);     
        AKTUELLE_ZEIT.Jahres_Tag:=DINT_TO_INT (DATE_TO_DINT (AKTUELLE_ZEIT.Datum) - DATE_TO_DINT (Jahr_anfang_DATE))+1;
        
        // Monat in DB verschieben
        AKTUELLE_ZEIT.Monat:=BCD_TO_INT (AT_AKT_DT.MONAT);
        
        // Monats Tag in DB verschieben
        AKTUELLE_ZEIT.Monats_Tag:=BCD_TO_INT (AT_AKT_DT.TAG);
    
        // Wochentag in DB verschieben
        AKTUELLE_ZEIT.Wochen_Tag :=DT_DAY(IN :=AKT_DT);
        
        // Stunde in DB verschieben
        AKTUELLE_ZEIT.Stunde:=BCD_TO_INT  (AT_AKT_DT.STUNDE);
    
        // Minute in DB verschieben
        AKTUELLE_ZEIT.Minute:=BCD_TO_INT (AT_AKT_DT.MINUTE);
        
        // Sekunde in DB verschieben
        AKTUELLE_ZEIT.Sekunde:=BCD_TO_INT (AT_AKT_DT.SEKUNDE);
        
           
        // Berechnung der UmstellungsTag Sommerzeit
        DT_TIME1:=DT#2013-03-31-02:00:00.000;// Achtung Datum muss immer ein Sonntag sein sonst fehler in der Berechnung der Zeit
        AT_DT_TIME1.JAHR:=WORD_TO_BYTE(INT_TO_BCD (AKTUELLE_ZEIT.Jahr));
        TAG_Sommerzeit:=31 -((AKTUELLE_ZEIT.Jahr + 5 + (AKTUELLE_ZEIT.Jahr/4)) MOD 7);
        AT_DT_TIME1.TAG:=WORD_TO_BYTE(INT_TO_BCD (TAG_Sommerzeit));
        AKTUELLE_ZEIT.Umstellungs_Sommerzeit:=DT_TIME1;
        
        // Berechnung der UmstellungsTag Winterzeit
        DT_TIME:=DT#2013-10-27-03:00:00.0; // Achtung Datum muss immer ein Sonntag sein sonst fehler in der Berechnung der Zeit
        AT_DT_TIME.JAHR:=WORD_TO_BYTE(INT_TO_BCD (AKTUELLE_ZEIT.Jahr));
        TAG_Winterzeit:=31 -((AKTUELLE_ZEIT.Jahr + 2 + (AKTUELLE_ZEIT.Jahr/4)) MOD 7);
        AT_DT_TIME.TAG:=WORD_TO_BYTE(INT_TO_BCD (TAG_Winterzeit));
        AKTUELLE_ZEIT.Umstellungs_Winterzeit:=DT_TIME;
        
        // Umstellung von Sommer auf Winterzeit von 3:00 auf 2:00 Uhr. Nach umstellung Bit von 2:00 bis 3:00 Uhr setzten damit Zeit nicht wieder auf Sommerzeit springt  
        AKTUELLE_ZEIT.SOMMER_TO_WINTER:=AKTUELLE_ZEIT.Winterzeit AND (AKT_DT > AKTUELLE_ZEIT.Umstellungs_Winterzeit+-T#1H AND AKT_DT < AKTUELLE_ZEIT.Umstellungs_Winterzeit);
         
        
         //  Sommerzeit 
        IF (AKT_DT>AKTUELLE_ZEIT.Umstellungs_Sommerzeit AND AKT_DT < AKTUELLE_ZEIT.Umstellungs_Winterzeit) AND NOT AKTUELLE_ZEIT.SOMMER_TO_WINTER THEN
           AKTUELLE_ZEIT.Sommerzeit:=TRUE;
           AKTUELLE_ZEIT.Winterzeit:=FALSE;
           AKTUELLE_ZEIT.Zeitzone:=AKTUELLE_ZEIT.UTC_Zeitzone+T#1H;
           Umstellung_Time:=T#1h;
        ELSE // Winterzeit
           AKTUELLE_ZEIT.Sommerzeit:=FALSE;
           AKTUELLE_ZEIT.Winterzeit:=TRUE; 
           AKTUELLE_ZEIT.Zeitzone:=AKTUELLE_ZEIT.UTC_Zeitzone;
           Umstellung_Time:=T#23h;
                                        
        END_IF;
        
        // Flankenmerker   
        //Bildung der positiven Flanke  //get the positive pulse
         AKTUELLE_ZEIT.P_Sommerzeit  := AKTUELLE_ZEIT.Sommerzeit AND NOT AKTUELLE_ZEIT.Edge_flag_pos1;
         AKTUELLE_ZEIT.Edge_flag_pos1   := AKTUELLE_ZEIT.Sommerzeit;
         
         AKTUELLE_ZEIT.P_Winterzeit  := AKTUELLE_ZEIT.Winterzeit AND NOT AKTUELLE_ZEIT.Edge_flag_pos2;
         AKTUELLE_ZEIT.Edge_flag_pos2   := AKTUELLE_ZEIT.Winterzeit;
    
       
        // Uhr Umstellung Sommer Winterzeit
        IF AKTUELLE_ZEIT.P_Sommerzeit OR AKTUELLE_ZEIT.P_Winterzeit THEN
           AKTUELLE_ZEIT.Lokalzeit:=AKTUELLE_ZEIT.Lokalzeit+Umstellung_Time;
           AKTUELLE_ZEIT.DatumUhrzeit:=D_TOD_DT(IN1 :=AKTUELLE_ZEIT.Datum,IN2 := AKTUELLE_ZEIT.Lokalzeit);
           TEMP_SFC0:=SET_CLK(PDT :=AKTUELLE_ZEIT.DatumUhrzeit); 
        END_IF ; 
         
         //UTC Berechnen
          AKTUELLE_ZEIT.UTC:=AKTUELLE_ZEIT.Lokalzeit +- AKTUELLE_ZEIT.Zeitzone;
    
        
                
              
        
           
           END_FUNCTION
    Geändert von emilio20 (25.03.2013 um 23:54 Uhr)

  4. #4
    Registriert seit
    17.07.2009
    Ort
    Am Rande der Ostalb
    Beiträge
    5.480
    Danke
    1.141
    Erhielt 1.242 Danke für 973 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Deine Berechnung wird ja nur einmal am Tag ausgeführt.
    Beim Neustart der CPU am gleichen Tag findet keine Berechnung mehr statt und deine Parameter bleiben auf 0.
    Du kannst im OB100 dein Datenwort für SP_BERECHNUNG_TAG mal auf -1 setzen.
    Damit wird die Berechnung bei Neustart durchgeführt.

    Gruß
    Dieter

Ähnliche Themen

  1. Antworten: 9
    Letzter Beitrag: 28.02.2013, 19:02
  2. Probleme mit KL2541 und CX9010 mit NC-Runtime
    Von maximb im Forum CODESYS und IEC61131
    Antworten: 1
    Letzter Beitrag: 28.11.2012, 15:37
  3. Antworten: 13
    Letzter Beitrag: 12.11.2012, 15:42
  4. KL2541 - Probleme mit Referenzfahrt, fahren ohne NC, nur mit SPS
    Von PraktikantMarkus im Forum CODESYS und IEC61131
    Antworten: 0
    Letzter Beitrag: 16.03.2012, 15:38
  5. Antworten: 3
    Letzter Beitrag: 12.07.2007, 09:49

Lesezeichen

Berechtigungen

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