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

Seite 9 von 10 ErsteErste ... 78910 LetzteLetzte
Ergebnis 81 bis 90 von 99

Thema: Mit Pointer in Ringregister schreiben

  1. #81
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.715
    Danke
    443
    Erhielt 914 Danke für 739 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von rostiger Nagel Beitrag anzeigen
    Kann es sein das dein '#Reset_Aktiv' nicht korrekt zurückgesetzt wird?
    Ich denke eher, es liegt hier dran, das da nicht geladen, sondern transferiert wird:
    Zitat Zitat von Minico89 Beitrag anzeigen
    [CODE]...
    // Register ggf. resetten
    ...
    // Zeiger Ringpuffer initialisieren
    T #Schleifenindex // als Schleifenindex speichern
    T "Register".Zeiger_Ringpuffer // als Zeiger für Ringpuffer speichern
    ...
    Wofür ich dann wohl verantwortlich bin:
    Zitat Zitat von hucki Beitrag anzeigen
    ...
    Ungefähr so (ist aber immer noch ungetestet, muss also nicht fehlerfrei sein!):
    Code:
    ...
    // Zeiger Ringpuffer initialiesieren
          T     #Schleifenindex; // als Schleifenindex speichern
          T     #Zeiger_Ringpuffer; // als Zeiger für Ringpuffer speichern
    
    // Pointer erstellen
          L     "Register".Zeiger_Ringpuffer    // Zeiger für Ringpuffer
          L     #DS_Laenge                  // Datensatzlänge
          *I 
    ...
    ...





    Ich würde so im Nachhinein auf den "Register".Zeiger_Ringpuffer ganz verzichten und nur mit dem Schleifenindex arbeiten:
    Code:
    ...
    // Register ggf. resetten
    ...
    // Pointer erstellen
          L     #Schleifenindex             // Schleifenindex laden
          L     #DS_Laenge                  // Datensatzlänge
          *I
    ...

  2. Folgender Benutzer sagt Danke zu hucki für den nützlichen Beitrag:

    Minico89 (05.08.2013)

  3. #82
    Registriert seit
    23.07.2013
    Beiträge
    66
    Danke
    26
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Jap, jetzt läuft der Kasten! Mal sehen was ich jetzt noch tolles an den Bausteinen ändern kann! Vielen vielen Dank vorerst

  4. #83
    Registriert seit
    23.07.2013
    Beiträge
    66
    Danke
    26
    Erhielt 0 Danke für 0 Beiträge

    Standard

    So, nachdem das jetzt geklärt ist hab ich jetzt eine Folgefrage:

    Wie bewerkstelligt man das am einfachsten dass ich jetzt etliche Merker und Eingänge auf Flanken kontrolliere? D.h. dass ich gerne protokollieren würde wenn z.B. ein Förderband ausfällt, oder z.b. ein Hubtisch.

    Beispielszenario:
    Fällt das Förderband aus, so soll es die Zahl 6 (die ich vorher einem Förderband zugeordnet habe) in das Ringregister schreiben, natürlich mit zugehöriger Uhrzeit.
    Fällt der Hubtisch aus, so soll es die Zahl 8 (...) in das Ringregister schreiben, natürlich mit zugehöriger Uhrzeit.

    Setze ich das eher mit einem Datenfeld um, oder einem großen parametrierbaren Baustein, oder mit vielen kleinen Minibausteinen?


    Kann ich das hier Fragen oder mache ich lieber einen anderen Thread dafür auf?

  5. #84
    Registriert seit
    20.06.2003
    Ort
    Sauerland.NRW.Deutschland
    Beiträge
    4.850
    Danke
    78
    Erhielt 800 Danke für 543 Beiträge

    Standard

    wobei hier db10.dbw0 die var ist welche in den fifo eingetragen wird
    Angehängte Grafiken Angehängte Grafiken
    .
    mfg Volker .......... .. alles wird gut ..

    =>Meine Homepage .. direkt zum Download

    Meine Definition von TIA: Total Inakzeptable Applikation

  6. #85
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.715
    Danke
    443
    Erhielt 914 Danke für 739 Beiträge

    Standard

    Zitat Zitat von Minico89 Beitrag anzeigen
    Wie bewerkstelligt man das am einfachsten dass ich jetzt etliche Merker und Eingänge auf Flanken kontrolliere? D.h. dass ich gerne protokollieren würde wenn z.B. ein Förderband ausfällt, oder z.b. ein Hubtisch.
    Juhu, ich darf mich wieder selbst zitieren:
    Zitat Zitat von hucki Beitrag anzeigen
    1. Man gehe in die FAQ, weil Deine Frage gefühlte 10x im Monat gestellt wird und man deshalb gute Chancen hat, dort was zu finden.
    2. Man öffne den Thread, der so ziemlich zu Deiner Frage passt, wie A... auf Eimer.
    3. Man lese, versuche zu verstehen und probiere dann selbst.

  7. #86
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.715
    Danke
    443
    Erhielt 914 Danke für 739 Beiträge

    Standard

    Zitat Zitat von Minico89 Beitrag anzeigen
    Jap, jetzt läuft der Kasten! Mal sehen was ich jetzt noch tolles an den Bausteinen ändern kann!
    Na ja, wenn ich Dein Konstrukt so sehe, wäre ich damit alles Andere als zufrieden, da z.B. immer noch globale Angaben innerhalb des FBs verwendet werden.
    Folgende Baustellen gäbe es aus meiner Sicht mindestens, bevor ich mich anderen Bausteinen zugewendet hätte:


    Offensichtlich warst Du nicht mal in der Lage, aus einem STRUCT, das 3 BYTES enthält, 3 einzelne BYTES an der Schnittstelle zu machen. Da muss man nur den STRUCT-"Käfig" entfernen und schon kannst Du Deine Stunde, Minute und Sekunde separat übergeben.

    Den Zeiger für den Ringspeicher außerhalb des FBs zu speichern (wie Du es jetzt machst) halte ich auch für sinnvoll. Trotzdem sollte auch er nicht global verwendet werden, sondern ebenfalls über die Schnittstelle übergeben werden. In diesem Fall würde man IN_OUT benötigen, da erst der alte Wert gelesen werden soll (IN-Part), dann verändert wird und der neue Wert dann wieder gespeichert werden soll (OUT-Part).

    Wenn der Zeiger für den Ringspeicher außerhalb des FBs gespeichert wird, sollte das auch für die aktuelle Ereignisnummer gelten.

    Wenn der Ringspeicher mit Nullen resettet wird, würde ich auch noch den Zeiger für den Ringspeicher und die Ereignisnummer resetten.
    Durch Ersteres könnte man auch schon nach dem Reset des ersten Datensatzes dort im nächsten Zyklus sofort wieder ein neues Ereignis eintragen, während die nachfolgenden Datensätze weiter genullt werden.

    Wie früher schon mal erwähnt, sind die 5ms nicht gerade weit von der Zykluszeit entfernt. Ich würde deshalb einfach jeden Zyklus einen Datensatz resetten. Dadurch könnte man sich den ganzen Timeraufwand sparen.

    Ich würde wissen wollen, ob das Resetten noch aktiv ist und einen entsprechenden Ausgang am FB erstellen.

    Das doppelte Öffnen des DBs bzw. Sichern des AR1 ist in meinen Augen auch "unschön".



    Ich hab' das mal für Dich zur Ansicht umgesetzt (immer noch ungetestet ):
    Code:
    FUNCTION_BLOCK "Ereignisspeicher"
    TITLE =
    AUTHOR : Hucki
    VERSION : 0.1
    
    
    VAR_INPUT
      Speichern : BOOL ;	
      Reset_Start : BOOL ;	
      Aktuell_Stunden : BYTE ;	
      Aktuell_Minuten : BYTE ;	
      Aktuell_Sekunden : BYTE ;	
      Speicher_DB : BLOCK_DB ;	
      DS_Anzahl : INT ;	
      DS_Laenge : INT ;	
      DS_Offset : INT ;	
    END_VAR
    
    VAR_OUTPUT
      Reset_Aktiv : BOOL ;	
    END_VAR
    
    VAR_IN_OUT
      Zeiger_Ringspeicher : INT ;	
      Ereigniszaehler : INT ;	
    END_VAR
    
    VAR
      Zeiger_DS_Reset : INT ;	
      FM_Speichern : BOOL ;	
      FM_Reset : BOOL ;	
    END_VAR
    
    VAR_TEMP
      Sicherung_AR1 : DWORD ;	
    END_VAR
    
    
    BEGIN
    
    NETWORK
    TITLE =
    
          UN    #Speichern; // Wenn Baustein nichts im DB speichern soll
          UN    #Reset_Start; // und nicht das Resetten des DBs beginnen soll
          UN    #Reset_Aktiv; // und auch nicht beim Resetten des DBs ist
          BEB   ; // dann Baustein gleich beenden, weil er nix zu tun hat
    
    
    
    // #### ALLGEMEIN ####################################################################################
    // AR1 sichern 
          TAR1  ; // Adress-Register 1 in Akku1 laden
          T     #Sicherung_AR1; // und temporär sichern 
    
    // Datenbaustein
          AUF   #Speicher_DB; // Speicher-DB öffnen
    
    
    
    //#### DS SPEICHERN ##################################################################################
          U     #Speichern; // Schließer-Eingang #Speichern
          FP    #FM_Speichern; // auf positive Flanke (0->1) prüfen
          SPBN  ResS; // wenn keine Flanke, zum Beginn der RESET-Routine springen
    
    // Ereigniszähler inkrementiern
          L     #Ereigniszaehler; // Ereigniszähler laden
          +     1; // um 1 erhöhen und 
          T     #Ereigniszaehler; // wieder speichern
    
    // Pointer erstellen
          L     #Zeiger_Ringspeicher; // Zeiger für Ringspeicher laden
          L     #DS_Laenge; // Datensatzlänge laden
          *I    ; // miteinander multiplizieren
          L     #DS_Offset; // Startadresse des Datenfeldes laden
          +I    ; // hinzu addieren
          SLD   3; // berechneten Wert auf die Byteadresse schieben
          LAR1  ; // und ins Adressregister 1 schreiben
    
    // Daten eintragen
          L     #Ereigniszaehler; // Ereigniszähler laden
          T     DBW [AR1,P#0.0]; // und im aktuellen Datensatz an WORD 0 sichern
    
          L     #Aktuell_Stunden; // Aktuelle Stunde laden
          T     DBB [AR1,P#4.0]; // und im aktuellen Datensatz an BYTE 4 sichern
    
          L     #Aktuell_Minuten; // Aktuelle Minute laden
          T     DBB [AR1,P#5.0]; // und im aktuellen Datensatz an BYTE 5 sichern
    
          L     #Aktuell_Sekunden; // Aktuelle Sekunde laden
          T     DBB [AR1,P#6.0]; // und im aktuellen Datensatz an BYTE 6 sichern
    
    // Zeiger inkrementieren
          L     #Zeiger_Ringspeicher; // Zeiger für Ringspeicher laden
          +     1; // um 1 erhöhen
          T     #Zeiger_Ringspeicher; // und wieder speichern
    
    // Zeiger auf Überlauf prüfen
          L     #Zeiger_Ringspeicher; // Zeiger für Ringspeicher laden
          L     #DS_Anzahl; // maximale Anzahl an Datensätzen laden
          >I    ; // auf Überschreitung prüfen
          SPBN  ResS; // wenn nicht überschritten, zum Beginn der RESET-Routine springen
          L     0; // Wert 0 laden
          T     #Zeiger_Ringspeicher; // und Zeiger für Ringpuffer auf 0 resetten
    
    
    
    //#### DS RESETTEN ###################################################################################
    // RESET starten
    ResS: U     #Reset_Start; // Öffner-Eingang #Reset_Start
          FN    #FM_Reset; // auf negative Flanke (1->0) prüfen
          S     #Reset_Aktiv; // und ggf. Reset aktivieren
    
    // RESET aktiviert?
          U     #Reset_Aktiv; // Reset aktiv?
          SPBN  Ende; // Nein, dann zum Ende springen
    
    // Bei RESET-Beginn Zeiger_Ringpuffer und Ereigniszähler zurücksetzen
          L     #Zeiger_DS_Reset; // Reset-Zeiger laden
          L     0; // Wert 0 laden
          ==I   ; // auf Gleichheit prüfen
          SPBN  PoiR; // wenn nicht 0 zum Erstellen des Pointers springen
          T     #Zeiger_Ringspeicher; // Zeiger für Ringspeicher auf 0 resetten
          T     #Ereigniszaehler; // Ereigniszähler auf 0 resetten
    
    // Pointer Löschschleife erstellen
    PoiR: L     #Zeiger_DS_Reset; // Reset-Zeiger laden
          L     #DS_Laenge; // Datensatzlänge laden
          *I    ; // miteinander multiplizieren
          L     #DS_Offset; // Startadresse des Datenfeldes
          +I    ; // hinzu addieren
          SLD   3; // berechneten Wert auf die Byteadresse schieben
          LAR1  ; // und ins Adressregister 1 schreiben
    
    // Daten eintragen
          L     0; // Wert 0 laden
          T     DBD [AR1,P#0.0]; // ins (1.) DWORD 0 eintragen
    
          L     0; // Wert 0 laden
          T     DBD [AR1,P#4.0]; // ins (2.) DWORD 4 eintragen
    
    // Zeiger erhöhen
          L     #Zeiger_DS_Reset; // Reset-Zeiger laden,
          +     1; // um 1 erhöhen
          T     #Zeiger_DS_Reset; // und wieder speichern
    
    // Zeiger auf Überlauf prüfen
          L     #Zeiger_DS_Reset; // Reset-Zeiger laden,
          L     #DS_Anzahl; // Max. Anzahl an Datensätzen laden
          >I    ; // auf Überschreitung prüfen
          SPBN  Ende; // wenn noch nicht überschritten zum Ende springen
          R     #Reset_Aktiv; // RESET deaktivieren
          L     0; // Wert 0 laden
          T     #Zeiger_DS_Reset; // Reset-Zeiger auf 0 resetten
    
    
    
    //#### ALLGEMEIN ####################################################################################
    // AR1 wiederherstellen                            
    Ende: L     #Sicherung_AR1; // Gesicherten Wert laden
          LAR1  ; // und ins Adress-Register 1 zurückschreiben
    
    
    END_FUNCTION_BLOCK
    und der entsprechende Aufruf des FBs:





    Und von der Sache her ist das Resetten ja die gleiche Funktion wie das Speichern, nur das halt alles Nullwerte gespeichert werden. Man könnte also theoretisch den FB auch auf die Speicher-Funktion begrenzen (vlt. noch etwas anpassen) und dann für den Reset einen 2. Aufruf des FBs mit anderen Übergabewerten an der Schnittstelle benutzen.

  8. Folgender Benutzer sagt Danke zu hucki für den nützlichen Beitrag:

    Minico89 (07.08.2013)

  9. #87
    Registriert seit
    23.07.2013
    Beiträge
    66
    Danke
    26
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Okay, vielen Dank soweit, sieht wirklich feiner aus. Ganz großen respekt vor deinem (eurer allen) Wissen!

    Funktioniert auch sehr gut, nur das resetten will nicht... aber vielleicht liegts ja an mir

  10. #88
    Registriert seit
    20.06.2003
    Ort
    Sauerland.NRW.Deutschland
    Beiträge
    4.850
    Danke
    78
    Erhielt 800 Danke für 543 Beiträge

    Standard

    für das reseten solltest du dir mal sfc21 anschauen.
    Code:
          L     0
          T     #BVal_FILL
          CALL  SFC   21
           BVAL   :=#BVal_FILL
           RET_VAL:=#RET_VAL
           BLK    :=P#DB3.DBX 0.0 BYTE 200
    Geändert von volker (07.08.2013 um 09:29 Uhr)
    .
    mfg Volker .......... .. alles wird gut ..

    =>Meine Homepage .. direkt zum Download

    Meine Definition von TIA: Total Inakzeptable Applikation

  11. #89
    Registriert seit
    23.07.2013
    Beiträge
    66
    Danke
    26
    Erhielt 0 Danke für 0 Beiträge

    Standard

    ich würde schon gerne den geschriebenen code benutzen, nur funzt er bei mir net komplett, ich weiss zum beispiel nicht was ich im OB1, wo ich den baustein calle, bei #Reset_Aktiv angeben soll.
    ich glaube ich könnte dort einen ausgang anlegen, weiss aber nicht ob ich den wirklich belegen muss. glaube ja net...

    aber leider bin ich nicht gut genug um den fehler zu finden...

  12. #90
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.712
    Danke
    398
    Erhielt 2.397 Danke für 1.997 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    ... das sieht für mich so aus, als würde es sich bei "Reset aktiv" um eine Rückmeldung des Bausteins selbst handeln, die so lange TRUE ist, wie die von "Reset Start" angeforderte Aktion läuft bzw. der "Reset Start" angesteuert ist. Das kannst du ggf. als Verriegelung für irgend etwas (oder auch einfach nur als Info) benutzen - mußt es aber nicht ... (Vorteil von FB's).

    Gruß
    Larry

Ähnliche Themen

  1. mit any pointer ein bit schreiben
    Von Limette im Forum Simatic
    Antworten: 24
    Letzter Beitrag: 01.03.2012, 12:40
  2. Array in DB schreiben(any-pointer)
    Von Limette im Forum Simatic
    Antworten: 14
    Letzter Beitrag: 28.10.2011, 22:17
  3. Störmledungsbaustein mit Pointer?!?
    Von CrazyMC im Forum Simatic
    Antworten: 27
    Letzter Beitrag: 20.05.2010, 00:49
  4. Pointer als Out Variable Daten schreiben
    Von mkd im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 28.10.2009, 10:58
  5. Problem mit Pointer
    Von Mathias im Forum Simatic
    Antworten: 9
    Letzter Beitrag: 06.02.2009, 10:03

Lesezeichen

Berechtigungen

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