# Arbeiten mit Integer-Werten ?!?



## Jackjackson (3 Februar 2009)

Hallo Leute,

ich will in STEP7 ein Programm schreiben, das über ein Signal einen Zähler hochzählt und jedesmal, wenn der hochzählt, den Wert als Integer-Wert speichert.... Frage ist, wo soll ich die Werte reinspeichern bzw. wie kann ich auf diese dann zugreifen?
Vlt kann mir jemand helfen, danke....

MfG


----------



## rostiger Nagel (3 Februar 2009)

hallo jack,
zb. MWxy oder DBxy.DBWxy

Befehl wäre:

T MW xy
..
L MW xy

oder

T DBxy.DBWxy
..
L DBxy.DBWxy

gruß helmut


----------



## Jackjackson (3 Februar 2009)

Wie speichere ich die in ein MW?
Mit dem Zähler schauts ja so aus:
      U     E0.0
      ZV   Z1
      LC    Z1
      T     MW1
der speichert doch nur den endwert.... ich brauch die vorherigen zahlen auch... mindestens die 5 vorherigen noch


----------



## rostiger Nagel (3 Februar 2009)

...die vorherigen zahlen auch...???
wie meinst das jetzt...?


----------



## Gebs (3 Februar 2009)

Hallo Jackjackson,

nimm dann besser einen DB und bau Dir darin einen FIFO oder einen Ringpuffer.

Mit LC lädst Du den Zählwert BCD-codiert. Wenn Du ihn aber als Int haben willst, hol Dir den Wert mit L Z1 oder vor dem T MW1 ein BTI.

Grüße
Gebs


----------



## Jackjackson (3 Februar 2009)

zB. Es sind 10 Eingangssignale gekommen, der Zähler ist auf 10...
ich will dass die Werte 10, 9, 8, 7, 6, 5 irgendwo gespeichert werden, so dass ich auf die zugreifen kann... bei 11 wärn dann eben 11, 10, 9, 8, 7, 6...
Geht das überhaupt?


----------



## peter(R) (3 Februar 2009)

Wenn du hochzählst zB. bis 30  dann werden die 5 vorherigen Zahlen
MIT SICHERHEIT   25, 26, 27, 28, 29 sein !!!

Oder willst du ein "Bündel" beliebiger Zahlen speichern ??  dann sieht die Welt gaaanz anders aus.

peter(R)


----------



## Jackjackson (3 Februar 2009)

Wie würde das mit beliebigen Zahlen gehn?
Bzw. ... bleiben wir lieber beim Zähler.... wie speichere ich die Zahlen?


----------



## peter(R) (3 Februar 2009)

l Endzahl
l 1
-i
t endw-1 ( zB in eine DW)
l Endzahl
l 2
-i
t endw-2 ( zB in eine DW)

usw.


primitivste Version

peter(R)


----------



## Gebs (3 Februar 2009)

Hallo Jackjackson,

Hier mal eine kleine Hilfestellung:


```
Auf DB 1 // Ringspeicher

U E0.0
ZV Z1

L Z1   // Adresse in Ringspeicher bilden
SLD3
LAR1

L #Zahl  // irgendeine Zahl die Du speichern willst
T DBW[AR1,P#0.0]

L Z1
L 10  // Anzahl der zu speichernden Zahlen
==I
R Z1
```

Grüße
Gebs


----------



## Jackjackson (3 Februar 2009)

Danke für die schnellen Antworten... das hilft mir ein bisschen weiter


----------



## Kai (3 Februar 2009)

Jackjackson schrieb:


> ich will in STEP7 ein Programm schreiben, das über ein Signal einen Zähler hochzählt und jedesmal, wenn der hochzählt, den Wert als Integer-Wert speichert.... Frage ist, wo soll ich die Werte reinspeichern bzw. wie kann ich auf diese dann zugreifen?


 


Jackjackson schrieb:


> Es sind 10 Eingangssignale gekommen, der Zähler ist auf 10...
> ich will dass die Werte 10, 9, 8, 7, 6, 5 irgendwo gespeichert werden, so dass ich auf die zugreifen kann... bei 11 wärn dann eben 11, 10, 9, 8, 7, 6...


 
Hier ist einmal ein Programmbeispiel für die Speicherung von Werten in einen FIFO-Speicher.

Die letzten 10 Zählwerte eines Zählers werden als INT-Werte in einem Datenbaustein als FIFO-Speicher gespeichert.


```
RGANIZATION_BLOCK "OB_HAUPTPROGRAMM"
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
END_VAR
BEGIN
NETWORK
TITLE =Zaehler
 
      U     "SIGNAL"; 
      ZV    "ZAEHLER"; 
      BLD   101; 
      NOP   0; 
      NOP   0; 
      U     "ZAEHLER_RUECKSETZEN"; 
      R     "ZAEHLER"; 
      NOP   0; 
      LC    "ZAEHLER"; 
      T     "ZAEHLER_ZAEHLWERT_BCD"; 
      NOP   0;
 
NETWORK
TITLE =Zaehler
 
      L     "ZAEHLER_ZAEHLWERT_BCD"; 
      BTI   ; 
      T     "ZAEHLER_ZAEHLWERT_INT"; 
      NOP   0; 
 
NETWORK
TITLE =FIFO Zaehler
 
      U     "SIGNAL"; 
      FP    "SIGNAL_FLANKE"; 
      SPBNB _001; 
      CALL "FC_FIFO_ZAEHLER" (
           DB_ZAEHLER               := "DB_ZAEHLER",
           ANZAHL_ZAEHLWERTE        := 10,
           ZAEHLWERT                := "ZAEHLER_ZAEHLWERT_INT");
_001: NOP   0; 
 
END_ORGANIZATION_BLOCK
```
 

```
TITLE =FIFO Zaehler
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : FIFO
VERSION : 1.0
 
VAR_INPUT
  DB_ZAEHLER : BLOCK_DB ; 
  ANZAHL_ZAEHLWERTE : INT ; 
  ZAEHLWERT : INT ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  SCHLEIFE : INT ; 
  ZWISCHENWERT : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =FIFO Zaehler
 
      AUF   #DB_ZAEHLER; // DB Zaehler
 
      L     P#0.0; 
      LAR1  ; 
 
      L     #ZAEHLWERT; // Zaehlwert
      T     #ZWISCHENWERT; // Zwischenwert
 
      L     #ANZAHL_ZAEHLWERTE; // Anzahl Zaehlwerte
M01:  T     #SCHLEIFE; 
 
      L     DBW [AR1,P#0.0]; // Zaehlwert
      L     #ZWISCHENWERT; // Zwischenwert
      T     DBW [AR1,P#0.0]; // Zwischenwert => Zaehlwert
      TAK   ; 
      T     #ZWISCHENWERT; // Zaehlwert => Zwischenwert
 
      L     P#2.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (3 Februar 2009)

Und noch zwei Bilder aus der Simulation mit PLCSIM.

Gruß Kai


----------



## MW (4 Februar 2009)

Ich glaub Gebs- und Kai´s Lösung schiesst da etwas übers Ziel hinaus, warum so umständlich ???

Ich würd sagen das Peter(R) lösung für die simple Aufgabe wirklich ausreichend ist.


----------



## Jackjackson (4 Februar 2009)

Danke .... hat mir sehr weitergeholfen!!  
Wie müsste man eigentlich den OB1 bzw FC ändern, dass statt einem zählerhochzählenden Eingangssignal zufällige Int-Werte ins Programm gespeist werden?


----------



## Gebs (4 Februar 2009)

Hallo Jackjackson,

die einfachste Möglichkeit wäre die Millisekunden aus dem OB1_Date_Time zu nehmen.

Grüße
Gebs


----------



## Jackjackson (4 Februar 2009)

Meinst du OB1_PREV_CYCLE, OB1_MIN_CYCLE und OB1_MAX_CYCLE?
Muss man am Programm nichts ändern?


----------



## Gebs (4 Februar 2009)

Hallo Jackjackson,

ich meine schon OB1_DATE_TIME! AB L 12.0 im OB1. Im LW 18 stehen die ms der Systemuhr und der aktuelle Tag.

Mit 

```
L LW 18
SRW 4
T MW xy
```
hast Du dann im MW xy die ms stehen.
Das MW xy setzt Du dann einfach an die Stelle des Zählwertes.

Grüße
Gebs


----------



## Jackjackson (4 Februar 2009)

ich verstehs zwar nicht, aber probiern kann ichs ja mal....


----------



## Jackjackson (4 Februar 2009)

Das zählt nur automatisch MW1 hoch und runter...
ich will nur die Werte nacheinander in MW1 setzen und speichern ...
      L     LW    18
      SRW   4
      T     MW1

L     MW1
      BTI   
      T     "Z_INT"
      NOP   0



(An die SPS werden die IDs der Fördergüter gesendet, welches die 10 IDs speichert, auf die man zugreifen kann...)


----------



## Gebs (4 Februar 2009)

Dann willst Du also nicht ZUFÄLLIGE Werte speichern, sondern die IDs?

Grüße
Gebs


----------



## Jackjackson (4 Februar 2009)

Die IDs sind ja nicht nummeriert nach Zählerprinzip... 
Bzw, anscheinend hab ich mich leicht missverständlich ausgedrückt


----------



## Kai (4 Februar 2009)

Hast Du mal ein Beispiel für eine ID?

Bestehen die IDs nur aus Zahlen oder auch aus Buchstaben?

Gruß Kai


----------



## Jackjackson (4 Februar 2009)

Es sind nur Ganzzahlen.


----------



## Kai (4 Februar 2009)

Welchen Wertebereich (INT oder DINT) haben die IDs? 

Wertebereich INT = - 32768 bis + 32767

Wertebereich DINT = - 2147483648 bis + 2147483647

Gruß Kai


----------



## Jackjackson (4 Februar 2009)

DINT wär am günstigsten


----------



## Gebs (4 Februar 2009)

Hallo Jackjackson,

wie wär's dann damit:


```
U #NeuesFoerdergutEingetroffen  
ZV Z1

L Z1
-1
L 4     // Weil ein DINT 4 Bytes hat    
*D
SLD 3 // Ins Pointerformat
LAR1  // im Adressregister 1 ablegen

AUF DB 1  // der DB in dem die IDs gespeichert werden sollen
L #ID
T DBD [AR1,P#x.0]  // ID speichern; X ist hier der Offset im DB ab wo die ID stehen

L Z1
L 10
>=I
R Z1
```

Wenn Du den Code in einen FC stellst und dem FC die IN-Variablen
#NeuesFoerdergutErhalten
#ID
spendierst, werden die Daten in einem Ringpuffer abgelegt.
Wenn Du dann auch noch den Zählerstand speicherst, weißt Du wo die neueste ID liegt.

Grüße
Gebs


----------



## vierlagig (4 Februar 2009)

warum -1? egal, spring sowieso grad nur hier rein


```
*
      L     Z      1
      SLD   5                           // Ins Pointerformat
      LAR1                              // im Adressregister 1 ablegen
```
 
geht schneller

und wenn die eins noch weg soll


```
*
      L     Z      1
      [COLOR=red][B]+     -1[/B][/COLOR]
      SLD   5                           // Ins Pointerformat
      LAR1                              // im Adressregister 1 ablegen
```


----------



## Jackjackson (4 Februar 2009)

Moment, das muss ich jetzt mal kapieren 

Danke schonmal für die Hinweise...


----------



## vierlagig (4 Februar 2009)

wobei ich es sinnvollerweise mit


```
*
      U     #NeuesFoerdgut
      SPBN  noid
      ZV    Z      1
 
       ....
 
noid: NOP   0
```
 
ergänzen würde, damit nur eine ID gespeichert wird, wenn es wirklich notwendig ist.


----------



## dtsclipper (4 Februar 2009)

@ vierlagig:

Dann würde der Z1 genau 1x zählen, da der Z ja eine Positive Flanke braucht.
______________________________
O #NeuesFoerdgut
ON #gezaehlt
      SPBN  noid
       l mw xxx
       +1
       T mw xxx

set
S #gezaehlt

noid: nop 0

UN     #NeuesFoerdgut
R #gezaehlt
_______________________________

Und dann halt noch das MW bei Bedarf wieder nullen..
Behauptet dtsclipper


----------



## vierlagig (4 Februar 2009)

der globale S7-zähler hat die flanken auswertung schon drinnen, also darüber mach ich mir keine platte.

wenn ich den codeschnipsel richtig verstanden habe, soll der zähler bei neuem fördergut um eins erhöht werden und legt damit den speicherplatz der ID im db für dieses neue fördergut fest.

fest steht, dass diese ganze global/lokal-mischmaschscheiße die der gebs da uns hingeschmissen hat nicht wirklich praktikabel ist.

ich würde alles lokal machen, auch den "zähler" als INT variable (STAT bei FB oder INOUT bei FC) und die DBnummer würde ich als blockDB übergeben... aber das ist ja dann dem jackson seine kanne bier


----------



## vierlagig (4 Februar 2009)

also in etwa so:


```
*
FUNCTION FC 2 : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
  xTrigger : BOOL ; 
  iID : INT ; 
  bdDB : BLOCK_DB ; 
END_VAR
VAR_IN_OUT
  iCounter : INT ; 
  xHelpFlag : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =
      U     #xTrigger; 
      FP    #xHelpFlag; 
      SPBN  end; 
      L     #iCounter; 
      +     1;
      T     #iCounter;  
      SLD   5; 
      LAR1  ; 
      AUF   #bdDB; 
      L     #iID; 
      T     DBD [AR1,P#0.0]; 
      L     #iCounter; 
      L     10; 
      ==I   ; 
      SPBN  end; 
      L     0; 
      T     #iCounter; 
end:  SET   ; 
      SAVE  ; 
 
END_FUNCTION
```
was man in drei minuten halt so baustein nennt


----------



## Gebs (4 Februar 2009)

vierlagig schrieb:


> fest steht, dass diese ganze global/lokal-mischmaschscheiße die der gebs da uns hingeschmissen hat nicht wirklich praktikabel ist.



Sollte ja auch nur nen Denkanstoss sein! Wenn ich sowas richtig programmiere 
sieht's ganz anders aus!

Grüße
Gebs


----------



## vierlagig (4 Februar 2009)

Gebs schrieb:


> Sollte ja auch nur nen Denkanstoss sein! Wenn ich sowas richtig programmiere
> sieht's ganz anders aus!
> 
> Grüße
> Gebs


 
da ich jackjacksons weg schon etwas länger verfolge, bin ich immer dafür, die denkanstöße sauber auszuführen.


----------



## dtsclipper (4 Februar 2009)

--- grins ---

Aber man muss ja nicht gleich alles verraten, nicht wahr?

Sonst kann ich mich vor euch ja nur noch vor Ehrfurcht verneigen!


----------



## SPSKILLER (4 Februar 2009)

vierlagig schrieb:


> da ich jackjacksons weg schon etwas länger verfolge, bin ich immer dafür, die denkanstöße sauber auszuführen.


 
wo wird denn in deinem Baustein der Zähler erhöht und ausgegeben?


----------



## vierlagig (4 Februar 2009)

SPSKILLER schrieb:


> wo wird denn in deinem Baustein der Zähler erhöht und ausgegeben?



iCounter : INT - INOUT


----------



## SPSKILLER (4 Februar 2009)

blick ich nicht 

wie kommt der Zähler auf 10? extern?


----------



## vierlagig (4 Februar 2009)

SPSKILLER schrieb:


> blick ich nicht
> 
> wie kommt der Zähler auf 10? extern?



hab die fehlende T iCounter nachgepflegt... ist in der eile wohl untergegangen.


----------



## Kai (4 Februar 2009)

Jackjackson schrieb:


> An die SPS werden die IDs der Fördergüter gesendet, welches die 10 IDs speichert, auf die man zugreifen kann...


 


Kai schrieb:


> Welchen Wertebereich (INT oder DINT) haben die IDs?


 


Jackjackson schrieb:


> DINT wär am günstigsten


 
Hier ist noch einmal ein neues Programmbeispiel für die Speicherung von Werten in einen FIFO-Speicher.

Eine beliebige Fördergut ID-Nummer wird im MD100 ID_NUMMER im Datenformat DINT eingetragen.

Bei einem positiven Flankenwechsel am M110.0 SIGNAL wird die ID-Nummer im FIFO-Speicher im DB100 DB_FOERDERGUT gespeichert.

Im FIFO-Speicher werden die letzten 10 ID-Nummern gespeichert.


```
ORGANIZATION_BLOCK OB 1
TITLE = Hauptprogramm
//18
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
END_VAR
BEGIN
NETWORK
TITLE =FIFO Foerdergut
 
      U     M    110.0; 
      FP    M    110.1; 
      SPBNB _001; 
      CALL FC   100 (
           DB_FOERDERGUT            := DB   100,
           ANZAHL_ID_NUMMERN        := 10,
           ID_NUMMER                := MD   100);
_001: NOP   0; 
 
END_ORGANIZATION_BLOCK
```
 

```
FUNCTION FC 100 : VOID
TITLE =FIFO Foerdergut
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : FIFO
VERSION : 1.0
 
VAR_INPUT
  DB_FOERDERGUT : BLOCK_DB ; 
  ANZAHL_ID_NUMMERN : INT ; 
  ID_NUMMER : DINT ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  ZWISCHENWERT : DINT ; 
  SCHLEIFE : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =FIFO Foerdergut
 
      AUF   #DB_FOERDERGUT; // DB Foerdergut
 
      L     P#0.0; 
      LAR1  ; 
 
      L     #ID_NUMMER; // ID-Nummer
      T     #ZWISCHENWERT; // Zwischenwert
 
      L     #ANZAHL_ID_NUMMERN; // Anzahl ID-Nummern
M01:  T     #SCHLEIFE; 
 
      L     DBD [AR1,P#0.0]; // ID-Nummer
      L     #ZWISCHENWERT; // Zwischenwert
      T     DBD [AR1,P#0.0]; // Zwischenwert => ID-Nummer
      TAK   ; 
      T     #ZWISCHENWERT; // ID-Nummer => Zwischenwert
 
      L     P#4.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (4 Februar 2009)

Und noch ein paar Bilder aus der Simulation mit PLCSIM.

Gruß Kai


----------



## Jackjackson (9 Februar 2009)

Danke für die Hinweise 
Ist es auch möglich für jeden gespeicherten Wert, sagen wir für ein Array von 1000 Werten, jeweils einen Ausgangsimpuls zu senden in einem Intervall von 50ms?


----------

