Systemzeit der CPU setzen

siemek

Level-1
Beiträge
24
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich hänge momentan ein wenig in der Luft. Vllt könnt ihr mir nen denkanstoß verpassen.

Ich versuche gerade Krampfhaft die Systemzeit meiner CPU einzustellen. Über den SFC0 mit direkter vorgabe des Datums und der Uhrzeit KEIN Problem.
Jetzt will ich aber Tag, Monat, Jahr, Stunde und Minute separat über das Panel eingeben können. Meinen "ersten" entwurf mit den Grundfunktionen seht
ihr am Ende der Nachricht.

Mein Problem schein so wie ich es meine folgendes zu sein:

ArZeitSchreiben AT ZeitSchreiben : ARRAY[0..7] OF BYTE;
.
.
ArZeitSchreiben[0] := INT_TO_BCD(Jahr);
ArZeitSchreiben[1] := INT_TO_BCD(Monat);
.
.
.

Diese beiden Variablentypen (BCD und BYTE) Vertragen sich nicht (Ungültiger Datentyp). Mit der INT Zahl die ich im Panel eingebe kann ich über INT_TO_BYTE nur die Zahlen von 1 bis 8 bzw. dann 16 für 10 verwenden ,
da ja das BCD Format erwartet wird, und sich ab da iwann unterscheidet.
Jetzt hab ich schon ein wenig gegoogelt und finde leider keine Möglichkeit wie ich den sch... so zu konvertieren, dass ich ihn rüberschreiben kann.

Ich hoffe ihr könnt mir da weiter helfen!

Code:
FUNCTION_BLOCK FB350

VAR
    ZeitGelesen                         :   DATE_AND_TIME;
    ZeitSchreiben                       :   DATE_AND_TIME;
    
    ArZeitSchreiben AT ZeitSchreiben    :   ARRAY[0..7] OF BYTE;
    
    FreigabeLesen                       :   BOOL;
    FreigabeLesenAlt                    :   BOOL;    
    FreigabeSchreiben                   :   BOOL;
    FreigabeSchreibenAlt                :   BOOL;
        
    Tag                                 :   INT;
    Monat                               :   INT;
    Jahr                                :   INT;
    Stunde                              :   INT;
    Minute                              :   INT;
    Sekunde                             :   INT;
    
    FehlerLesen                         :   INT;
    FehlerSchreiben                     :   INT;
    

END_VAR

    IF(FreigabeLesen AND NOT FreigabeLesenAlt) THEN
        FehlerLesen := READ_CLK(CDT := ZeitGelesen);
    END_IF;
    
    IF(FreigabeSchreiben AND NOT FreigabeSchreibenAlt) THEN
        IF Monat < 1 THEN
            Monat := 1;
        END_IF;
        
        IF Monat > 12 THEN
            Monat := 12;
        END_IF;
        
        //IF Jahr < 2012 THEN
        //    Jahr := 2012;
        //END_IF;
                
        CASE Monat OF
            01, 03, 05, 07, 08, 10, 12:     //JANUAR, März, Mai,  ...
            IF(Tag > 31) THEN
                Tag := 31;
            END_IF;
            IF(Tag < 1) THEN
                Tag := 1;
            END_IF;
            
            02:     //Februar
            IF( NOT (((Jahr MOD 4) = 0) AND ((Jahr MOD 100) <> 0) AND ((Jahr MOD 400) = 0))) THEN
                IF(Monat = 2 AND Tag > 28) THEN
                    Tag := 28;
                END_IF;
            ELSIF(Tag > 28) THEN
                Tag := 28;
            END_IF;
            IF(Tag < 1) THEN
                Tag := 1;
            END_IF;
            
            04, 06, 09, 11:     //April, Rest
            IF(Tag > 30) THEN
                Tag := 30;
            END_IF;
            IF(Tag < 1) THEN
                Tag := 1;
            END_IF;
            
        END_CASE;
        
        ArZeitSchreiben[0] := INT_TO_BCD(Jahr);
        ArZeitSchreiben[1] := INT_TO_BCD(Monat);
        ArZeitSchreiben[2] := INT_TO_BCD(Tag);
        ArZeitSchreiben[3] := INT_TO_BCD(Stunde);
        ArZeitSchreiben[4] := INT_TO_BCD(Minute);
        ArZeitSchreiben[5] := INT_TO_BCD(Sekunde);
        
        FehlerSchreiben := SET_CLK( PDT := ZeitSchreiben);
                
    END_IF;    
            
    FreigabeSchreibenAlt    := FreigabeSchreiben;
    FreigabeLesenAlt        := FreigabeLesen;
    
    ;
END_FUNCTION_BLOCK
 
Hallo,
wenn ich es richtig verstanden habe dann geht es dir um diesen Zeile (n) :
Code:
 ArZeitSchreiben[0] := [COLOR=#FF0000][B]int_to_Byte([/B][/COLOR]INT_TO_BCD(Jahr)[B][COLOR=#FF0000])[/COLOR][/B];

Ansonsten müßte es passen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja genau. Da irgendwo muss ich meine INT Zahl ins BCD konvertieren und dann halt in der Variable ZeitSchreiben "speichern". Nur halt die Konvertierung an sich macht mir irgendwie die Probleme, da BCD nicht im BYTE gespeichert werden kann.
Und auf BYTE bin ich ja angewiesen, da bei DATE_AND_TIME im ersten BYTE ja Tag im zweiten Monat ... usw. gesichert werden.

Dein roter Zusatz funktioniert... bei allen Zahlen die im BCD vorkommen. Bei allen anderen bekomm ich einen Fehler aus dem SFC0 (SET_CLK) zurück weils halt ohne BCD nicht funktioniert.
 
Hallo,
du mußt natürlich auch schauen, ob (und wie) dein jeweiliger Wert in die Bytes hinein muss.
Bei Jahr bin ich mir z.B. sicher, dass du nur die letzen beiden Stellen desselben verwenden darfst (also : Jahr mod 100).
Wo ich mich nicht so sicher bin ist die Sache mit dem Wochentag. Es kann sein, dass der Wochentag auch zu dem Datum passen muss (wie gesagt, ich bin mir da jetzt nicht sicher).

Wo genau hängt es denn jetzt bei dir ?

Gruß
Larry
 
Erstmal schon vielen Dank

Bei mir hängt es momentan am beschreiben der einzelnen Bytes im DATE_AND_TIME Format (DT#1995-02-02-08:30:01.999). Ich weiß nicht wie ich das "einfach" nach BCD wandeln kann und dann auch noch in ein Byte schreibe.
Byte Inhalt Bereich
0 Jahr 1990.....2069
1 Monat 1....12
2 Tag 1....31
3 Stunde 0...23
4 Minute 0....59
5 Sekunde 0....59
6 MSD v. ms 00...99
7(MSB) LSV v. ms 0....9
7(LSB) Wochentag 1....7 (1 = Sonntag)

Meine momentane Idee wäre es einfach eine Switch-Case-Anweisung dafür zu schreiben. Aber das finde ich persönlich nicht so schön (weil mindestens 31 Möglichkeiten). Die Sache mit Wochentag und Datum würde ich für mich als irrelevant betrachten da ich über das "normale" DATE_AND_TIME auch nicht am Wochentag rumwerkel ich denke das ist eine "interne Panel Geschichte".
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Code:
        ArZeitSchreiben[0] := WORD_TO_BYTE(INT_TO_BCD(Jahr));
        ArZeitSchreiben[1] := WORD_TO_BYTE(INT_TO_BCD(Monat));
        ArZeitSchreiben[2] := WORD_TO_BYTE(INT_TO_BCD(Tag));
        ArZeitSchreiben[3] := WORD_TO_BYTE(INT_TO_BCD(Stunde));
        ArZeitSchreiben[4] := WORD_TO_BYTE(INT_TO_BCD(Minute));
        ArZeitSchreiben[5] := WORD_TO_BYTE(INT_TO_BCD(Sekunde));
        
        FehlerSchreiben := SET_CLK( PDT := ZeitSchreiben);

Gruss Daniel
 
Hier ein Vorschlag zum Umwandeln von int auf Byte (um danach als Pointer darauf zuzugreifen):

Code:
      L     "DB_UHR".Jahr    // integer   ( ABER nur 2-stellig:   für 2012 hier nur eine 12 eingeben!!!)
      ITB   
      T     DB51.DBB    2

      L     "DB_UHR".Monat    // integer
      ITB   
      T     DB51.DBB    3

      L     "DB_UHR".Tag    // integer
      ITB   
      T     DB51.DBB    4

      L     "DB_UHR".Stunde    // integer
      ITB   
      T     DB51.DBB    5

      L     "DB_UHR".Minute    // integer
      ITB   
      T     DB51.DBB    6

      L     "DB_UHR".Sekunde    // integer
      ITB   
      T     DB51.DBB    7

      CALL  SFC0
       PDT    :=P#DB51.DBX2.0   //DB51 => DB_UHR
       RET_VAL:=#intRET_VAL

lg, Michael
 
Zuletzt bearbeitet:
Hallo und ein frohes Neues :),

So endlich von meinen zahlreichen Montagen zurück und habe dann endlich wieder ein wenig Zeit für die Sachen nebenher.
Zu meinem Problem:
Alles viel einfacher :) Wie gedacht. Man muss nur einmal bissle überlegen (und nen Azubi an die Aufgabe setzen ^^).

Und zwar läuft das ganze wie folgt:

ScreenShot011.jpg

In dem Bild auf dem HMI legt man sich mindestens das Feld an welches man ändern will (ich beschreibe es hier mal mit dem Tag).
Dieser wird als Byte und im Darstellungsformat Hexadezimal (da das Format Variablen intern als BCD verarbeitet wird) eingestellt.

In der Steuerung kann man jetzt einen FB anlegen und in diesem dann per MOVE Funktion den Wert des Bytes in eine DATE_AND_TIME Variable schreiben/schieben.

ScreenShot001.jpg

Im Anschluss dann das Ganze per SFC0 in der Steuerung aktualisieren und TADA :)

Man muss nicht mehr den ganzen scheiss im DATE_AND_TIME Format in der Steuerung eingeben sondern kann auch mal nur einzelne Werte abändern!

Damit wäre mein Problem gelöst :)

Danke für die vielen Tipps!

das ganze in SCL werde ich auch iwann noch mal versuchen und posten :) aber mti der FUP Lösung kann ich leben
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Siemek,

ich habe mir auch schon einmal einen Kopf zum Einstellen der Sys-Zeit gemacht. Das komplette DTL einknibbeln war mir zu müssig.
Momentan musst du ja immer noch das knibbelige eingeben der Zahl durchführen.

Meine aktuelle Lösung ist allerdings, das ich lediglich die einzelnen Werte per Buttons verändere. Also z.B. Stunden, Minuten und Sekunden.

Gruß, Voxe
 
stimmt auch wieder :-.) muss ich mal die werte vorher in die uhrzeit einlesen zb. mit der bildnummer arbeiten... wenn dieses bild in wincc flex geladen wird einmal die jeweiligen werte in die felder laden (die wo jetzt 00 drinne steht)
dann brauchste auch nur das verändern was gerade interessiert
 
Hehe, musst du nicht.

Ich habe das DTL als komplettes E-A Feld gemacht. Wer das komplett ändern will, ok. Dazu ein paar Buttons drum rum.
Die S7 wertet die Buttons und beschreibt das DTL neu.

Gruß
 
Zum Beispiel einen Button über und unter den Tag. Der eine Button erhöht den Tag um 1, der andere verringert den Wert um 1.
Damit kann man alles einstellen. In SCL habe ich mir eine Funktion zur Umsetzung geschrieben. Die wird halt mit verschiedenen Parametern in SCL aufgerufen.
 
Zurück
Oben