# Wasseruhr mit CPU 314C-2 DP



## chefren_new (10 September 2009)

Hallo Leute

möchte gerne einen Wasserdurchflusszähler an meiner CPU 314C-2 DP anschliessen. Leider habe ich keine Ahnung wie das geht und was ich brauche.
Einen Durchflusszähler habe ich im Internet gefunden der 80 Impulse in der Minute liefert.
Wie kann ich das abgreifen? die Auswertung muss ja sehr schnell gehen.
Kann mir jemand Tipp geben wie ich da vorgehen kann.

DANKE


Gruß


----------



## online (10 September 2009)

80 Impulse in der Minute kann ja nur die Maximale anzahl sein. Du musst auch wissen, wieviele impulse pro was? (zB. 1 Imp = 1L oder 10 Imp = 1 m³) 
Dann nimmst du deinen Eingang der SPS wo der Impuls drauf verdrahtet ist, und legst ihn im Programm am besten auf einen Addierer (EN). Den Addierer würde ich mit einem Doppelwort belegen und dann immer um 1 hochzählen lassen.
Dann kannst du noch das Doppelwort Skalieren indem du z.B. bei 1 Imp/L
duch 1000 Teilst um m³ ausgegeben zu bekommen.


----------



## tschortscho51 (10 September 2009)

Die CPU 314C hat die Systemfunktion "Frequenzmessen" mit SFB48.
Im Handbuch Technologiefunktionen sind die Sonderfunktionen der CPU beschrieben.


----------



## DerTheo (13 September 2009)

Die Impule über einen Frequenzmesser , entweder Integriert bei den 3xxC-Modellen oder als externe Hardware, ist der sicherste Weg.
Wir haben schon viel Ärger mit dem Zählen über normale Eingänge bekommen, wenn z.B. die Impulse kürzer als die Zykluszeit sind. Da experimentierten wir mit Impulsverlängerungsrelais u.ä.


----------



## Paule (13 September 2009)

DerTheo schrieb:


> Die Impule über einen Frequenzmesser , entweder Integriert bei den 3xxC-Modellen oder als externe Hardware, ist der sicherste Weg.
> Wir haben schon viel Ärger mit dem Zählen über normale Eingänge bekommen, wenn z.B. die Impulse kürzer als die Zykluszeit sind. Da experimentierten wir mit Impulsverlängerungsrelais u.ä.


Also bei 80 Impulse pro Minute komme ich auf 1,3 Impulse pro Sekunde.
Das sollte die CPU ja wohl noch können! *ROFL* 
Und von der Funktion:
Genauso wie es online beschrieben hat.
Nur als Ergänzung > Mit dem Eingang eine Flanke bilden.


----------



## PN/DP (13 September 2009)

*Zählimpuls zu kurz*

Hallo,

das Problem bei der Impulszählung von Wasseruhren ist nicht die Frequenz, sondern das Tastverhältnis der 
Impulse. Bei vielen Wasseruhren ist der 1-Impuls nur 1...10ms lang, also kürzer als die Zykluszeit.

Bei hochwertigen Wasserzählern kann die Impulslänge oft auf größere Werte (z.B. 100ms) parametriert werden.

Wenn das nicht geht, gibt es ein paar Möglichkeiten, die Impulse sicher zu erfassen

CPU mit Prozessalarm-fähigen integrierten Digitaleingängen, z.B. CPU 31xC
*Bei CPU 314C-2DP können alle 24 Digitaleingänge Prozessalarm auslösen*
Digitaleingabebaugruppe mit Prozessalarm, z.B. 6ES7321-7BH01-0AB0 (16 Eingänge)
CPU mit integrierten schnellen Zählereingängen, z.B. CPU 31xC
   Die CPU 314C-2DP hat 4 Zählerkanäle.
schnelle Zählerbaugruppen, z.B. FM 350-2 6ES7350-2AH01-0AE0 (8 Kanäle)
externe Impulsverlängerungs-Elektronik, z.B. Murr MIB 6652320, Sabo SUM.350.XX, 
   Phoenix Contact UEGM-OE/AV-24DC/24DC/100, Weidmüller DKZA 35 24VDC 150MS (802211), 
   Weidmüller DKZ DK5 24VDC 0.1-1S (824378), Weidmüller MCZ TO 24VDC/150MS (828641),
   Rinck Electronic IPL4, ATR DM3/DM4, Koralewski IPF-3.1K, MP-Sensor MP-IV2, Beckhoff KL1232
S7-200 als Vorzähler, über MPI an die S7-300-CPU gekoppelt
   Hier kann die S7-300 mehrere Minuten in STOP sein und trotzdem geht kein Zählimpuls verloren.
   Bei ganz kurzen Impulsen < 1ms kann bei S7-200-CPU auch noch "Impulsabgriff" aktiviert werden.

Gruß
PN/DP


----------



## chefren_new (16 September 2009)

Hallo 

Danke für die rasche Antwort.

möchte die Wasseruhr gerne mit meiner 314c mit dem schnellen Zählereingan realisieren.

Wie könnte da ein Programmbeispiel aussehen ( FUP ) kann mir jemand helfen.

DANKE


----------



## Paul (16 September 2009)

Hallo

U E0.0                  //Zählimpuls
FP M10.0              //Flankenmerker 
SPBN m001           //Springe nicht zu m001
L 10                     // z.B bei 10 Liter/Imp
L db1.dbd0           //Istwert Zähler
+I                       //draufaddieren
T db1.dbd0           //gibt neuen Istwert
m001: Nop0          //Sprungmarke

Machs in AWL in FUP werden selbst so simple Sachen wie dies unübersichtlich.

MfG
Paul


----------



## chefren_new (16 September 2009)

Hallo

Danke für die Hilfe
AWL kann ich aber nicht richtig lesen, hat jemand das ganze in FUP
bin ganz neu in diesem Bereich.

möchte die Werte für jeden Tag und das ganze 30 Tage Speichern wie kann man so etwas machen. Einen Werte Tag für Tag speichern? eventuell den Werte z.B  450 Liter inkl. Datum

kann jemand eine Beispiel in FUP.


DANKE


Gruß


----------



## PN/DP (16 September 2009)

*schneller zählen als die Zykluszeit*

Impulse an einem Digitaleingang im normalen OB1-Zyklus zählen geht wegen der sehr kurzen Zählimpulse ja gerade nicht.


chefren_new schrieb:


> möchte die Wasseruhr gerne mit meiner 314c mit dem schnellen Zählereingan realisieren.



Du mußt in der Hardware-Konfig der CPU314C *einen Zähler-Kanal auf Endlos-Zählen* parametrieren.
Dann im Programm den Zählerstand des Kanals auslesen. Wenn er sich gegenüber dem Zählerstand
vom letzten OB1-Zyklus geändert hat, dann die Differenz zum vorherigen Zählerstand auf Deinen
eigentlichen Impulszähler aufaddieren. Aber nicht im 1.OB1-Zyklus bei STOP->RUN !

S7-300 CPU 31xC Technologische Funktionen (CPU 312C, CPU 313C, CPU 314C)
SIMATIC S7-300 CPU 31xC und CPU 31x: Technische Daten

Ich finde, daß die Variante mit dem *Prozessalarm* wesentlich einfacher und sicherer zu programmieren ist. 
In der Hardware-Konfig der CPU einstellen, welcher Eingang bei welcher Flanke Prozessalarm auslösen soll. 
Dann im OB40 Deinen Impulszähler incrementieren.
Allerdings wirst Du um AWL nicht herumkommen.

Sorry, für ein fertiges Programmbeispiel habe ich gerade keine Zeit.

Gruß
PN/DP


----------



## Paul (16 September 2009)

@PN/DP
Ich finde, daß die Variante mit dem *Prozessalarm* wesentlich einfacher und sicherer zu programmieren ist. 
In der Hardware-Konfig der CPU einstellen, welcher Eingang bei welcher Flanke Prozessalarm auslösen soll. 
Dann im OB40 Deinen Impulszähler incrementieren.
Allerdings wirst Du um AWL nicht herumkommen.

Die Zykluszeit ist hier, denke ich, nicht das Problem.
Der Junge muss doch erstmal lernen wie zwei Werte einfach addiert werden.

Ich schau mal ob ich in FUP was einfaches hier einstellen kann, dauert aber ein bisschen, weil erstmal Besprechung angesagt ist.

MfG
Paul


----------



## PN/DP (16 September 2009)

*nicht einfache, sondern schnelle Zählung*

Moin Paul,



PN/DP schrieb:


> das Problem bei der Impulszählung von Wasseruhren ist nicht die Frequenz, sondern das Tastverhältnis der
> Impulse. Bei vielen Wasseruhren ist der 1-Impuls nur 1...10ms lang, also kürzer als die Zykluszeit.



chefren_new hat sich nun so entschieden:


chefren_new schrieb:


> möchte die Wasseruhr gerne mit meiner 314c mit dem schnellen Zählereingan realisieren.



Gruß
PN/DP


----------



## Paul (16 September 2009)

@PN/DP
chefren_new hat sich nun so entschieden:

Na ok
Schauen wir mal ob wir ihn da durchführen können


----------



## Paule (16 September 2009)

Paul;216994Na ok
Schauen wir mal ob wir ihn da durchführen können[/quote schrieb:
			
		

> Also das ist ja jetzt nicht so das Problem.
> Das einzige komplizierte ist da wohl das richtig Alarmbit aus dem OB40 Stack rauszusuchen.
> 
> 
> ...


----------



## PN/DP (16 September 2009)

*FUP-Beispiel*

*Paule* ist aber schnell...

@ chefren_new

Schau mal in das Datenblatt Deines Wasserzählers, wie lang der Zählimpuls ist.

Wenn der Zählimpuls länger als Deine Zykluszeit ist, dann kannst Du im normalen 
OB1-Programm so zählen:

```
M124.0
       +-----+   +--------+                M124.0 Flankenmerker
       |  P  |   | ADD_DI |
E124.0-|     |---|EN      |                E124.0 Zähleingang
       +-----+   |        |
       DB10.DBD0-|IN1  OUT|-DB10.DBD0      DB10.DBD0 Zähler (DINT)
                 |        |
             L#1-|IN2  ENO|-
                 +--------+
```

Wenn der Zählimpuls kürzer als Deine Zykluszeit ist, dann MUSST Du entweder einen 
schnellen Zähler-Kanal auf Endlos-Zählen parametrieren oder der SPS-Eingang muß 
einen Prozessalarm auslösen, z.B. nur bei steigender Flanke.

Wenn dieser Eingang die *einzige Prozessalarm-Quelle* ist, dann kannst Du einfach 
im *OB40* programmieren:

```
+--------+
          | ADD_DI |
      ...-|EN      |
          |        |
DB10.DBD0-|IN1  OUT|-DB10.DBD0
          |        |
      L#1-|IN2  ENO|-
          +--------+
```

Wenn es *mehrere Prozessalarm-Quellen* gibt, dann wird es komplizierter.


Paule schrieb:


> Das einzige komplizierte ist da wohl das richtig Alarmbit aus dem OB40 Stack rauszusuchen.


Es muß im OB40 zuerst festgestellt werden, welcher Eingang den Prozessalarm 
ausgelöst hat. (siehe auch Onlinehilfe zum OB40)
Das geht dann aber wirklich nur noch in AWL vernünftig.

Gruß
PN/DP


----------



## PN/DP (16 September 2009)

*OB40 Beispiel*

Hier jetzt der komplette OB40-Code (allerdings nicht getestet)
wenn E124.0 nur bei steigender Flanke einen Prozessalarm auslöst:

```
//OB40
//prüfen, ob E124.0 den Prozessalarm ausgelöst hat
      L     #OB40_IO_FLAG
      L     B#16#54                     //Eingangsbaugruppe PE...
      <>I   
      SPB   ENDE

      L     #OB40_MDL_ADDR
      L     124                         //PEW124
      <>I   
      SPB   ENDE

      L     #OB40_POINT_ADDR
      UD    DW#16#1                     //00000000_00000000_00000000_00000001 = E124.0
      SPZ   ENDE

//E124.0 hat den Alarm ausgelöst
//Wasserzähler um 1 Einheit erhöhen
      L     DB10.DBD    0               //alter Zählerstand
      +     L#1                         //Zähleinheit addieren
      L     L#1_000_000_000             //max Zählumfang
      MOD                               //Wrap zu 0
      T     DB10.DBD    0               //neuer Zählerstand

ENDE: NOP   0
```
Der Zähler zählt einfach nur die Impulse vom Wasserzähler.
Der Zählerstand muß für eine Anzeige noch mit der Volumeneinheit/Impuls 
multipliziert werden. Oder gleich im OB40 statt 1 einen anderen Faktor addieren.

Oft sind die Volumeneinheiten/Impuls glatte 10-er Potenzen, z.B. 10l/Imp.
Dann muß man sich nur irgendwo ein Dezimalkomma in den Zählerstand reindenken.
Beispiel:
10l/Imp und Komma 2 Stellen von hinten einfügen -> Anzeige 1234,56 m³

Gruß
PN/DP


----------



## chefren_new (16 September 2009)

Hallo

Danke für die Bemühungen

mein Durchflusszähler:
80 Impulse / Liter
Durchsatz 0,5-50 Liter/Min 

Es sollte für jeden Tag die Liter gespiechert werden und das 30 Tage,
also man sollte immer einen Rückblick von 30 Tage  haben.

Gruß


----------



## PN/DP (16 September 2009)

*Tagesverbräuche einen Monat lang speichern*

Also bei max 50 Liter/Minute und 80 Impulsen/Liter müssen die Tagesdurchsätze als DINT
oder REAL gespeichert werden.
1 Tag = 1440 Minuten * 50 l/Minute = 72.000 l/Tag * 80 Imp/l = 5.760.000 Imp/Tag

Ich würde den Impulszähler endlos laufen lassen (NICHT um Mitternacht auf 0 setzen).
Bei einem Zählumfang von 0 bis 999.999.999 ist ca. 1x im Jahr mit einem Wrap zu rechnen.
(Zähler springt von 999.999.999 zu 0, Tages-Differenz wird dann negativ!)

*Tagesverbräuche einen Monat lang speichern*

DB mit den Tagesdurchsätzen und Hilfsvariablen anlegen

```
//Pseudocode!
STRUCT
Tagesdurchsatz       : ARRAY[1..31] OF DINT ; //Tagesdurchsätze je Kalendertag in Liter
Zaehlerstand_gestern : DINT ;                 //Zählerstand gestern um 23:59 Uhr
Tag_gestern          : BYTE ;                 //Datum.Tag beim letzten Speichern
END_STRUCT ;
```
Es wird kein Zeitstempel gespeichert, der Tag des Monats ist der Index in das Array!

Immer um Mitternacht (für's Index-Rechnen besser um 23:59 Uhr) oder anderer fester Zeitpunkt
folgender Ablauf in Pseudocode:

```
* Datum/Uhrzeit als DATE_AND_TIME mit SFC1 "READ_CLK" in #Temp_DuT lesen
  LAR1 P##Temp_DuT
  Tag_jetzt    := LB [AR1, P#2.0] (in BCD!) und mit BTI zu 1..31dez wandeln
  Stunde_jetzt := LB [AR1, P#3.0] (in BCD!)
  Minute_jetzt := LB [AR1, P#4.0] (in BCD!)
* Ist es 23:59 Uhr? (Stunde_jetzt == B#16#23 AND Minute_jetzt == B#16#59)
  AND Heute noch nicht gespeichert? (Tag_jetzt <> DB.Tag_gestern)
* OK, um 23:59 Uhr 1x Tagesverbrauch speichern
    * DB.Tag_gestern := Tag_jetzt //damit nur 1x gespeichert wird
    * Tagesdurchsatz[Tag_jetzt] //in Liter// := (Zählerstand_jetzt - DB.Zählerstand_gestern) / 80
      falls (Zählerstand_jetzt - DB.Zählerstand_gestern) negativ, dann 1.000.000.000 addieren
      falls Liter-Bruchteile exakt gerundet werden sollen, dann in REAL rechnen
    * DB.Zaehlerstand_gestern := Zählerstand_jetzt
```

Die CPU-Uhr sollte mit einer geeichten Uhr synchronisiert werden, z.B. mit einem NTP-Server.
Die CPU-Uhr sollte immer auf Winterzeit stehen.

Gruß
PN/DP


----------



## PN/DP (16 September 2009)

*aktueller Tagesdurchsatz*

Soll der aktuelle Tagesdurchsatz (in Liter) seit Mitternacht angezeigt werden:
Tagesdurchsatz_heute in Liter := (Zählerstand_jetzt - DB.Zählerstand_gestern) / 80

Gruß
PN/DP


----------



## chefren_new (17 September 2009)

Hallo

Danke

für eine Programmbeispiel wäre ich sehr dankbar, kann leider die Theorie noch nicht in ein Programm umsetzten, und das ich nur FUP lesen kann macht die Sache nicht einfacher.

wie kann ich 30 Tage speichern, wird das in DBs gemacht die ich mit Wincc Flex auslesen kann?

Gruß


----------



## PN/DP (17 September 2009)

Hallo chefren_new,



chefren_new schrieb:


> wie kann ich 30 Tage speichern, wird das in DBs gemacht die ich mit Wincc Flex auslesen kann?


siehe meinen Programmentwurf in #18


PN/DP schrieb:


> *Tagesverbräuche einen Monat lang speichern*
> 
> DB mit den Tagesdurchsätzen und Hilfsvariablen anlegen


Die Tagesdurchsätze in Liter werden in einem DINT-Array in einem DB gespeichert. 
Die Werte kannst Du in WinCC flexible anzeigen.




chefren_new schrieb:


> für eine Programmbeispiel wäre ich sehr dankbar, kann leider die Theorie noch nicht in ein Programm umsetzten, und das ich nur FUP lesen kann macht die Sache nicht einfacher.


Tja, alles was Du nur noch machen müßtest, wäre, den Pseudocode meines Programmentwurfs 
in meinem Beitrag #18 in ein paar AWL-Zeilen zu übersetzen. (FUP ist dafür völlig ungeeignet)
Vielleicht findet sich jemand hier aus dem Forum, der das auf die Schnelle für Dich macht.

Ich könnte erst heute Abend das AWL-Programm hier reinstellen (komme jetzt nicht dazu).
Hast Du vielleicht eine Wunsch-Nummer für den DB? Welche Nummer soll der FC haben?
Auf welcher Adresse speicherst Du den Zählerstand - DB10.DBD0?
Sollen die Tagesdurchsätze in Liter oder m³ sein? REAL oder DINT? Wieviele Nachkommastellen?

Gruß
PN/DP


----------



## chefren_new (17 September 2009)

Hallo 

Hab keine Wunschnummer für DB und FC
und die Ausgabe sollte in Liter sein.

Vielen Vielen Danke für die Hilfe.



Gruß


----------



## Paul (17 September 2009)

Hallo PN/DP

Respekt vor deinen Programmierkentnissen (Ernsthaft!)
Aber glaubst du nicht das unser CHEFREN_NEW einen Einstieg braucht
der ein paar Level niedriger angesetzt ist als deine Version mit Arrays und Pointern

Sicher ist dein Lösungsweg profihaft gemacht aber ich glaube das Chefren dafür von 
von seinen Kentnissen her noch nicht weit genug ist.

MfG
Paul


----------



## Paul (17 September 2009)

Hallo Chefren
Hast du die Hardware eigentlich schon zur Verfügung, so das du dich 
Schritt für Schritt an die Sache ranarbeiten kannst.

Erstmal testen ob du wirklich die schnellen Eingänge brauchst
Mit einem normalen Eingang ist das für einen Anfänger viel simpler
Dann erstmal das zählen und addieren fertigmachen
Wenn das funzt an das Speichern für 30 Tage gehen

Wenn auf deiner CPU nicht viel anderes Programm läuft und die Zykluszeit
unter 15 mS liegt kommst du mit einem normalen Eingang hin
50L/min * 80 Imp = 4000 Imp/min --> 1 Imp = 15ms

MfG
Paul


----------



## chefren_new (17 September 2009)

Hallo

meine Hardware
314c cpu
Wasseruhr von Actaris Aquadis+ inkl Impulsgeber Cyble Sensor V2
2 Leiter 

Link zu meiner Hardware

http://www.actaris.com/de/index.php?module=actaris&func=viewmedia&idmp=3671


Ich bitte um Hilfe

der Impuls hat doch keine 24V kann ich den an einen DI dran machen?

DANKE


----------



## Paul (17 September 2009)

Hallo
Wenn ich das richtig sehe hast du an deinem Zähler einen Reed Kontakt
d.h. ein potentialfreier Kontakt der durch einen Magnet geschaltet wird.
Wenn du 24V reinschickst kommen auch 24V wieder raus.

Wieviele Impulse liefert das Ding pro Liter????????
Wenn du deine Erfassung nur auf 1 Liter genau brauchst wäre es ein Blödsinn
einen Impulsgeber einzusetzen der 80 Imp/Liter ausgibt.

MfG
Paul


----------



## PN/DP (17 September 2009)

*Anschaltung Sensor an SPS*

Der Cyble Sensor kann 30V/100mA schalten. Der SPS-Eingang braucht 15..30V/9mA.

Beim Sensor mit 2 Adern kommt der weiße Draht an +24V und der braune Draht an 
den SPS-Digitaleingang.

Beim Sensor mit 5 Adern muß der braune Draht an 0V und der weiße Draht an den 
SPS-Digitaleingang. Zusätzlich muß vom SPS-Digitaleingang zu +24V ein 
Widerstand 1,2 bis 1,5kOhm / 0,8 bis 1W gelegt werden. 
Der Eingang hat dann in Ruhe etwa 18V und der Sensor schaltet ihn auf ca. 0,5V.

Gruß
PN/DP


----------



## PN/DP (18 September 2009)

*ein paar Bemerkungen ...*

*Extrem kurze Impulslänge*

Wie Paul im #24 schon ausgerechnet hat, kommt im worst case alle 15ms ein Impuls. 
Das ist aber die *Periodendauer* und darf nicht mit der Impulslänge verwechselt werden.
Der Impuls ist nicht 15ms lang, sondern im Idealfall nur 7,5ms Impuls und 7,5ms Pause
(bei Tastverhältnis 1:1).
In der Realität ist die Impulslänge meist noch kürzer, z.B. ~ 5% (Reed-Kontakt-Äquivalent).
Das wären hier im Beispiel *0,75ms !!!*
Der SPS-Eingang mit dem Zähler muß nicht nur Prozessalarm auslösen, sondern auch die
Eingangsverzögerung muß auf 0,1ms eingestellt werden. Wir sind nun hart an der Grenze dessen,
was die CPU 314-2 DP an Prozessalarmen verarbeiten kann (OB40 Verzögerung ~ 0,5ms)!
Eventuell müßte nun doch der kompliziertere Weg über den schnellen Zählkanal genommen werden.

Gut wäre es gewesen, wenn chefren_new gleich genauere Angaben gemacht hätte, 
Aus 80 Impulsen/Minute im #1 sind nun 4000 Impulse/Minute in #17 geworden. Das ist für die 
Realisierung ein erheblicher Unterschied! Die Problematik der sehr kurzen Impulslänge habe 
ich in diesem Thread schon mehrmals erwähnt. Zuerst in #6
Nur hat das scheinbar nicht jeder gelesen.

Klarheit kann hier nur ein Blick in das Datenblatt des Wasserzählers schaffen (siehe unten).

*Sollte man chefren_new hier mit fertigem "professionellen" Programmcode helfen?*

Ich denke, daß diese spezielle Aufgabe NICHT geeignet ist, chefren_new das simple zählen 
und addieren schonend beizubringen, wenn vorher schon klar ist, daß das Programm dann nicht 
funktionieren wird. chefren_new bekommt vielleicht den richtigen Programmcode hin, wird dann 
aber verzweifelt suchen, warum sein Programm zu wenige Impulse zählt und die Welt nicht mehr 
verstehen. Übrigens findet man den FUP-Code zum einfachen zählen in #15.

Weil das exakte schnelle Zählen für die Aufgabe essentiell ist und nicht im OB1 möglich ist, 
habe ich den eigentlich simplen, für Anfänger aber schwierigen Code des OB40 hier komplett 
programmiert veröffentlicht. #16

Im Übrigen hat chefren_new hier nur geschrieben, daß er geradeso FUP LESEN kann. Was er 
SCHREIBEN (programmieren) kann, hat er nicht erwähnt. Er hat auch nicht erwähnt, ob er 
irgend etwas von den hier gebrachten Programmbeispielen übernommen und ausprobiert hat.

Ich glaube, daß chefren_new das gar nicht selbst programmieren will. Er will sich nicht 
Schritt für Schritt zur Lösung ranarbeiten. Er will das fertige Programm.

Deshalb habe ich seine mehrfach geäußerte Frage nach der Speicherung der Tagesverbräuche 
nur als Programmentwurf in Pseudocode beantwortet. Da stecken alle wichtigen Informationen 
drin für jemanden, der das wirklich programmieren will. #18
Mit wahrscheinlich weniger Zeitaufwand hätte ich das Programm auch gleich in AWL programmieren
und hier reinstellen können. Den AWL-Code hätten aber viel weniger Leser verstanden.

Und in #20 zeigt chefren_new, daß er diesen detaillierten Programmentwurf nicht richtig 
liest oder nicht versteht.

chefren_new möchte die 30-Tage-Durchflüsse in WCCflex anzeigen ...
Falls das eine Trendkurve mit Daten aus der SPS werden soll, so sind da noch bestimmte
Anforderungen seitens WCCflex an die Speicherreihenfolge der Daten zu beachten, d.h. die 
Daten müssen historisch sortiert werden (ältester Wert zuerst).
Falls es eine einfache Auflistung der Daten sein soll, muß womöglich der eigentlich 
überflüssige Datumsstempel mit im Array abgelegt werden. Ich schätze, chefren_new wird 
die Datumsangabe nicht nachträglich in WCCflex errechnen können.


Ich finde nicht, daß mein Programmentwurf mit Array und Pointerzugriff besonders kompliziert 
oder "profihaft" ist. Da kann man sich doch reindenken und alles dazu relevante in der Step7- 
Onlinehilfe und hier im Forum nachlesen. Umständlicher wäre es, kein Array und keine Pointer
zu benutzen (z.B. 31 einzelne Tag-Vergleiche oder Sprungleiste). Der einzige "Trick" in dem 
Programmentwurf: ich brauche keine Flanke (Flanken setze ich stets sparsam ein). 

Ich helfe gern, auch mit fertigen Programmbausteinen. Der Fragesteller muß aber genau 
beschreiben was er braucht, damit ich die freiwillig kostenlose Arbeit nur 1x machen muß.

*@chefren_new*

Ich werde den AWL-Code zu meinem Programmentwurf noch nicht schreiben. Das ist noch zu früh.

Probiere erstmal aus, ob die Erfassung des Zählimpulses mit dem OB40 zuverlässig funktioniert.
Dann melde Dich wieder und erkläre, wie Du die Tagesdurchflüsse in WCCflex anzeigen willst.
Danach richtet sich dann, wie die Tagesdurchflüsse gespeichert werden. Und erst dann kann man 
ein gutes Programm dafür schreiben.


Ich kann mit dem Datenblatt nicht nachvollziehen, wie Du mit dem in #25 genannten Wasserzähler
auf 80 Impulse/Liter kommen willst. Mit Bestellnummer 10424 für DN15...20 kommt man bestenfalls 
auf 10 Impulse/Liter (0,1 Liter/Impuls). Das macht dann bei 50 Liter/Minute 500 Impulse/Minute
und die LF-Impulslänge läge bei etwa *6ms*. Da wären wir wieder im technisch vernünftigen Bereich.

Warum kommst Du hier immer nur mit ungenauen Angaben, wo das wichtigste stets fehlt?
Mußt Du immer erst jemanden fragen der sich auskennt? Eventuell Deinen Instandhaltungstechniker?
Das ist doch keine Schande. Es wäre aber für uns, die Dir helfen wollen, eine riesige Hilfe,
wenn die Aufgabenstellung klarer wäre und wenn wir Dich und Deine Kenntnisse und Fähigkeiten 
besser einschätzen könnten.

Das SPS-Forum mit so vielen idealistischen Mitgliedern ist eine feine Sache, allerdings 
funktioniert das Helfen nur bei konstruktiver *Mitarbeit* der Fragesteller.

Sorry chefren_new, aber das mußte ich loswerden.

Ach ja: Danke dafür, daß Du den 
	

	
	
		
		

		
			





 Button gefunden und benutzt hast.
Sehr viele Fragesteller, deren EP mit "Ich wäre für jede Hilfe dankbar" endet, finden den 
Button komischerweise nicht.

"Ich habe fertig!"

Gruß
PN/DP


----------



## Paul (18 September 2009)

@PN/DP
Wie Paul im #24 schon ausgerechnet hat, kommt im worst case alle 15ms ein Impuls. 
Das ist aber die *Periodendauer* und darf nicht mit der Impulslänge verwechselt werden.
Der Impuls ist nicht 15ms lang, sondern im Idealfall nur 7,5ms Impuls und 7,5ms Pause
(bei Tastverhältnis 1:1).


Du hast recht, sorry da habe ich nicht aufgepasst


----------



## rostiger Nagel (18 September 2009)

Hallo PN/DP,
meiner Meinung nach leistest du hier im Forum eine sehr gute Arbeit,
deine Antworten sind sehr ausführlich und auf hohem Niveau.
Wenn es einmal Rückschläge vom Fragesteller gibt, mach trotzdem
weiter so.
Von mir bekommst du ein extra 
	

	
	
		
		

		
		
	


	




Gruß Helmut


----------



## chefren_new (18 September 2009)

Hallo

ich weis eure Hilfe sehr zu schätzen, und bin echt für alles sehr dankbar.
in diesem Forum wurde mir schon des Öfteren weitergeholfen.

Gruß


----------



## Paul (18 September 2009)

Hallo chefren

Wie ist denn jetzt der Stand der Dinge?
Läuft schon irgendwas, wenigstens ansatzweise, so kommen wir ja nicht weiter.

MfG
Paul


----------



## PN/DP (18 September 2009)

*Fragen-Liste*

Hallo chefren_new,

hast Du den Wasserzähler schon an der SPS angeschlossen? Und den OB40 programmiert?
Nicht vergessen: In der Hardware-Konfig den Prozessalarm bei steigender Flanke aktivieren 
und die Eingangsverzögerung auf 0,1ms einstellen. Die Konfig in die CPU laden.

Bitte probiere aus, ob der Zähler in der SPS (DB10.DBD0) mit Deinem Wasserzähler 
synchron läuft, mindestens 1 Tag lang. Sieh mal zu, daß Du ein paar Minuten lang den 
maximalen Durchfluss erreichst und beobachte den Zählerwert in DB10.DBD0.

Bitte beantworte diese Fragen:

Welche CPU hast Du genau? 6ES7 314-.....-....
Wie hoch ist die Zykluszeit Deines jetzigen Programms ohne Zähler?
An welchem Eingang hast Du den Wasserzähler angeschlossen? E124.0?
Wieviele Impulse/Liter bringt der Wasserzähler tatsächlich?
Welche Version WinCC flexible hast Du?
Welches Panel hast Du? Genauer Typ, am besten Bestellnummer 6AV.........
Wie ist das Panel an die CPU angeschlossen? MPI oder Profibus?
Wie willst Du die 30 Tagesdurchflüsse anzeigen?
   Als Trendkurve? Als einfache Zahlen-Ausgabefelder? Bitte beschreiben.

Je mehr Fragen Du beantwortest, desto genauer können wir Dir dann helfen.
*Du meldest Dich wieder wenn Du Ergebnisse hast, einverstanden?*
(oder wenn was nicht funktioniert)

Gruß
PN/DP


----------



## chefren_new (18 September 2009)

Hallo

hab jetzt folgendes Ergebniss, meine Wasseruhr mach bei jedem Liter ein Impuls,  denn ich einfach an einen Zaehler sende, und setze das Ganze um 23:59 zureuck.
Habe  Stat Variablen Liter_1 bis Liter_30 angelegt die ich in einem DB habe und mit Wincc Flex einfach auslesen kann.

Mein Status
Ich kann jetzt die Lieter fuer einen Tag Zaehlen und in Wincc Flex anzeigen.
Wie kann ich variabel die Ergbniss in die Stat Variablen Liter_1 bis Liter_30 bekommen.

ich moechte mich nochmals fuer eure Geduld bedanken.

Gruss


----------



## Paul (18 September 2009)

Na also, das ist doch schon mal was!

Du hast also in der Deklarationstabelle deines FB´s dreißig Variablen angelegt, 
für die 30 Tage und in einer *(der ersten?) *steht dein aktueller Wert. *Richtig???*
Du übergibst also der Wert des Zählers an den Instanz-DB. *Richtig???*
Du siehst den akutellen Zählwert nicht am Zähler sondern in einem *Datenbaustein Richtig??? *


*Bitte antworte bevor wir weitermachen*


----------



## Modellbahn per SPS (18 September 2009)

PN/DP schrieb:


> Impulse an einem Digitaleingang im normalen OB1-Zyklus zählen geht wegen der sehr kurzen Zählimpulse ja gerade nicht.
> 
> 
> Du mußt in der Hardware-Konfig der CPU314C *einen Zähler-Kanal auf Endlos-Zählen* parametrieren.
> ...






Ich finde diese Idee wohl auch am Sinnvollsten. Jedoch gibt es auch noch in FUB die Möglichkeit so etwas zu realisieren. Du solltest dich deshalb einwenig mit Gegentakt auskennen. Wenn dein Signal der Wasseruhr alle 1.3 Sec kommt bei max. Durchfluss und die Zyklenzeit <10ms ist. Kasst du dir einen Internen Taktgeber selbst machen, er sollte auf die Hälfte deines Taktes also deinen 1.3 Sek eingestellt sein. Das Ganze gliederst du mit einem UND Gleid vor deinen Zähler in deiner SPS. Dadurch das jetzt die Taktung vom Taktgeber kommt und mit deiner Zähluhr per UND Glied verknüpft ist, sollte dein Zähler nun jeden Takt deiner Uhr erkennen. Achte bitte darauf das dies alles in ein FC gehört, wegen der Geschwindigkeit des Zykluses


----------



## Paul (18 September 2009)

@@@@@@@@
Ich finde diese Idee wohl auch am Sinnvollsten. Jedoch gibt es auch noch in FUB die Möglichkeit so etwas zu realisieren. Du solltest dich deshalb einwenig mit Gegentakt auskennen. Wenn dein Signal der Wasseruhr alle 1.3 Sec kommt bei max. Durchfluss und die Zyklenzeit <10ms ist. Kasst du dir einen Internen Taktgeber selbst machen, er sollte auf die Hälfte deines Taktes also deinen 1.3 Sek eingestellt sein. Das Ganze gliederst du mit einem UND Gleid vor deinen Zähler in deiner SPS. Dadurch das jetzt die Taktung vom Taktgeber kommt und mit deiner Zähluhr per UND Glied verknüpft ist, sollte dein Zähler nun jeden Takt deiner Uhr erkennen. Achte bitte darauf das dies alles in ein FC gehört, wegen der Geschwindigkeit des Zykluses 

Hääää  

Sorry verstehe ich nicht


----------



## Paul (18 September 2009)

@Modelbahn per SPS

Das würde bedeuten das der Zählimpuls von der Wasseruhr nur durchkommt
wenn auch dein interner Takt (Gegentakt) gerade <High> ist.
Imulse außerhalb des internen Taktes werden ignoriert.
Wenn der Wasserstrom nur zaghaft läuft und du nur alle 5sec einen Puls bekommst
ist es Zufall ob er erfasst wird oder nicht.

Gegentakt heißt wohl so weil er dagegen arbeitet 

Oder habe ich etwas grundsätzlich nicht kapiert ?????


----------



## PN/DP (18 September 2009)

@ Modellbahn per SPS


Modellbahn per SPS schrieb:


> Ich finde diese Idee wohl auch am Sinnvollsten.


Hääää ?  Welche von den zwei?

Ist aber egal. chefren_new ist schon fast fertig (siehe #34). Das 
Zählproblem ist gelöst, es geht nur noch um das geordnete Ablegen 
der Tagesdurchflüsse in DB-Variablen.

Das Signal von der Wasseruhr kommt nicht alle "1.3 Sec", sondern 
alle 1 Liter. Und das kann im *ungünstigsten* Fall alle 1,2 Sekunden 
sein, es kann aber auch stundenlang gar kein Impuls kommen. 
Lissajous-Figuren funktionieren aber nur bei relativ gleichbleibenden 
Frequenzen. (falls ich Deinen "Gegentakt" richtig interpretiere)

@ Paul
Wenn Ihr dann bei der Tag-abhängigen Adressierung der Stat-Variablen
Liter_1 bis Liter_30 ankommt, da muß kein AR1 verwendet werden. Die 
Indirekte Adressierung gibt es auch speicherindirekt (T DBD[LD0] oder 
T DID[MD0]). Eine SPL mit "Tag" als Index würde sich auch anbieten, 
allerdings nicht in FUP. Oder Du hast eine bessere Idee. 
Ich klinke mich jetzt hier mal aus. chefren_new ist ja auf einem 
erfolgversprechenden Weg.

@ chefren_new
Klasse, Du bist ja schon weit gekommen. Besser, als ich gedacht habe. :-D
Weiter so, Du schaffst das. 
	

	
	
		
		

		
		
	


	




Gruß
PN/DP


----------



## Paul (18 September 2009)

@PN/DP

Mir schwebt da eine wesentlich simplere Lösung vor.
Bei nur 30 Meßwerten ist das locker ohne Adressregister etc. machbar
sondern mit ein paar einfachen Lade- Transferbefehlen,
so das Chefren auch kapiert was er da macht.
Das Problem mit den schnellen Zähleingängen hat sich ja auch von selbst gelöst,
dadurch das er jetzt nur noch 1 Imp/Liter hat.

Ich hoffe nur das der Impuls nicht nur 1 ms lang ist 

Erst mal abwarten wie er die Werte überhaupt dargestellt haben will.

bis später
Paul


----------



## chefren_new (18 September 2009)

Hallo

Ich bekomme jetzt die Liter aus dem Zähler diese möchte ich in einer Stat Varibale ablegen und am nächsten Tag das ganze wieder von vorne, und das 30 Tage. 

In Wincc Flex lese ich die 30 Varibalen einzeln aus.

Meine Problem ist,  wie kann ich z.B.: von meiner Stat Variabele Liter_1 auf Liter_2 wechselen usw.

? kann man den Namen einer Variable zusammenbauen? also Liter_ (1-30) variabel?

ich bitte um einen Tipp 

Gruß


----------



## Paul (18 September 2009)

@Chefren
Ich bekomme jetzt die Liter aus dem Zähler diese möchte ich in einer Stat Varibale ablegen und am nächsten Tag das ganze wieder von vorne, und das 30 Tage. 

Das mit den 30 Tagen haben wir jetzt langsam schon kapiert!!!!!!!!!!!!!!!!!!!

Steht dein aktueller Zählwert jetzt in einem *Datenwort* *ja oder nein?*
Wenn *<Ja>* in welchem DB und in welchem Datenwort *????*

Wenn *<Nein>* warum nicht? Das ist unbedingt erforderlich. Frag nach wenn du nicht weißt wie du das da reinkriegst

In welchem DB und Datenwort steht dein Aktualwert 
Wie lauten die Adressen für die Tage 1-30
Wir brauchen das wenn wir das weiterschieben sollen

MfG
Paul


----------



## chefren_new (19 September 2009)

Hallo

der aktuelle Zaehler liegt als INT vor. Die Variablen sind in meinem FB2 unter STAT deklariert. und um OB1 wird der FB2 aufgeruffen und mit DB64 verknuepft.

Ich verarbeite die Liter aus meinem Zaehler noch weiter, hab ja das Problem das der Zaehler nur bis 999 geht un ich ueber 1000 brauche.
Das funtioniert und ich bekommen Liter_1 als INT. 
nur kann ich leider noch nicht, wenn ich Mitternacht den Zaehler ruecksetzte in z.B.: Liter_2  usw. die neue Anzahl der Liter ablegen.

Gruss


----------



## PN/DP (19 September 2009)

*FUP-Beispiele Zähler, Tagesdurchfluss und 30-Tage-Liste*

Hallo chefren_new,

bevor Du Dein letztes Problem mit dem Ablegen der Tagesdurchflüsse in die 30-Tage-Liste
löst, solltest Du Dir noch einmal Gedanken über Dein Programmdesign machen.
Designfehler später ausmerzen macht einige Arbeit.

Du hast einen maximalen Durchfluss von 50 Liter/Minute, also mußt Du damit rechnen,
daß der Tagesdurchfluss maximal 72.000 Liter betragen kann. Das passt nun nicht mehr 
in einen INT. Also nimm gleich *DINT*. Deswegen wird Dein Programm NICHT komplizierter.

Den Zählerstand täglich um Mitternacht auf 0 zurücksetzen halte ich für keine gute Idee 
(die echte Wasseruhr stellt sich auch nicht täglich zurück). Laß doch den Zählerstand 
weiterlaufen und merke Dir nur den Zählerstand um Mitternacht. Der Tagesdurchfluss ist 
dann einfach die Differenz zwischen dem Zählerstand Heute_Mitternacht und dem gestern 
um Mitternacht gemerkten Zählerstand_Gestern.
Mit dem weiterlaufenden Zähler kannst Du besser kontrollieren, ob der Zähler in der CPU 
langfristig mit der Wasseruhr synchron läuft und nicht doch Zählimpulse verloren gehen.

Beispiel für einen Zähler, der bei 1.000.000.000 auf 0 springt

```
M124.0                        E124.0 Zähleingang
       +-----+   +--------+           M124.0 Flankenmerker
       |  P  |   | ADD_DI |           DB10.DBD0 Zähler (DINT)
E124.0-|     |---|EN      |
       +-----+   |        |
       DB10.DBD0-|IN1  OUT|-DB10.DBD0 +--------+
                 |        |           | MOD_DI |
             L#1-|IN2  ENO|-----------|EN      |
                 +--------+           |        |
                            DB10.DBD0-|IN1  OUT|-DB10.DBD0
                                      |        |
                         L#1000000000-|IN2  ENO|-
                                      +--------+
```

Den Zähler und die 30-Tage-Liste würde ich NICHT in einem Instanz-DB speichern (STAT), 
sondern in einem ganz normalen Global-DB, den ich später nicht mehr verändere. 
Wenn Du später mal in Deinem FB2 Variablen hinzufügst, dann muß der Instanz-DB neu erzeugt 
und in die CPU geladen werden. Die Werte im Zähler und in der 30-Tage-Liste sind dann weg 
(alle wieder 0).


Verstehe ich Dich richtig, daß Du in WCCflexible Deine 30-Tage-Durchfluss-Liste etwa so
anzeigen willst?

```
vor 30 Tagen        (Datum - 30 )  99999 l
...                                  ...
vor 3 Tagen         (Datum - 3  )  99999 l
Vorgestern          (Datum - 2  )  99999 l
Gestern             (Datum - 1  )  99999 l
Heute seit 0:00 Uhr (Datum_heute)  99999 l
```
Dann wäre es doch sinnvoll, wenn alle Tageswerte um Mitternacht automatisch zum Tag davor
weiterrücken. Und das vereinfacht Dein Programm zum Ablegens des Tagesdurchflusses in die 
30-Tage-Liste ganz erheblich, weil Du dann um Mitternacht den Tagesdurchfluss des gerade 
abgelaufenen Tages *immer in die Variable für den Tagesdurchfluss_Gestern speicherst*, 
nachdem Du vorher die anderen Tagesdurchflüsse zum jeweiligen Vortag umgespeichert hast.

Falls Du in WCCflexible in der Liste der Tagesdurchflüsse auch das zugehörige Datum mit 
anzeigen willst, dann überlege, was für Dich einfacher ist: die Datumswerte in WCCflexible
berechnen oder auch für das Datum eine 30-Tage-Liste in der CPU anlegen und in WCCflexible
nur anzeigen. Die 30-Tage-Datum-Liste in der CPU wäre genauso aufzubauen und zu verwalten
wie die 30-Tage-Durchfluss-Liste, nur daß diese Liste eben ein Datum enthält statt eines 
Liter-Wertes.

Tip:
Mach in das Liter-Ausgabefeld in WCCflexible 3 Stellen von hinten ein Komma rein, dann hast 
Du die gleiche Anzeige wie auf der Wasseruhr, nämlich *m³*.


Berechnung des Tagesdurchflusses seit Mitternacht (beachtet Wrap 1.000.000.000->0)

```
+--------+
               | SUB_DI |
           ...-|EN      |
               |        |
     DB10.DBD0-|IN1  OUT|-#Liter_heute
               |        |
#Zaehlerstand_ |        |         +---+
       Gestern-|IN2  ENO|---------| & |
               +--------+         |   |  +--------+
                          +----+  |   |  | ADD_DI |
                          | <0 |--|   |--|EN      |
                          +----+  +---+  |        |
                                         |        |
                            #Liter_heute-|IN1  OUT|-#Liter_heute
                                         |        |
                            L#1000000000-|IN2  ENO|-
                                         +--------+
```


Um Mitternacht alle Tagesdurchflüsse 1 Tag zurück umspeichern, der älteste Wert verschwindet.
Danach den heute gezählten Tagesdurchfluss in den letzten = neuesten Wert speichern.
Zuletzt den aktuellen Zählerstand als Zählerstand_Gestern merken.

```
+---+                +--------+
             | & |                |  MOVE  |
#Mitternacht-|   |-+--------------|EN   OUT|-#Liter_1   // ältester Wert
             +---+ |              |        |            // vor 29 -> nun 30 Tagen
     ^             |     #Liter_2-|IN   ENO|-
     |             |              +--------+
     |             |              +--------+
(BOOL, nur         |              |  MOVE  |
 1 Zyklus lang)    +--------------|EN   OUT|-#Liter_2
                   |              |        |
                   |     #Liter_3-|IN   ENO|-
                   |              +--------+
                   |              +--------+
                   |              |  MOVE  |
                   +--------------|EN   OUT|-#Liter_3
                   |              |        |
                   |     #Liter_4-|IN   ENO|-
                   |              +--------+
                   |
                  ...               ...   //noch Liter_5 bis Liter_29 einfügen
                   |
                   |              +--------+
                   |              |  MOVE  |
                   +--------------|EN   OUT|-#Liter_29
                   |              |        |
                   |    #Liter_30-|IN   ENO|-
                   |              +--------+
                   |              +--------+
                   |              |  MOVE  |
                   +--------------|EN   OUT|-#Liter_30  // neuester Wert
                   |              |        |            // "gestern"
                   | #Liter_heute-|IN   ENO|-
                   |              +--------+
                   |              +--------+
                   |              |  MOVE  |
                   +--------------|EN   OUT|-#Zaehlerstand_Gestern
                                  |        |
                        DB10.DBD0-|IN   ENO|-
                                  +--------+
```

@ Paul
Ich hoffe, Du nutzt den schönen Tag für was "besseres" als das SPS-Forum. 
Deshalb bin ich hier doch noch einmal eingesprungen. 

Gruß
PN/DP


----------



## PN/DP (19 September 2009)

*AWL-Programm hochgeladen*

Info: Ich habe zum Pseudocode im Betrag #18 nun das Step7-Programm als AWL-Quelle angehängt.
Tagesverbräuche einen Monat lang speichern

Gruß
PN/DP


----------



## Paul (19 September 2009)

@PN/DP
Genauso habe ich mir das mit dem Werte umspeichern auch gedacht,
nur das ich Liter_1 als neuesten und Liter_30 als ältesten Wert genommen hätte,
aber das spielt eigentlich keine Rolle.

Einfach und funktioniert!!!!!!!

MfG
Paul


----------



## chefren_new (20 September 2009)

Hallo  

Danke 
hab jetzt alles fertig, nur ein kleines Problem, wie kann ich den Bool Wert 
Mitternacht nur einen Zyklus lang machen?

Gruss


----------



## PN/DP (20 September 2009)

*Mitternacht Speicher-Impuls*



chefren_new schrieb:


> wie kann ich den Bool Wert Mitternacht nur einen Zyklus lang machen?


Auf den ersten Blick, indem ich vergleiche, ob es jetzt 0:00 Uhr (oder 23:59 Uhr) ist 
und daraus eine Flanke erzeuge. Das Problem ist aber etwas komplizierter. Wenn die Uhr 
der CPU mit einer anderen Uhr synchronisiert wird, dann kann es *zweimal Mitternacht*
werden! (Ich habe auch schon Programme mit selbstgestrickter Uhrzeitsynchronisation 
gesehen, wo es sogar mehr als zweimal Mitternacht wurde.  )

Wie das??? 
Angenommen die CPU-Uhr geht etwas vor. Irgendwann wird die CPU-Uhr 0:00 Uhr anzeigen 
und die Flanke auslösen. Etwas später kommt die Uhrzeit-Synchronisation und sagt:
"Es ist jetzt 23:59 Uhr und 50 Sekunden". Die CPU-Uhr stellt sich zurück und etwas 
später zeigt sie wieder 0:00 Uhr an. Die Flanke wird noch einmal ausgelöst. :sm9:

Man muß also noch verhindern, daß die Flanke mehrfach ausgelöst wird. Das kann z.B. mit 
einem AVERZ-Timer realisiert werden, der von der ersten Flanke gestartet wird und dann 
mehrere Minuten nachläuft. Während der Timer läuft werden dann eventuelle weitere Flanken 
ignoriert.

Das ist mir aber noch nicht sicher genug. Ich bevorzuge eine andere Lösung. Ich merke mir, 
an welchem Tag (Datum) das letzte mal Mitternacht war (das Speichern ausgeführt wurde) und 
vergleiche, ob heute noch der gleiche Tag ist. Dann ist es egal, wie lange oder wie oft es 
Mitternacht an dem Tag mit dem gleichen Datum ist, meine Mitternachts-Funktion wird trotzdem 
nur einmal ausgeführt.

Beim Uhrzeit-Vergleich wird die Sekunde der Uhrzeit nicht mit verglichen. Es kann ja sein, 
daß genau diese Sekunde durch die Uhrzeit-Synchronisation übersprungen wird, wenn die 
CPU-Uhr nach geht und dann vor-gestellt wird. :sm9:

Nun endlich zum Programm.

In meinem Beispiel soll es um *23:59 Uhr Mitternacht* sein. Das ist besser als 0:00 Uhr,
wenn ich das Datum des gerade endenden Tages weiterverarbeiten will. 0:00 Uhr ist ja 
schon ein neuer Tag und ich müßte zusätzlich ermitteln, welches Datum "gestern" war.

Das ganze kurz in 16 Zeilen AWL

```
//NETWORK
//TITLE =Mitternacht Speicher-Impuls (AWL)
//TEMP.Temp_DT : Date_And_Time ; //Datum + Uhrzeit von SFC1 "READ_CLK"
//"DB11".Tag_speicher : BYTE ;   //Datum.Tag beim letzten Speichern

      CALL  "READ_CLK"                  //Datum + Uhrzeit lesen mit SFC1
       RET_VAL:=#Temp_Int
       CDT    :=#Temp_DT

      LAR1  P##Temp_DT                  //Pointer auf gelesene DATE_AND_TIME

      L     W [AR1,P#3.0]               //BCD Stunde + Minute
      L     W#16#2359                   //ist es 23:59 Uhr ?
      ==I   
      SPBN  ZMIT                        //nein, nicht speichern -> VKE=1 

      L     "DB11".Tag_speicher         //heute schon gespeichert?
      L     B [AR1,P#2.0]               //BCD Datum.Tag
      ==I   
      SPB   ZMIT                        //ja, nicht speichern -> VKE=1

      T     "DB11".Tag_speicher         //Speicherdatum merken (BCD Datum.Tag)
      CLR                               //VKE=0 ->  #Mitternacht=1
ZMIT: NOT                               //VKE negieren
      =     #Mitternacht                //Speicher-Impuls 1 Zyklus lang
```


Soll das Programm in FUP geschrieben werden, dann müssen einige zusätzliche Befehle rein.
Die temporäre Date_And_Time-Variable Temp_DT muß hier auf L0.0 beginnen. Wenn nicht, 
dann müssen LB2 (lokal-Byte 2) und LW3 (lokal-Word 3) angepasst werden. 
Der Zugriff auf LB2 und LW3 geht in FUP nur direkt nicht-symbolisch. Indirekte Adressierung
gibt es nicht in FUP.

Uhrzeit lesen (FUP)

```
TEMP.Temp_DT : Date_And_Time ; muß auf L0.0 beginnen!

    +------------+
    | "READ_CLK" |
...-|EN   RET_VAL|-#Temp_Int
    |            |
    |         CDT|-#Temp_DT       +--------+
    |            |                |  MOVE  |
    |         ENO|-+--------------|EN   OUT|-#Tag_Int
    +------------+ |              |        |
                   |          LB2-|IN   ENO|-
                   |              +--------+
                   |              +--------+
                   |              |  MOVE  |
                   +--------------|EN   OUT|-#Uhrzeit_Int
                                  |        |
                              LW3-|IN   ENO|-
                                  +--------+
```


Mitternacht Speicher-Impuls (FUP)

```
"DB".Tag_speicher muß INT in einem DB sein (z.B. STAT bei FB)
23:59 Uhr = W#16#2359 (BCD) = 9049 (Dez)

                  +--------+
                  | CMP==I |
     #Uhrzeit_Int-|IN1     |  +---+
                  |        |  | & |
             9049-|IN2     |--|   |
                  +--------+  |   |
                  +--------+  |   |
                  | CMP<>I |  |   |
         #Tag_Int-|IN1     |  |   |      #Mitternacht
                  |        |  |   |      +-------+
"DB".Tag_speicher-|IN2     |--|   |-+----|   =   |
                  +--------+  +---+ |    +-------+
                                    |    +--------+
                                    |    |  MOVE  |
                                    +----|EN   OUT|-"DB".Tag_speicher
                                         |        |
                                #Tag_Int-|IN   ENO|-
                                         +--------+
```

Gruß
PN/DP


----------



## Strommann (3 April 2011)

Hallo, dieser alte Beitrag hat mir bei einer Zähleraufgabe sehr geholfen. Nun habe ich allerdings noch das Problem das Datum für den jeweiligen Tag in einem vernünftigen Format (z.b. 30.12. statt 1230) anzeigen zu lassen. Kann mir hier jemand noch einen Tip geben? Das ganze soll hinterher in WinCC dargestellt werden.


----------



## uncle_tom (3 April 2011)

Beitrag gelöscht


----------



## PN/DP (3 April 2011)

Strommann schrieb:


> Nun habe ich allerdings noch das Problem das Datum für den jeweiligen Tag in einem vernünftigen Format (z.b. 30.12. statt 1230) anzeigen zu lassen.


Bei Panels kann man in *Control Panel > Regional Settings* das Format der Datumsanzeige einstellen oder man schreibt sich selbst das Datum formatiert in einen String.

Harald


----------



## Strommann (3 April 2011)

Es geht ja nicht um Panels, sondern um die Anzeige in einem WinCC Projekt (nicht Flexible).


----------



## thomass5 (3 April 2011)

...wenn du schon die 1230 hast, dann trenn sie doch in 12 und 30 auf, und setz sie entsprechend ein...

Thomas


----------



## Strommann (3 April 2011)

Wenn ich diese getrennt mit WinCC abhole verbrate ich nur für die Datumsanzeige 60 Prozessvariablen. Das freut sicherlich Siemens, es muss aber doch eine andere Lösung geben. Optimal wäre das ganze intern von WinCC machen zu lassen, aber das bekommt man sicher nur Scripten hin.


----------

