Wasseruhr mit CPU 314C-2 DP

Zuviel Werbung?
-> Hier kostenlos registrieren
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ß
 
@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
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
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
 
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
Code:
        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?
Code:
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 .


Berechnung des Tagesdurchflusses seit Mitternacht (beachtet Wrap 1.000.000.000->0)
Code:
               +--------+
               | 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.
Code:
             +---+                +--------+
             | & |                |  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
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@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
 
Mitternacht Speicher-Impuls

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??? :confused:
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
Code:
//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)
Code:
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)
Code:
"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
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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.
 
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
 
...wenn du schon die 1230 hast, dann trenn sie doch in 12 und 30 auf, und setz sie entsprechend ein...

Thomas
 
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. :confused:
 
Zurück
Oben