# Werte in DB archivieren bzw schieben



## MK_Auto (19 Oktober 2009)

Hallo zusammen suche eine einfache Lösung um einen wert in den DB zu schreiben und bei dem nächsten wert immer einen weiterzuschieben also das die Werte praktisch gespeichert werden
MfG
Micha


----------



## vierlagig (19 Oktober 2009)

stichwort schieberegister

aber warum schieben? kannst doch auch nacheinander eintragen


----------



## dtsclipper (19 Oktober 2009)

Oder ein einfacher Ringpuffer mit einem Zeiger.

dtsclipper


----------



## MK_Auto (19 Oktober 2009)

*Hallo vielagig*

Danke für deine Antwort nur habe ich die Stelle noch nicht gefunden suche halt ne einfache lösung das ein wert gemessen wird in DB eingetregen wird und er dann sage ich mal durchrutscht wenn der nächste kommt brauche 100 Werte
Gruß Micha


----------



## MK_Auto (19 Oktober 2009)

*Achso ich hatte vergessen zu erwähnen*

das ich mit pointer und AWL sage ich mal nicht so vertraut bin


----------



## vierlagig (19 Oktober 2009)

der ringpuffer von dtsclipper ist da genau das richtige.

brauchst nen DB mit hundert fächern
indirekt adressiert und den zeiger beim nächsten wert hochgezählt
beim 101. wert setzt du den zeiger wieder auf null

also: full steam ahead!


----------



## MK_Auto (19 Oktober 2009)

*Hallo Vierlagig*

mein Problem ist das mit dem zeiger das habe ich bisjetzt ncint geschnallt


----------



## MK_Auto (19 Oktober 2009)

*Der Grund der sache ist*

ich muss immer in der lage sein die 100 Werte auszudrucken daher in DB und dann über Panel im Protokol einlesen und drucken


----------



## vierlagig (19 Oktober 2009)

```
*
      U     #xTrigger                   //neuer wert vorhanden
      SPBN  end

      L     #dPointer                   //adresse
      LAR1                              //ins adressregister

      AUF   DB   100                    //DB öffnen
      L     #rValue                     //Wert
      T     DBD [AR1,P#0.0]             //in DB schreiben

      +AR1  P#4.0                       //nächstes Fach auswählen
      TAR1  
      T     #dPointer                   //und wert für die nächste Werwendung speichern

      L     #dPointer                   //hat der  pointer
      L     P#400.0                     //das 101te facherreicht
      >=D   
      SPBN  end
      L     L#0                         //wird er genullt
      T     #dPointer

end:  NOP   0
```

so sollte es funktionieren


----------



## dtsclipper (19 Oktober 2009)

Das ist im Grunde kein Problem.

Der " Zeiger " ist einfach nur ein Wert, mit dem ein Datenwort angesprochen wird, beginnend bei 0.

Also 


```
// Hier Rückstellbedingung
 
SPB NoRe
L 0
T MW 490
NoRe: nop 0
```
 
Um dann das " Registerfach " anzusprechen, muss noch der DB geöffnet werden und dann das Datenfach adressiert

```
AUF DB100
 
L #SpeicherWert
T dbw [MW 490]
 
L MW490
L 2
+I
T MW490  // Zeiger erhöhen
```
 
Das ist so die Basisversion ohne Flanken und die Rückstellung fehlt auch noch.

dtsclipper


----------



## MK_Auto (19 Oktober 2009)

*Danke Vierlagig aber*

aber wenn ich es richtig sehe fängt er wieder bei null an zu schreiben 
also im ersten fachh wenn 100 voll 
der erste wert muss aber immer oben stehen das ist das Problem 
MIcha


----------



## dtsclipper (19 Oktober 2009)

Der ERSTE Wert oder der letzte gemessene?


----------



## MK_Auto (19 Oktober 2009)

*Sorry*

also der zu letzt gemessene muss oben stehn


----------



## dtsclipper (19 Oktober 2009)

Also, so auf die schnelle:

Am simpelsten ist es mit der guten alten Lade- und Transfertechnik.
Einfach mit der Flanke das neue Daten da sind 


```
ON #Neuer_Eintrag
O #Eingetragen
SPB NILO
 
L db100.dbw100
T db100.dbw102
 
L db100.dbw98
T db100.dbw100
 
L db100.dbw96
T db100.dbw98
 
...
 
L #Neuer_Wert
T db100.dbw0
 
set
S #Eingetragen
 
NILO: nop 0
 
ON #Neuer_Eintrag
R #Eingetragen
```
 
Wobei #Neuer_Eintrag und R #Eingetragen entweder statische Variablen im FB sind ODER aber Merker.

Vierlagig bringt mich um.


----------



## MK_Auto (19 Oktober 2009)

*Danke*

genauso habe ich es mir fast gedacht dachte halt es gibt ne funktin wo man die int im DB komplett verschieben kann


----------



## dtsclipper (19 Oktober 2009)

Wenn es eine fertige Funktion gibt kenne ich sie nicht...

Man ann das ganze noch in eine nette kleine Schleife Verpacken...



```
ON #Eintragen
O #Eingetragen
SPB NILO
 
L 102   // StartWert
T MW490
 
NEXT: nop 0
 
L MW490 // Dekrementieren
L 2
-I
T MW490
 
L MW490
L 2
+I
T MW 492
 
AUF DB100
L DBW[MW490]
T DBW[MW492]
 
 
L MW490
L 0
>I
SPB NEXT
 
L #Neuer_Wert
T DBW[MW490]
 
SET
S #Eingetragen
 
NILO: nop 0
ON #Eintragen
R #Eingetragen
```
 
Könnte klappen.

dtsclipper


----------



## MK_Auto (19 Oktober 2009)

*Gibt es*

keine möglichkeit zu schieben ??
also wie nen bit schieberregister die Datenwörter schieben ??
Micha


----------



## dtsclipper (19 Oktober 2009)

Genau das macht das Ding doch.


```
L MW490 // Dekrementieren
L 2
-I
T MW490 // Altes Datenfach
 
L MW490
L 2
+I
T MW 492  // Neues Datenfach
 
AUF DB100
L DBW[MW490] // Lade aus altem Fach
T DBW[MW492] // Transferiere in das neue
```


----------



## MK_Auto (19 Oktober 2009)

*Danke aber heute verstehe*

ich das wohl icht mehr oder ich habe mich auch falsch ausgedrückt 
Also Wert kommt geht sage ich mal ins datenword 0
2 ter Wert kommt erster ins word 2 und der neue ins 0 
usw


----------



## vierlagig (19 Oktober 2009)

dtsclipper schrieb:


> Vierlagig bringt mich um.



die möglichkeit besteht, ja, durchaus! 

nehmen wir also nochmal meinen code her und modifizieren ihn ... hab heut abend aber eine leichte rechenschwäche ... könnte also sein, dass die schleife nicht ganz hinhaut...


```
*

      U     #xTrigger                   //neuer wert vorhanden
      SPBN  end

      L     #rValue            //da das schieben dauern kann
      T     #rValueTemp            //speichern wir uns den wert erstmal weg

      L     P#392.0
      //T     #dAdressTemp
      LAR1

      AUF   DB   100      
      L     98
next: T     #iLoopCounter

      L     DBD [AR1,P#0.0]             //Wert in das
      T     DBD [AR1,P#4.0]             //nächste Fach schreiben

      //L     #dAdressTemp    
      TAR1  //neu
      SRD   3
      +     -4
      SLD   3
      //T     #dAdressTemp 
      LAR1  //neu
      
      LOOP  next

      L     #rValueTemp
      T     DB100.DBD  0

end:  NOP   0
```


----------



## Kai (19 Oktober 2009)

MK_Auto schrieb:


> Hallo zusammen suche eine einfache Lösung um einen wert in den DB zu schreiben und bei dem nächsten wert immer einen weiterzuschieben also das die Werte praktisch gespeichert werden.


 


MK_Auto schrieb:


> Also Wert kommt geht sage ich mal ins datenword 0
> 2 ter Wert kommt erster ins word 2 und der neue ins 0
> usw


 
Du könntest mit einem FIFO-Speicher arbeiten:

http://www.sps-forum.de/showpost.php?p=215073&postcount=3

http://www.sps-forum.de/showpost.php?p=215075&postcount=4

Gruß Kai


----------



## MK_Auto (19 Oktober 2009)

*Ok*

ich vrstehe das irgendwie nicht ist vieleicht schon zu spät heute danke erstmal werde mich morgen damit beschäftigen


----------



## Kai (19 Oktober 2009)

MK_Auto schrieb:


> ich muss immer in der lage sein die 100 Werte auszudrucken daher in DB und dann über Panel im Protokol einlesen und drucken


 
Wenn Du Dein Panel mit VBScript programmieren kannst, dann könntest Du den FIFO-Speicher auch direkt als VBScript im Panel programmieren.

Siehe dazu das nachfolgende Programmbeispiel für WinCC flexible:

http://www.sps-forum.de/showthread.php?t=22745

Gruß Kai


----------



## MK_Auto (19 Oktober 2009)

*Danke Kai*

habe mich mit der Materie noch nicht beschäfzigt geht das beim op77b ?? und kann man das auch drucken ??
Gruß Micha


----------



## Kai (19 Oktober 2009)

Das OP77B kann man leider nicht mit VBScript programmieren.

Gruß Kai


----------



## MK_Auto (19 Oktober 2009)

*Danke Kai*

also hilft es doch nur alle 100 Variabeln im Protokoll einzutragen


----------



## vierlagig (19 Oktober 2009)

MW hatte im chat grad den FC90(??sicher war er sich auch nicht) ins feld geworfen ... der kann das schieberegister wohl auch in K*U*P


----------



## MW (19 Oktober 2009)

Wenn du in AWL nicht so fit bist, kannst du auch einen fertigen Baustein aus der Siemens Lib nehmen, dass ist der FC90 "WSR" aus der Standart Library->TI-S7 Converting Blocks. Der stellt die von dir benötigte Schiebefunktion bereit.

Ja der VL war wieder schneller oder ich zu langsam


----------



## fmbux (20 Oktober 2009)

Hallo Micha,

ich weiß nicht ob Du in SCL fit bist. Mit 20 Zeilen Code wäre das Problem sicher
abgeschlossen. Sogar noch mit einem Zeitstempel zu dem Wert und einem
zusätzlichen Bit das nach 100 Werten gesetzt wird und was Du dann in Deinem
Panel, als Bitmeldung, zum autom. Ausdruck des Protokolls verwenden kannst.

Hier die Grundidee :

VAR
   Datenpuffer :  ARRAY[0..99] OF 
                                          STRUCT
                                                  Wert : INT ; //Format evtl. ändern
                                                   Datum : DATE_AND_TIME ; //mit READ_CLK  
                                          END_STRUCT ;
END_VAR

Der zugehörige Instanzdatenbaustein mit 100 Indexvariablen wird dann automatisch angelegt.

Jetzt muß man einmal eine FOR-Schleife durchlaufen und die Werte jeweils eine Indexvariable nach vorn kopieren und den neuen Wert in das letzte Fach eintragen.
In der FOR-Schleife dann eine Varable jeweils um +1 erhöhen und bei 100, ein Bit zum
Ausdrucken des Protokolls setzen und vom Panel wieder zurücksetzen.

Gruß fmbux


----------



## PN/DP (20 Oktober 2009)

*Umkopieren mit SFC20 "BLKMOV"*

Hallo Micha,



MK_Auto schrieb:


> also der zu letzt gemessene muss oben stehn





MK_Auto schrieb:


> dachte halt es gibt ne funktin wo man die int im DB komplett verschieben kann


Muß der zuletzt gemessene Wert unbedingt oben = am Anfang des Array stehen?

Üblicherweise steht am Anfang der älteste Wert und am Ende der neueste Wert.
Dann sind die Meßwerte historisch richtig sortiert, so daß das Array auch gleich 
als Trendkurve ausgegeben werden kann (ältester=Links, neuester=Rechts).

Und dann kann man statt der Schleife eine fertige Funktion für das Umkopieren der 
99 Meßwerte vor dem Einspeichern des neuen Wertes benutzen: *SFC20 "BLKMOV"*
Der SFC20 kopiert immer aufsteigend und benötigt nur etwa ein siebtel der Zeit 
einer Schleife.

```
U     #Trigger
      SPBN  END

      CALL SFC20
       SRCBLK :=P#DB100.DBX 2.0 WORD 99
       RET_VAL:=#Temp_Int
       DSTBLK :=P#DB100.DBX 0.0 WORD 99

      L     #Messwert
      T     DB100.DBW 198

END:  NOP   0
```
Aber wie gesagt, SFC20 geht nur, wenn der neueste Meßwert unten/hinten steht.

Gruß Harald


----------



## vierlagig (20 Oktober 2009)

PN/DP schrieb:


> Aber wie gesagt, SFC20 geht nur, wenn der neueste Meßwert unten/hinten steht.



nicht unbedingt, man kann ja zweimal kopieren, in einen tempDB auslagern und beim zurückkopieren nur die 99 werte übernehmen ... aber zykluszeittechnisch sollte das aufs selbe wie das shiften rauskommen ... man kann es allerdings in K*U*P machen...


----------



## MK_Auto (20 Oktober 2009)

*Also Danke*

erstmal an alle die mir geholfen haben ja der letzte Wert muss oben stehen Zeit denke ich ist relativ es werden mit ner 313c nur die werte ausgelsen und eine bewegung und nen paar Lampen mehr macht das ding nicht ok es sind 3 mal 100 werte aber sollte funzen 
nein mit er Hochsprache habe ich mich leider noch nicht beschäftigt 
Micha


----------



## MK_Auto (20 Oktober 2009)

*oki*

danke der baustein vom kai hat mir sehr geholfen habe noch abschließend ne frage weiß ist die falsche rubrik aber bekomme ich die Daten auf einen schlag ins OP 77B
oder Variable für Variable
Micha


----------



## Flinn (20 Oktober 2009)

PN/DP schrieb:


> Der SFC20 kopiert immer aufsteigend und benötigt nur etwa ein siebtel der Zeiteiner Schleife.



Hi PN/DP,

mal so 55% Offtopic:

Wie macht der SFC20 das eigentlich in 1/7 der Zeit einer Schleife?
Ist in dem SFC nicht auch nur "normaler" AWL-Code? Wenn ja, AWL ist ja bekanntlich sehr Maschinencode-nahe.  Hmmm, wie geht's denn dann noch schneller?  Grübel... Werde ich heute wohl nicht schlauer ins Bett gehen können...

Gruß
Flinn


----------



## PN/DP (22 Oktober 2009)

*Benchmark*



Flinn schrieb:


> Wie macht der SFC20 das eigentlich in 1/7 der Zeit einer Schleife?
> Ist in dem SFC nicht auch nur "normaler" AWL-Code? Wenn ja, AWL ist ja bekanntlich sehr Maschinencode-nahe.


Vielleicht hat der in S7-300 verbaute Prozessor einen Blockmove-Befehl im Microcode (MOVSB)?
Vielleicht arbeitet die SFC20 auch mit Speicheradressen in einem Flat-Modell und muß nicht für
jeden Speicherzugriff die DBx.DBWy-Adresse auf die tatsächliche Speicheradresse umrechnen?

Auch AWL ist nur eine (Hardware-nah aussehende) Interpretersprache. Der SFC20 ist aber schon 
in echtem Maschinencode in der Firmware der CPU enthalten.

Das für uns Programmierer zugängliche AR1-Register enthält nur den "halben" Pointer (nur den 
Offset zum Beginn des DB). Der Prozessor muß bei jedem AWL-Zugriff auf den Speicher den Wert im 
AR1 prüfen, die Nummer des aktuell geöffneten DB (Selektor) ermitteln, dann aus einer Tabelle die 
Anfangsadresse dieses DB auslesen und zum Offset aus dem AR1 addieren. Der SFC20 macht diese 
Prüfung und Berechnung nur einmal.

Ich hatte mal für eine Thema, wo es um das Umspeichern von 2879 INT-Werten in einem FIFO ging, 
auf einer echten CPU 315-2PN/DP (315-2EH13) verschiedene Programmversionen programmiert und 
die benötigte Bearbeitungszeit gemessen: jede Minute einen Datensatz aufzeichnen

```
Normal verständliche AWL-Schleife    : 19,3ms
Optimierte Schleife                  : 16,2ms
2 INT-Werte gleichzeitig umspeichern :  8,7ms
mit SFC20 umspeichern                :  2,7ms
```
Daher kommt meine Aussage, daß der SFC20 nur ein siebtel der Bearbeitungszeit einer in AWL 
programmierten Programmschleife benötigt.

Manche Sachen muß man einfach in der Praxis ausprobieren, um solche Erkenntnisse zu gewinnen.

Gruß Harald


----------



## Flinn (22 Oktober 2009)

PN/DP schrieb:


> CPU 315-2PN/DP




Vielen Dank für die interessante Info, PN/DP.
Jetzt erklärt sich auch dein Nickname.

Gruß
Flinn


----------

