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

Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 26 von 26

Thema: Maximalwert eines Analogwertes ermitteln und mitloggen

  1. #21
    Registriert seit
    19.06.2008
    Ort
    Ostalbkreis
    Beiträge
    3.140
    Danke
    201
    Erhielt 553 Danke für 498 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    ah jetzt ja...

    EDIT 2: Irgendwie sind bei mir die Beiträge durcheinander gerutscht....
    Geändert von Verpolt (04.11.2014 um 13:45 Uhr)

  2. #22
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.186
    Danke
    923
    Erhielt 3.291 Danke für 2.660 Beiträge

    Standard

    Hmm, soviele Baustellen in Deinen verschiedenen Programmversionen...
    Hier mal ein Beispielcode für 100 Messreihen.

    Der Log-DB:
    Code:
       0.0  STRUCT
      +0.0   Tab_Len : INT  := 100;            //Anzahl Werte in Tabelle = Anzahl Messreihen
      +2.0   Tab_Idx : INT  := 99;             //Index Tabellenplatz aktuelle Messreihe (0..99)
      +4.0   MaxWert : ARRAY [0 .. 99] OF      //Tabelle Maxwerte je Messreihe
      *4.0             REAL := 0.000000e+000;
    =404.0  END_STRUCT ;
    Der Log-FC Deklarationen:
    Code:
    VAR_INPUT
      IN_Messreihe_Aktiv : BOOL ;
      IN_Messwert : REAL ;
      IN_LogDBNr : INT ;
    END_VAR
    VAR_IN_OUT
      IO_FHM : BOOL ;	//Flankenhilfsmerker
    END_VAR
    VAR_TEMP
      tmp_DBNr : INT ;
      tmp_Tab_Ptr : DWORD ;
    END_VAR
    Der Log-FC Code:
    Code:
          U     #IN_Messreihe_Aktiv
          FP    #IO_FHM                     //IN_OUT: Flankenhilfsmerker
          SPBN  Mlog
    
    //Messreihe gerade gestartet
    //Index auf nächsten Tabellenplatz in LogDB weiterstellen (Ringpuffer) ...
          L     #IN_LogDBNr
          T     #tmp_DBNr
          AUF   DB [#tmp_DBNr]
          L     DBW    2                    //[IN_LogDBNr].Tab_Idx: aktueller Platz (0..99)
          +     1                           //auf nächsten Platz weiterstellen
          L     DBW    0                    //[IN_LogDBNr].Tab_Len: Anzahl Tabellenplätze (100)
          MOD                               //auf 0..99 begrenzen
          T     DBW    2                    //[IN_LogDBNr].Tab_Idx: aktueller Platz (0..99) merken
    
          SLD   5                           //Index --> P#<Index * 4 Byte>.0  (für REAL-Tabelle)
          L     P#4.0                       //Offset Tabelle "MaxWert" im DB: +4.0
          +D                                //dazurechnen
          T     #tmp_Tab_Ptr                //Pointer in REAL-Tabelle
    
    //... und geloggten Maxwert initialisieren
    //      L     -3.402823e+038              //minimal möglicher REAL-Wert
          L     #IN_Messwert                //erster Messwert
          T     DBD [#tmp_Tab_Ptr]          //als MaxWert Anfangswert
          SPA   Mend
    
    
    Mlog: U     #IN_Messreihe_Aktiv
          SPBN  Mend
    
    //Adresse aktueller MaxWert[Index] ermitteln
          L     #IN_LogDBNr
          T     #tmp_DBNr
          AUF   DB [#tmp_DBNr]
          L     DBW    2                    //[IN_LogDBNr].Tab_Idx: aktueller Platz (0..99)
          SLD   5                           //Index --> P#<Index * 4 Byte>.0  (für REAL-Tabelle)
          L     P#4.0                       //Offset Tabelle "MaxWert" im DB: +4.0
          +D                                //dazurechnen
          T     #tmp_Tab_Ptr                //Pointer in REAL-Tabelle
    
    //Messwert > bisheriger Maxwert?
          L     DBD [#tmp_Tab_Ptr]          //bisheriger MaxWert [IN_LogDBNr].MaxWert[Tab_Idx]
          L     #IN_Messwert
          <R                                //Messwert > bisheriger Maxwert?
          SPBN  Mend                        //nein --> nichts tun
          T     DBD [#tmp_Tab_Ptr]          //ja   --> als neuen Maxwert speichern
    
    Mend: SET
    Warum gibst Du eigentlich die DB-Nr variabel vor? Dadurch geht das ganze leider nicht mehr schön symbolisch.
    Für die Referenzdaten ist es übrigens besser, wenn Du den DB als BLOCK_DB übergibst statt die DB-Nummer als INT.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  3. #23
    raf77 ist offline Benutzer
    Themenstarter
    Registriert seit
    31.07.2014
    Beiträge
    34
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hallo PN/DP,
    1000 Dank für deinen Programmcode!!!
    Ich werde es sofot ausprobieren.. bin schon sehr gespannt.
    Und ja, es war vielleicht eine nicht so gute Idee die DBNr. varaiabel vorzugeben.

    DANKE!!!!

  4. #24
    raf77 ist offline Benutzer
    Themenstarter
    Registriert seit
    31.07.2014
    Beiträge
    34
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hallo PN/DP,
    ich habe soweit alles eingerichtet... den DB, FC und alle Deklarationen.
    Zwei Fragen hätte ich da noch :
    In der DB- Tabelle... sind die beiden Variablen Tab_Len und Tab_Idx mit dem Anfangswert vorbelegt ... quasi die 100 und die 99 in die Tabelle als Anfangswert eintragen, oder??
    Worauf ich mir auch noch nicht 100 Prozentig einen Reihm bilden kann ist der erste Abschnitt des Programms:

    AUF DB [#tmp_DBNr]
    L DBW 2 //[IN_LogDBNr].Tab_Idx: aktueller Platz (0..99)
    + 1 //auf nächsten Platz weiterstellen
    L DBW 0 //[IN_LogDBNr].Tab_Len: Anzahl Tabellenplätze (100)
    MOD //auf 0..99 begrenzen
    T DBW 2 //[IN_LogDBNr].Tab_Idx: aktueller Platz (0..99) merken

    SLD 5 //Index --> P#<Index * 4 Byte>.0 (für REAL-Tabelle)
    L P#4.0 //Offset Tabelle "MaxWert" im DB: +4.0
    +D //dazurechnen
    T #tmp_Tab_Ptr

    Hier wird der DB geöffnet und dann werden aus dem DB die beiden Wörter Adresse 0.0 und 2.0 bzw die Intvariablen geladen....
    Dann werden sie durch sich dividiert und der Rest wieder in 2.0 geladen....
    Wenn ich das ganze Starte über "U #IN_Messreihe_Aktiv" wird der Maxwert in die erste Adresse eingetragen ... sonst passiert nichts. Auch wird nichts in Adresse 0.0 und 2.0 eingetragen.


    Sorry, dass ich da noch nicht so fit bin und so viele Fragen stelle ... ich bin noch ziemlich am Anfang und das ist mein erstes Projekt in der Größenordnung.

    Gruß
    Rafael
    Geändert von raf77 (05.11.2014 um 11:15 Uhr)

  5. #25
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.186
    Danke
    923
    Erhielt 3.291 Danke für 2.660 Beiträge

    Standard

    Zitat Zitat von raf77 Beitrag anzeigen
    In der DB- Tabelle... sind die beiden Variablen Tab_Len und Tab_Idx mit dem Anfangswert vorbelegt ... quasi die 100 und die 99 in die Tabelle als Anfangswert eintragen, oder??
    Ja richtig. Die 100 und die 99 sind die Anfangswerte, mit denen auch der Aktualwert initialisiert sein muß. (DB Ansicht > Datensicht + Bearbeiten > Datenbaustein initialisieren)
    Die Vorbelegung von Tab_Len ist wichtig und darf nicht größer als die tatsächliche Arraygröße sein. Du könntest auch statt der Variable im Programm eine konstante feste Größe eintragen. Die Verwendung der Variable macht das ganze aber universeller und leichter für andere Arraygrößen änderbar.
    Die Vorbelegung von Tab_Idx ist optional, beim Start des Loggings wird geprüft, ob der Wert innerhalb des Arrays liegt (ob er 0 .. Tab_Len - 1 ist). Bei Vorbelegung mit 99 (Tab_Len - 1) beginnt das erste Logging freundlicherweise im ersten Array-Element.


    Zitat Zitat von raf77 Beitrag anzeigen
    Worauf ich mir auch noch nicht 100 Prozentig einen Reihm bilden kann ist der erste Abschnitt des Programms
    Bei der steigenden Flanke von #IN_Messreihe_Aktiv (Start der Messreihe) wird gelesen, welcher Wert im Schreibindex Tab_Idx (DBW2) steht (von der Messreihe vorher), der Wert wird um 1 erhöht (auf das nächste Array-Element weitergestellt), und dann mittels MOD mit Tab_Len (DBW0) dafür gesorgt, daß der Index nur Werte von 0..99 (Tab_Len - 1) hat und in wieder Tab_Idx (DBW2) gespeichert (gemerkt für die Verwendung in dieser Messreihe).
    Wenn bei dem Erhöhen ein Ergebnis größer Arraygröße rauskommt (>= Tab_Len), dann wird durch das MOD der Wert auf 0..99 "gemappt" und das Array wieder von unten her neu überschieben (Ringpuffer).

    "SLD 5": zusammengefasst Multiplikation * 8 (um aus dem Index eine Byteadresse P#<Index>.0 zu machen) und weitere * 4 (weil es ein REAL-Array ist und ein REAL-Wert 4 Byte belegt)
    Danach wird noch die Anfangsadresse des Arrays im DB dazuaddiert (+ P#4.0) --> ergibt die Adresse von [IN_LogDBNr].MaxWert[Tab_Idx]


    Zitat Zitat von raf77 Beitrag anzeigen
    Wenn ich das ganze Starte über "U #IN_Messreihe_Aktiv" wird der Maxwert in die erste Adresse eingetragen ... sonst passiert nichts. Auch wird nichts in Adresse 0.0 und 2.0 eingetragen.
    Das DBW2 muß beim ersten Durchlauf mit #IN_Messreihe_Aktiv = TRUE verändert worden sein: das gerade oben beschriebene Weiterstellen um 1 auf das nächste Array-Element.

    Solange #IN_Messreihe_Aktiv = TRUE ist wird bei jedem Durchlauf geprüft, ob der #IN_Messwert größer als der bisher in [IN_LogDBNr].MaxWert[Tab_Idx] gespeicherte Wert ist und ggf. in [IN_LogDBNr].MaxWert[Tab_Idx] geschrieben.

    Du mußt nun von außen dafür sorgen, daß #IN_Messreihe_Aktiv genau so lange TRUE ist wie Deine Messreihe andauert. Danach muß #IN_Messreihe_Aktiv FALSE werden und bei der nächsten Messreihe wieder TRUE --> dadurch wird wie beschrieben Tab_Idx auf das nächste Array-Element weitergestellt und der MaxWert der nächsten Messreihe mitgeloggt.

    Spiele mal mit Deiner Variable, welche Du an #IN_Messreihe_Aktiv angegeben hast (0, 1, 0, 1 ...) und beobachte Tab_Idx. Dann spiele mit dem Messwert bei aktivem #IN_Messreihe_Aktiv und beobachte [IN_LogDBNr].MaxWert[Tab_Idx].

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  6. #26
    raf77 ist offline Benutzer
    Themenstarter
    Registriert seit
    31.07.2014
    Beiträge
    34
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Harald,
    wow!! 1000 Dank für die schnelle und vor allem ausführliche Erläuterung. Ich habe alles verstanden und richtig was dazu gelernt!!! DANKE !!.... UND diese Lösung ist wirklich klasse!!!!!
    Der Fehler, den ich natürlich gemacht habe, waren die Anfangswerte von Tab_Len und Tab_Idx in dem DB. Die standen natürlich noch auf "0". Ich hatte den Datenbaustein auch noch nicht initialisiert.
    Was ich auch noch anpassen musste war der Array- Wert. Diesen habe ich auf ARRAY [0..100] gesetzt... mit ARRAY [0..99] stieg die SPS immer mit dem Eintrag des 99ten Wertes aus da der Tab_Len Wert größer war und das Programm wahrscheinlich einen Messwert in die Zeile 100 in der Tabelle schreiben wollte, die nicht da war... denke ich.
    Nun läuft es!

    Gruß
    Rafael

Ähnliche Themen

  1. Glättung eines Analogwertes
    Von hank12 im Forum Simatic
    Antworten: 23
    Letzter Beitrag: 27.11.2014, 21:49
  2. Suche Tool zur Darstellung eines Analogwertes
    Von bludie im Forum Suche - Biete
    Antworten: 4
    Letzter Beitrag: 22.08.2012, 15:06
  3. Länge eines UDT ermitteln
    Von Woto im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 20.04.2009, 08:21
  4. Antworten: 40
    Letzter Beitrag: 08.12.2008, 13:38
  5. Adresse eines Merkers am FB ermitteln
    Von RAN im Forum Simatic
    Antworten: 9
    Letzter Beitrag: 18.10.2007, 13:48

Lesezeichen

Berechtigungen

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