Pointer/Schleifen und Impulse?

softwareheini

Level-1
Beiträge
29
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,
hoffe Ihr könnt mir weiterhelfen.

Habe ne Siemens CPU 315 2DP (Step7 V5.4)

Ich möchte skallierte Analogwerte über ein Schleife
in einen DB schreiben.
Das funktioniert auch soweit.

Nur möchte ich nur einmal pro Sekunden den
Analogwert in den DB schreiben, bei erneutem Impuls
den Wert in die nächste Speicherstelle vom dem DB
usw. bis der DB voll ist.

Und dann wieder von vorne anfangen.

Brauch das für ne Mittelwertbildung.
Im moment werden aber leider alle Speicherstellen
gleichzeitig beschrieben.:cry:




Code:
FUNCTION "FC Schreiben" : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  dbnummer : INT ;    
  Analogsignal : REAL ;    
  Impuls : BOOL ;    
END_VAR
VAR_OUTPUT
  Ausgang : REAL ;    
END_VAR
VAR_TEMP
  dbnr : WORD ;    
  Schleifenzaehler : INT ;    
  Check_Ret_Val : INT ;    
  Check_DB_Length : WORD ;    
  Check_Write_rot : BOOL ;    
  dbnummer_1 : WORD ;    
  Ergebniss : REAL ;    
  Schleifenzaehler_1 : INT ;    
  Flanke_Impulse : BOOL ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     #dbnummer; 
      T     #dbnummer_1; 

NETWORK
TITLE =Aktuelle DB Checken

      CALL "TEST_DB" (
           DB_NUMBER                := #dbnummer_1,
           RET_VAL                  := #Check_Ret_Val,
           DB_LENGTH                := #Check_DB_Length,
           WRITE_PROT               := #Check_Write_rot);
      NOP   0; 
NETWORK
TITLE =



      L     #dbnummer; 
      T     #dbnr; 
      AUF   DB [#dbnr]; 

NETWORK
TITLE =

       LAR1  P#0.0; 

       L     #Check_DB_Length; // Länge vom DB laden
       SRW   2; // 2 Bit nach Rechts schieben

anf:  T     #Schleifenzaehler; /
        L     #Analogsignal; 
        T     DBD [AR1,P#0.0]; 
        +AR1  P#4.0; 
        L     #Schleifenzaehler; 
        LOOP  anf;
vielen Dank schon mal im vor aus!!!
 
Schleife

Hallo,

du darfst das nicht in einer Schleife machen. Du musst dir den "Eintragszähler" merken und daraus die Adresse berechnen. 1 mal pro Sekunde arbeitest du den Baustein ab, trägst den Wert ein und erhöhst den Eintragszähler bzw nullst ihn bei "voll".

Momentan füllst du jese Sekunde den DB mit dem gleichen Wert.

André
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

danke für die schnelle antwort.
Nur wie mach ich das? Steh jetzt irgendwie aufm Schlauch.

Die Werte Auslesen und/oder die Berechnung durchführen
muss ich dann in einer Schleife machen, oder?

mfg
softwareheini
 
Schleife

Hallo,

du musst dir einen Eintragszähler nehmen. 0 -> 1 -> 2 -> 3 -> 0. Überdiesen adressierst du die gewünschte Stelle im DB

Code:
      L     #Eintrag
      SLW   5
      LAR1  
      L     #Wert      
      T     DBD [AR1,P#0.0]

André
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@softwareheini

Die SPS arbeite ihr Programm ja ohnehin in einer Schleife ab. Sie fängt am Anfang des OB 1 an, arbeitet das Programm ab, macht dann noch ein paar interne Dinge und fängt wieder am Anfang des OB 1 an. Was du nun tun mußt ist, eine global Variable zu definieren (Merkerwort oder eine Int in einem DB). Dann baust du dir einen Timer, der einen Impuls abgibt, z.Bsp. jede Sekunde. Mit dem Impuls rufst di jedes Mal ein Stück Code auf, das in etwas so aussieht, wie oben im Post von sc. #Eintrag wäre deine globale Variable, #Wert dein abzuspeichernder Wert. #Eintrag zählst du jedesmal um 1 hoch, so wird die nächste Stelle im DB adressiert. Außerdem mußt du natürlich aufpassen, das #Eintrag nicht größer wird, als Stellen in deinem DB vorhanden sind, sonst geht die SPS irgendwann in Stop.

Nachtrag: Ich seh grad, geht ja schon, auch gut :ROFLMAO:!
 
Hallo noch mal,

kann es sein, dass wenn mein #Eintrag nicht global
sonder lokal im FC ist
und ich den FC mehrmals aufrufen, es zu einem Konflikt kommt.?

Ich hab mir einen DB erstellt in den ich mit dem 1. FC Aufruf 10 REAL Werte nacheinander schreibe.

Mit dem nächsten FC Aufruf erhöhe ich meinen Pointer und
schreibe wieder 10 Werte rein.
Den Pointer Offset übergebe ich jeweils von Außen.

Wenn ich einen FC aufrufe funktioniert es, bei zweien nicht :confused:

Ich arbeite innerhalb des FC´s mit AR2. Dieses wird
am Anfang auch "gerettet" und zum Schluss wieder
geladen?

Was könnte ich noch ändern?

mfg
softwareheini
 
Hallo noch mal,

kann es sein, dass wenn mein #Eintrag nicht global
sonder lokal im FC ist
und ich den FC mehrmals aufrufen, es zu einem Konflikt kommt.?

Ich hab mir einen DB erstellt in den ich mit dem 1. FC Aufruf 10 REAL Werte nacheinander schreibe.

Mit dem nächsten FC Aufruf erhöhe ich meinen Pointer und
schreibe wieder 10 Werte rein.
Den Pointer Offset übergebe ich jeweils von Außen.

Wenn ich einen FC aufrufe funktioniert es, bei zweien nicht :confused:

Ich arbeite innerhalb des FC´s mit AR2. Dieses wird
am Anfang auch "gerettet" und zum Schluss wieder
geladen?

Was könnte ich noch ändern?

mfg
softwareheini

#Eintrag soll ja über mehrere SPS-Zyklen hinweg gültig bleiben. Daher darf die Variable auf keinen Fall lokal sein. Das Beste in diesem Falle, du machst #Eintrag zu einer INOUT-Variablen und schreibst an jeden FC-Aufruf eine andere globale Variable (Merkerwort oder Datenwort aus einem DB). Vor dem Start der Aufzeichnung übergibst du an diese Variablen den jeweiligen Startzähler. Wenn der FC fertig ist steht in dem Startzähler der letzte Zähler mit dem geschrieben wurde, so kannst du z.Bsp. auch gleich kontrollieren, ob dein FC fertig ist.
 
Zurück
Oben