Uhrzeit- und Pausensteuerung Beckhoff

Zuviel Werbung?
-> Hier kostenlos registrieren
Die internen Zähler der Uhren würde ich tatsächlich bei 12 h "überlaufen" lassen, also - wenn man so will - die Minuten-Impulse ab Mitternacht bzw. ab Mittag zählen lassen.
Die Anzahl der Impulse ab Mitternacht, die persistent gespeichert werden, lassen sich relativ leicht ermitteln.
Aber wie kann ich die Anzahl der Impulse aus der aktuellen Zeit ermitteln, um im Anschluss die Differenz bilden zu können?

Gruß
Michi
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Funktionsbaustein den ich dafür verwende berücksichtigt die Sommer-und Winterzeit
Hmmm, dann hätten wir uns den Umweg über Winter-/Sommer-Zeit-Umschaltung eigentlich schenken können/müssen.
Wenn ich die Beschreibung richtig deute, kann ein "Jitter", also ein Schwanken um den tatsächlichen Wert herum, auftreten.
Um wie viel kann die gelieferte Zeit normalerweise nachgehen bzw. vorgehen?
Wahrscheinlich sollten wir die Weitergabe von Minuten-Impulsen ein wenig "abkoppeln". Immerhin können wir die Uhren nicht rückwärts laufen lassen, sondern müssen uns mit u.U. sehr vielen "EhrenRunden" behelfen, die aber nicht unnötig durch kleine, kurzzeitige Abweichungen angeleiert werden sollten.
 
Hmmm, dann hätten wir uns den Umweg über Winter-/Sommer-Zeit-Umschaltung eigentlich schenken können/müssen.
Die Impulse müssen doch trotzdem gesetzt werden, oder nicht? Ich vergleiche lediglich mein errechnetes mit dem aktuellen Datum und gebe dann die Impulse/ keine Impulse an die Uhren weiter.
Um wie viel kann die gelieferte Zeit normalerweise nachgehen bzw. vorgehen?
Diese Frage kann ich dir jetzt nicht beantworten.
 
Moin MichiJa,

habe nochmal "gebastelt". Aber - wie immer - nicht getestet:

Code:
//-> TYPE Uhr :
//->     STRUCT
//->         iAnzg         : INT  ; // für aUhr[iIdx].iAnzg
//->         iDiff         : INT  ; // für aUhr[iIdx].iDiff
//->         bPuls         : BOOL ; // für aUhr[iIdx].bPuls
//->     END_STRUCT
//-> END_TYPE

VAR_OUTPUT
    obUhr01Step  : BOOL ;
    obUhr02Step  : BOOL ;
//  u.s.w. ...
    obUhr19Step  : BOOL ;
    obUhr20Step  : BOOL ;
END_VAR

VAR
    aiAnzg           : ARRAY[1..20] OF INT  ; // "Ersatz" für aUhr[iIdx].iAnzg [min]
    aiDiff           : ARRAY[1..20] OF INT  ; // "Ersatz" für aUhr[iIdx].iDiff -60..659 [min]
    abPuls           : ARRAY[1..20] OF BOOL ; // "Ersatz" für aUhr[iIdx].bPuls
//->     aUhr             : ARRAY[0..20] OF Uhr ; // ersetzt aiAnzg[] und aiDiff[] und abPuls[]

    tbAusgTakt       : BOOL ; // 0,5 Hz-Takt für Ansteuerung der Uhren

    dtSollAnzgSec    : DT   ; // HilfsVariable für den eingelesenen Datums+Zeit-Wert [s]

    iAnfMin          : INT  := -60 ; // "Konstante" max. 60 Minuten-Impulse unterdrücken
    iIdxMaxUhr       : INT  :=  20 ; // "Konstante" Index letzte Uhr
    iIdxMinUhr       : INT  :=   1 ; // "Konstante" Index erste Uhr
    iSollAnzg        : INT  ; // aus DATE_AND_TIME extrahierte Zeit "00:00" .. "11:59" [min]
    iIdx             : INT  ; // LaufVariable (Array-Index)

    sbAusgTaktZuvo   : BOOL ; // static, für FlankenErkennung AusgabeTakt
    siSollAnzgZuvo   : INT  ; // static, für FlankenErkennung Zeit (hh:mm)
END_VAR

dtSollAnzgSec := ??? ; // <===<<< eingelesene Zeit mit Datum [s] (DT, DATE and TIME)

iIdxMinUhr :=   1 ; // Index für erste Uhr
iIdxMaxUhr :=  20 ; // Index für letzte Uhr

iAnfMin    := -60 ; // AnfangsWert für iDiff z.B. -60..659, d.h. max 60 min warten statt Ehrenrunden ausgeben

iSollAnzg  := DT_TO_INT ( ( dtSollAnzgSec / 60 ) MOD 720 ) ; // [min] begrenzt auf "00:00" .. "11:59"

// - - - < im MinutenTakt Abweichungen ermitteln und weitergeben > - - -
IF NOT siSollAnzgZuvo AND iSollAnzg THEN
    FOR iIdx := iIdxMinUhr TO iIdxMaxUhr DO
        IF NOT bPuls[iIdx] THEN // Anzahl Minuten-Impulse -60..659
//->         IF NOT aUhr[iIdx].bPuls THEN // Anzahl Minuten-Impulse -60..659                   // ersetzt vorherige Zeile
            iDiff[iIdx] := ( iSollAnzg - iAnzg[iIdx] - iAnfMin ) MOD 720 + iAnfMin ;
//->             aUhr[iIdx].iDiff := ( iSollAnzg - iAnzg[iIdx] - iAnfMin ) MOD 720 + iAnfMin ; // ersetzt vorherige Zeile
        END_IF ;
    END_FOR ;
END_IF ;
siSollAnzgZuvo := iSollAnzg ; // FlankenVariable aktualisieren

// - - - < im BlinkTakt (0,5 Hz) Pulse ausgeben > - - -
tbAusgTakt := ( dtSollAnzgSec MOD 2 ) = 0 ;
IF NOT sbAusgTaktZuvo XOR tbAusgTakt THEN // keine AusgTaktFlanke
    ; // nix
ELSIF tbAusgTakt THEN // pos. AusgTaktFlanke
    FOR iIdx := iIdxMinUhr TO iIdxMaxUhr DO
        IF iDiff[iIdx] > 0 THEN
//->         IF aUhr[iIdx].iDiff > 0 THEN                       // ersetzt vorherige Zeile
            bPuls[iIdx] := TRUE ; // Puls starten
//->             aUhr[iIdx].bPuls := TRUE ; // Puls starten     // ersetzt vorherige Zeile
        END_IF ;
    END_FOR ;
    sbAusgTaktZuvo := tbAusgTakt ; // Flanken-"Merker" aktualisieren
ELSE // neg. AusgTaktFlanke
    FOR iIdx := iIdxMinUhr TO iIdxMaxUhr DO
        IF bPuls[iIdx] THEN // wenn PulsAusgabe für diese Uhr aktiv ist, dann ...
//->         IF aUhr[iIdx].bPuls THEN // wenn PulsAusgabe für diese Uhr aktiv ist, dann ...          // ersetzt vorherige Zeile
            iDiff[iIdx] := iDiff[iIdx] - 1 ; // Soll-Impulse dekrementieren
//->             aUhr[iIdx].iDiff := aUhr[iIdx].iDiff - 1 ; // Soll-Impulse dekrementieren           // ersetzt vorherige Zeile
            iAnzg[iIdx] := ( iAnzg[iIdx] + 1 ) MOD 720 ; // AnzeigeWert aktualisieren
//->             aUhr[iIdx].iAnzg := ( aUhr[iIdx].iAnzg + 1 ) MOD 720 ; // AnzeigeWert aktualisieren // ersetzt vorherige Zeile
            bPuls[iIdx] := FALSE ; // und Puls beenden
//->             aUhr[iIdx].bPuls := FALSE ; // und Puls beenden                                     // ersetzt vorherige Zeile
        END_IF ;
    END_FOR ;
    sbAusgTaktZuvo := tbAusgTakt ; // Flanken-"Merker" aktualisieren
END_IF ;

// - - - < Ausgabe der Minuten-Impulse an die Peripherie > - - -
obUhr01Step := bPuls[1] ;
//-> obUhr01Step := aUhr[1].bPuls ;  // ersetzt vorherige Zeile
obUhr02Step := bPuls[2] ;
//-> obUhr02Step := aUhr[2].bPuls ;  // ersetzt vorherige Zeile
//
// u.s.w. ...
//
obUhr19Step := bPuls[19] ;
//-> obUhr19Step := aUhr[19].bPuls ; // ersetzt vorherige Zeile
obUhr20Step := bPuls[20] ;
//-> obUhr20Step := aUhr[20].bPuls ; // ersetzt vorherige Zeile

Habe für die n Uhren ein Array of Struct bzw. wahlweise drei Arrays (2x INT und 1x BOOL) angedacht mit den "Zeilen" 1..n (konkret 1..20) eingeführt, damit jede angeschlossene Uhr "individuell" angesteuert werden kann.
Die Zeilen, die für die Version "Array of Struct" gemeint sind, sind allesamt "auskommentiert" und beginnen mit "//->".
Werden diese aktiviert, dann muss normalerweise die Zeile direkt davor entfallen bzw. auskommentiert werden.
Ausnahmen:
Bei der TypDefinition (ganz am Anfang) entfällt nichts.
Bei der Deklaration der "normalen" Arrays entfallen alle drei, wenn die Deklaration von aUhr[] aktiviert wird.

Häwenaissuiikend! Gruss, Heinileini

PS:
Wie steht es eigentlich mit ...
Mein Problem ist nun die Programmierung der Sirenen.
Ist das noch akut/aktuell?
 
Zuletzt bearbeitet:
Zurück
Oben