INT Werte speichern bzw. verschieben

steppenwolf

Level-1
Beiträge
47
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen.

Mir wurde ein Projekt zugetragen, von dem ich noch nicht so recht weiß wie ich das ganze lösen soll/kann.

Hier stehen mehrere Maschinen, welche ein gewisse Geschwindigkeit fahren. Die Summe dieser Maschinengeschwindigkeiten (welche sich ändert durch Störung, Geschwindigkeitsänderung durch Bediener, Wartung etc) sollte die Geschwindigkeit der nachfolgenden Maschine beeinträchtigen/steuern.

An und für sich kein göberes Problem, wenn da nicht ein Zeitspanne von ungefähr 2-3 Minuten zwischen den Maschinen wäre.

Kurz und Knapp:

Die Summe der geschwindigkeiten speichern (alle 5 Sekunden), und nach 2 Minuten (ebenfalls im Abstand von 5 Sekunden) in einen bereits bestehenden DB reinschreiben.

Ich hoffe soweit alles vernünftig erklärt zu haben. Bei Fragen einfach schreiben.

Ich danke im Voraus

MfG

Flo
 
Hört sich interessant an ...

Soweit ich es verstanden habe (falls nicht bitte schreiben) willst du eine Art Produkt-bezug herstellen.
Demnach wäre für mich da ein FIFO die Wahl der Mittel, das (z.B.) über den OB35 getriggert alle 5 Sekunden weitergeschoben und vorne mit einem neuen Wert gefüllt wird. In etwa richtig ?
Wenn ja, dann bestimmt die Länge des FIFO-Speichers im Grunde deine Zeitspanne, die du damit überbrückst ...

Wie willst du das angehen ? Standard-Programmierung oder SCL ?
Wenn ich mit meiner Beschreibung so in etwa richtig liege, dann wäre SCL schon hilfreich ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry

Erst mal vielen Dank für die schnelle Antwort.

FIFO wäre sicher eine interessante Lösung. Aber wie realisiere ich das, ohne das ganze zu kompliziert zu machen, mit SCL oä???

Da ich kein Programmier Profi bin, und mich nicht jeden Tag mit solchen Aufgaben herumschlagen muss, fällt mir das ganze ein wenig schwer.

Danke und Grüsse


Flo
 
Programmier-Profi wird man durch machen ...

Mein Vorschlag wäre, das Ganze in SCL anzugehen. Aus deinem Feedback lese ich heraus, dass du dich damit noch nicht beschäftigt hast.

Wenn du es dir zutraust, dann wirst du es auch schaffen ...

Gruß
LL
 
Habe mir gerade nochmal deinen Ansatz mit OB35 durch den Kopf gehen lassen.

Erstens: Einen FIFO DB mit 48 Bytes anlegen!

Lösungsvorschlag: (im OB35)

Als erstes alle Maschinenspeed addieren (alles INT Werte)

letzes wort im FIFO DB in den Maschinen DB schreiben.
Das zweitletzte ins letzte...
das drittletzte ins zweit letzte ...
.
.
.
Das erste wort ins zweite....
Und dann die Summe aller maschinen ins erste Wort.
5 Sek. abwarten, und OB35 wird neu gestartet.

Würde das funktionieren?


Danke und Grüsse

Flo
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... so in etwa hatte ich mir das gedacht.

Alle FIFO-Werte einzeln zu verschieben ist aber Unsinn. Das sollte man in einer Schleife machen. Zu dem Thema gibt es in der Rubrik FAQ einen schönen Beitrag von Volker.

Kümmerst sich jede Maschine hier beim Durchreichen um sich selbst ?
Oder hast du eine SPS, die das Zentral für alle tun soll ...?
 
Hallo Larry

Alle relevanten Daten laufen auf einer 417 zusammen.
Jeweils zwei DBs pro Maschine (Status - Comand)

Ich habe auch zum Thema Schleife mal im FAQ nachgeschaut, und auch sonst das Forum durchsucht. Leider werde ich nicht schlau aus der Angelegenheit.

Ich bleib aber am Ball...

Grüsse

Flo
 
... wenn du etwas nicht verstanden hast, dann frag doch ...
Ich denke mal, das man das schon gelöst bekommt.
Also ... wo hängt es ...?
 
Hast du dir den Beitrag in der FAQ durchgelesen ?
Ich nehme mal an : Ja ...

Anstelle eine Variable (Datenwort) direkt zu adressieren (L DB10.DBW 12) kann du es auch indirekt (über Pointer = Zeiger) ansprechen. Hier gibt es 2 Möglichkeiten. Die eine wäre über das Adress-Register (AR1 oder AR2) wie im Beispiel in der FAQ. Eine andere direkt über den Pointer (L DBW [Pointer]).

Der Pointer in der S7 basiert auf Bit-Adressierung. Das heißt, wenn du ein Byte ansprechen willst, dann mußt du im Pointer berücksichtigen, dass das 8 Bit beinhaltet. Hierfür wird dann gerne der SLD-Befehl herangenommen (SLD 3 bedeutet das Gleiche wie "mal 8").

Willst du das Datenwort 4 in deinem DB ansprechen dann programmierst du :
Code:
Pointer : dword
 
L 4
SLD 3
T Pointer
 
L DBW [Pointer]

Hast du das soweit verstanden ?

In einer Schleife arbeitest du mit einer Zählvariablen, die die Anzahl der Durchläufe bestimmt und die du mit jedem Durchlauf erhöhst (oder verringerst - je nach Aufgabenstellung)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

Danke erstmal.

Also ich habe mir den letzten Beitrag mal sehr genau angeschaut.

Ich werde mir jetzt das ganze mal runterladen, ein neues Projektchen öffnen und das ganze mal simulieren.

Das kann doch wohl nicht unmöglich sein, zu verstehen.

Ich sage mal danke, und melde mich (hoffentlich mit einer Erfolgsmeldung) wieder.

Danke und Grüsse

Flo
 
... guter Vorschlag ...:p

Aber auch wenn du keinen Erfolg hast, dann stell auf jeden Fall dein Werk hier ein. Ich denke, dann wird dir schon geholfen ...
Das FIFO hinzubekommen dürfte nicht das Problem sein.
 
Die Summe der geschwindigkeiten speichern (alle 5 Sekunden), und nach 2 Minuten (ebenfalls im Abstand von 5 Sekunden) in einen bereits bestehenden DB reinschreiben.

Ich habe das Programmbeispiel für den FIFO mal an Deine Aufgabenstellung angepasst:

- Der FIFO speichert 24 INT-Werte.

- Alle 5 Sekunden wird ein INT-Wert in den FIFO eingelesen.

- Nach 2 Minuten (24 Werte x 5 Sekunden) wird der erste in den FIFO eingelesene INT-Wert wieder aus dem FIFO ausgelesen.

- Nach weiteren 5 Sekunden wird der zweite in den FIFO eingelesene INT-Wert wieder aus dem FIFO ausgelesen, usw.


Code:
ORGANIZATION_BLOCK OB 1
TITLE =Hauptprogramm
//16
//   
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : FIFO
VERSION : 1.0
 
VAR_TEMP
  OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ;   //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ; //Priority of OB Execution
  OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ;   //Reserved for system
  OB1_RESERVED_2 : BYTE ;   //Reserved for system
  OB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ;   //Date and time OB1 started
  RETVAL : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Taktgeber 5 Sekunden
 
      UN    M     10.0; 
      L     S5T#5S; 
      SE    T     10; 
      NOP   0; 
      NOP   0; 
      NOP   0; 
      U     T     10; 
      =     M     10.0; 
 
NETWORK
TITLE =FIFO-Speicher
 
      U     M     10.0; 
      SPBNB _001; 
      CALL FC   100 (
           SPEICHER                 := DB200.FIFO,
           ANZAHL_WERTE             := 24,
           WERT_EINLESEN            := MW   100,
           WERT_AUSLESEN            := MW   102);
_001: NOP   0; 
 
END_ORGANIZATION_BLOCK

Code:
FUNCTION FC 100 : VOID
TITLE =FIFO-Speicher
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : FIFO
VERSION : 1.0
 
VAR_INPUT
  SPEICHER : POINTER ;  
  ANZAHL_WERTE : INT ;  
  WERT_EINLESEN : INT ; 
END_VAR
VAR_OUTPUT
  WERT_AUSLESEN : INT ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ;  
  AR1_REGISTER : DWORD ;    
  DB_NUMMER : WORD ;    
  ZWISCHENWERT : REAL ; 
  SCHLEIFE : INT ;  
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =FIFO-Speicher
 
      L     P##SPEICHER; // POINTER
      LAR1  ; 
 
      L     W [AR1,P#0.0]; // DB-Nummer
      T     #DB_NUMMER; 
 
      AUF   DB [#DB_NUMMER]; 
 
      L     D [AR1,P#2.0]; // Bereichszeiger
      LAR1  ; 
 
      L     #WERT_EINLESEN; // Wert
      T     #ZWISCHENWERT; // Wert => Zwischenwert
 
      L     #ANZAHL_WERTE; // Länge
M01:  T     #SCHLEIFE; // Schleife
 
      L     W [AR1,P#0.0]; // Wert
      L     #ZWISCHENWERT; // Zwischenwert
      T     W [AR1,P#0.0]; // Zwischenwert => Wert
      TAK   ; 
      T     #ZWISCHENWERT; // Wert => Zwischenwert 
 
      L     P#2.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; // Schleife
      LOOP  M01; 
 
      L     #ZWISCHENWERT; // Zwischenwert
      T     #WERT_AUSLESEN; // Wert
 
NETWORK
TITLE =DB-Register und Adressregister AR1 wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION

Gruß Kai
 

Anhänge

  • OB1.pdf
    5,3 KB · Aufrufe: 25
  • FC100.pdf
    5,4 KB · Aufrufe: 26
  • DB200.pdf
    3,7 KB · Aufrufe: 21
  • Fifo.zip
    31,8 KB · Aufrufe: 28
Zuviel Werbung?
-> Hier kostenlos registrieren
Und hier sind noch ein paar Bilder aus der Simulation mit PLCSIM.

Gruß Kai
 

Anhänge

  • VAT_1.jpg
    VAT_1.jpg
    303,2 KB · Aufrufe: 27
  • VAT_2.jpg
    VAT_2.jpg
    302,9 KB · Aufrufe: 19
  • VAT_3.jpg
    VAT_3.jpg
    303,2 KB · Aufrufe: 19
SUCCESS!:ROFLMAO:

Hallo zusammen!

Danke für eure Hilfe.

Nach langer Tüftelei im PLCSIM bin ich endlich hinter das "Geheimnis" gekommen. Ich habe es bisher nur mit drei Werten gemacht. Und es hat funktioniert. Aber ich verlängere es einfach auf 24, und dann hab ich meine 2 Minuten.

Ich danke euch für eure Hilfe und Zeit.

Grüsse

Flo
 
Zurück
Oben