# awl schleife und pointer



## Iserlohner (17 Februar 2011)

Hallo erstmal,
also nachdem ich jetzt vieles hier im forum über pointer und schleifen gelesen habe muss ich doch mal nachfragen....
Ich habe diesen Beitrag zwar verstanden: http://www.sps-forum.de/showthread.php?t=8887

aber da ich noch nie mit pointern in s7 gearbeitet habe blick ich nicht durch....

mein problem bzw vorhaben.....

ich habe einen Datenbaustein siehe bild "db"
in diesem db sind Zeitwert_soll und Zeitwert_rest bereits beschrieben...
nun möchte ich Zeitwert_ist einfach mit ist=soll-rest ausrechnen..
damit ich nun aber nicht 256 mal diese rechnung ausführen muss dachte ich an eine schleife  von 1-256 mit pointern die jeweils auf soll, rest und ist zeigen.....

ich verzweifel grad an der syntax..... danke im vorraus


----------



## vierlagig (17 Februar 2011)

Iserlohner schrieb:


> ich verzweifel grad an der syntax..... danke im vorraus




ich seh keine.


----------



## IBN_Christian (17 Februar 2011)

Einfacher wäre es in SCL zu programmieren


```
FOR i:= 1 TO 256 BY 1 DO

ZeitwertIst[i] = ZeitwertSoll[i] - ZeitwertRest[i];

END_FOR;
```


----------



## wolder (17 Februar 2011)

Hallo Christian,

so einfach wie du es beschreibst ist es aber gar nicht.
Da solltest du schon mehr Info geben.
Vor allem auch die Zeitwert-Variablen-Deklaration.

Gruß wolder

P.S.: Ich kann die Info nicht geben, da ich das selber nicht weiß. Hab das zwar mal mit SCL probiert, aber kläglich gescheitert.


----------



## wolder (17 Februar 2011)

```
L  P#0.0                           //Anfangswert des Pointers
     LAR1                                //in das Adressregister schreiben
     L 256                               //Schleifenzähler auf 256
anf:T MW30                           //vorbelegen und im MW30 zwischenspeichern
     AUF DB121
     L DBW[AR1,P#0.0]             //hole aus dem DB das DBW0 (erster Durchgang)
     BTI                                 //Umwandeln in Integer
     L DBW[AR1,P#1024.0]        //hole aus dem DB das DBW1024 (erster Durchgang)
     -I                                   //Subtraktion
     T DBW[AR1,P#512.0]         //schreibe ins DBW512 (erster Durchgang)
     +AR1 P#2.0                     //addiere zu dem Adressregister den Pointerwert 2.0
     L MW30                          //Lade den Schleifenzähler
     LOOP anf                        //subtrahiere mit 1 und springe nach anf, wenn das Ergebnis > 0 ist.
```
Absolut ungetestet und bestimmt noch mit Fehlern.
Gruß wolder

Edit: Ich hoffe die Kommentierung reicht aus


----------



## Iserlohner (17 Februar 2011)

@wolder kannst du den ansatz bitte mal kommentieren.......


ich hatte so angefangen

      AUF   "DB_Zeiten"
      L     257
      L     1
      -I    
      T     #index
anf:  NOP   0
      L     #index
      SLD   3
      LAR1  

      L     DBW [AR1,P#0.0]


----------



## Iserlohner (17 Februar 2011)

@christian...

ich hab noch nie mit scl gearbeitet,
dier schleife ist ja verständlich für mich, aber der rest drum rum, wir schreib ich dann "ist" in den db bzw lese "soll" und "rest" aus dem db


----------



## bike (17 Februar 2011)

Iserlohner schrieb:


> @christian...
> 
> ich hab noch nie mit scl gearbeitet,
> dier schleife ist ja verständlich für mich, aber der rest drum rum, wir schreib ich dann "ist" in den db bzw lese "soll" und "rest" aus dem db



Ich würde dir den Hinweis geben, denk bitte zuerst nach wie du Programmieren willst.
AWL oder SCL, womit hast du mehr Erfahrung und/oder Wissen.
Beides auf einmal für das selbe Programm ist doof.

bike


----------



## Iserlohner (17 Februar 2011)

hab mich für die awl lösung entschieden...

der vorschlag von wolder klappt soweit....

 L     P#0.0
      LAR1  
      L     256
anf:  T     MW    30
      AUF   "DB_Zeiten"
      L     DBW [AR1,P#0.0]
      L     DBW [AR1,P#512.0]
      -I    
      T     DBW [AR1,P#1024.0]
      +AR1  P#2.0
      L     MW    30
      LOOP  anf






zur info, ich zeige mir die werte alle an nem op77 an...
dbw0 bis dbw510 sind ja s5time werte,  und dbw512 bis dbw1022 sind integer werte, aber nun steht der wert in dbw1024 bis 1534 aber als hex was muss ich tun um die zeit als s anzuzeigen????
ich hampel grad mit der linearen skalierung rum, die kapier ich wohl nicht richtig....
für "soll" und "rest" hab ich die Skalierung auf 0-6000 und 0-6 eingestellt, bin ich aber ehrlich gesagt nur durch langes probieren dran gekommen....
für "ist" also den errechneten wert der nun als hex vorliegt komm ich an keine sinnvolle richtige anzeige,,,,,,


----------



## vierlagig (17 Februar 2011)

S5TIME ist eine BCD-codierte Darstellung von Zeitwerten mit Hilfe einer ebenfalls in diesem Datentyp codierten Zeitbasis...

einfach mal den Aufbau angucken und eine Umrechnung schreiben


----------



## wolder (17 Februar 2011)

Oh stimmt.
Die Zeiten waren ja einmal in S5-Time und dann als WORD.

Wo kommen die WORD-Werte denn her?
Ich nehme an, dass das der DUAL-Ausgang vom Timer ist oder ist das der DEZ-Ausgang des Timers?

Der DEZ-Ausgang ist ja bereits eine S5-Time.
Dann könntest du deine Einstellung in dem DB auf S5Time ändern. Dann sollte der Code wieder passen.

Bei dem OP bin ich gerade überfragt. Kannst du da bei der Anzeige nicht S5-Time als Einstellung vorgeben?

Dann bräuchtest du keine Umrechnung mehr. 
Edit: Ist natürlich quatsch! Umrechnen musst du trotzdem.

Gruß wolder


----------



## Iserlohner (17 Februar 2011)

@wolder:
also die werte "rest" kommen von dem DEZ Ausgang des Timers...
und weil ich keine s5time am OP77 anzeigen kann deshalb als word, dann bekomme ich am display über die lineare skalierung den wert richtig angezeigt... 

@vierlagig:
Habe das format des datentypes s5time hier vorliegen und auch kapiert....
BIT 14&15 ohne funktion,bit 12&13 für die Zeitbasis und 0bis11 der zahlenwert...
aber wo soll ich nun was machen?


----------



## vierlagig (17 Februar 2011)

die Formate anpassen!
bzw. stimmen die ja bei Dir, es handelt sich beides mal um S5TIME, aber womöglich mit unterschiedlicher Zeitbasis. und aber auch bleibt es eine BCD-codierte Zahl, die kann man nicht so einfach mit der Festpunkt-Arithmetik erschlagen, da muß man schon mal umwandeln...

also: erster Schritt, Zeitbasis überprüfen -> ggf. anpassen und merken
zweiter Schritt, Zeitbasis eliminieren
dritter Schritt, BCD -> INT
vierter Schritt, Differenz bilden
fünfter Schritt, INT -> BCD
sechster und finaler Schritt, Zeitbasis setzen


----------



## Iserlohner (17 Februar 2011)

@wolder:

habe jetzt im db alle datentypen auf s5time geändert und die Anzeige des DEZ Ausgang des Timer "rest" dbw 512 bis 1022, klappt am display immer noch.....


jetzt bleibt nur das problem mit dem richtigen errechnetem wert...
der steht an der richtigen stelle im db also die pointer und schleife und so klappt prima...danke.....
aber der errechnete oder geschriebene wert wie auch immer passt nicht...


----------



## wolder (17 Februar 2011)

Was sind das denn für Zeitwerte (Soll)?
Sind die immer mit dem Faktor sekunden?

Der Dual-Ausgang gibt dir ja die "reinen" Zahlen aus, ohne Multiplikator.
Wenn der Zeitwert_soll immer im Sekundenbereich liegt, dann kannst du das relativ einfach umwandeln.

Aber sag uns erstmal wie der TW-Eingang des Timers beschaltet ist.

Stell vielleicht mal ein Bild zu Verfügung wie dein Programm aussieht, dann wirds wahrscheinlich einfacher.

Gruß wolder

Edit: zu langsam, 4L war schneller. Darauf wollte ich hinaus.


----------



## Iserlohner (17 Februar 2011)

also ich nehme einfach nen timer:

 U     E    124.6
      L     "DB_Zeiten".Zeitwert_soll[50]
      SE    T    333
      NOP   0
      NOP   0
      LC    T    333
      T     "DB_Zeiten".Zeitwert_rest[50]
      NOP   0



jetzt kommt der sollwert durch ne eingabe vom display in sekunden
und der restzeit und istzeit sollen angezeigt werden...
siehe bild über skalierung..


----------



## wolder (17 Februar 2011)

Das hab ich mir gedacht.
Durch das Format Timer in WinCC Flexible gibst du die Zahl in Form von ms an.
Durch die Skalierung bekommst du die Zahl als sec.
So weit, so gut.
Allerdings vergibt die CPU den Multiplikator selbst. Das heißt, dass du gar nicht weiß welchen Multiplikator du wirklich hast.

Wie wäre es denn, wenn du die Zahl im OP als WORD-Größe ohne Skalierung in die CPU schreibst (als Hex). Somit hast du schon den Hex bzw. BCD-Wert richtig.
Was du jetzt noch vor dem Timer-Starten machen musst, ist den Multiplikator von Hand erzeugen.

```
L     "DB_Zeiten".Zeitwert_soll[50]
L 2#0010000000000000             //Multiplikator von Hand erzeugen
OW
SE T333
```
Dann kannst du den DUAL-Ausgang des Timers nehmen und ihn im DB ablegen.
Beim Rechnen musst du dann den Zeitwert_soll noch in einem Integer umwandeln und Subtrahieren. Dann kannst du den Restwert als Integer im OP anzeigen.

Ich ändere das mal im Beispiel.

Gruß wolder


----------



## wolder (17 Februar 2011)

So, ich mach Feierabend.
Ich hoffe, dir geholfen zu haben.
Ansonsten sind ja auch noch andere hier.
Ich schau morgen wieder rein.

Schönen Feierabend euch allen.

Gruß wolder


----------



## Iserlohner (18 Februar 2011)

guten morgen....

so ich hab mal deine tips weiter befolgt, wolder.....

dabei geht mir die sps in störung, wenn ich für "soll" werte eingebe am display...
komischewrweise nicht bei jedem wert....
siehe Bild "OK" bei zB "55" oder "5" oder "87" nimmt er den wert an,
Gebe ich eine "10" oder "15" ein geht die sps auf störung siehe Bild...

was dann noch komisch ist, "rest" + "ist" ergibt immer den selben rechnerichen wert, aber nicht den sollwert.... 
siehe bild, soll=55 aber er zählt runter von 37....


----------



## vierlagig (18 Februar 2011)

ja, ja, nicht jeder kann mit BCD rechnen


----------



## Iserlohner (18 Februar 2011)

ich anscheinend nicht....

wo liegt der fehler?


----------



## vierlagig (18 Februar 2011)

```
S5TIME:

  7  6  5  4  3  2  1  0  7  6  5  4  3  2  1  0
  -  -  x  x  <-------------- BCD ------------->
        0  0 - 0,01s
	0  1 - 0,1s
	1  0 - 1s
	1  1 - 10s
		
BCD:
  7  6  5  4  3  2  1  0  7  6  5  4  3  2  1  0
  x  -  -  -  <-------------- BCD ------------->
  0 - +
  1 - -
```

deswegen sag ich 





> zweiter Schritt, Zeitbasis eliminieren


darüber hinaus ist darauf zu achten, dass die tetraden der BCD zahlen nur gültige werte von 0-9 haben, was man bei eingabe im format WORD nicht garantieren kann ... aber man kann ja eine INT-BCD-wandlung durchführen...

am besten allerdings wäre sich von den S5timern zu verabschieden und was vernünftiges zu nehmen


----------



## wolder (18 Februar 2011)

Ich kenn das OP77 jetzt nicht auswendig, aber so wie es auf dem Bild aussieht, kann man keine Hex-Zahlen eingeben. Also eh nur Zahlen von 0-9. Demnach bräuchte man keine Umwandlung von INT nach BCD.

Fragen:
- Hast du das SOLL-EA-Feld auch angegeben, dass die Zahl im Hex-Format ist und die Variable vom Typ WORD und nicht Timer?
- Schreibst du den DUAL-Ausgang ("INT"-Wert in sec) vom Timer in den DB?

Gruß wolder


----------



## vierlagig (18 Februar 2011)

wolder schrieb:


> Ich kenn das OP77 jetzt nicht auswendig, aber so wie es auf dem Bild aussieht, kann man keine Hex-Zahlen eingeben. Also eh nur Zahlen von 0-9. Demnach bräuchte man keine Umwandlung von INT nach BCD.



eingabe 15 als word: 1111d
aber BCD: 0001 0101d


----------



## wolder (18 Februar 2011)

Wenn ich aber bei dem EA-Feld als Darstellung Hexadezimal angebe, dann ist die Eingabe, die ich tätige, schon im Hex-Format. Und da ich auf den ersten Blick bei dem OP77 keine Eingabe mit A-F machen kann, habe ich ziemlich sicher immer einen BCD-Code.

Gruß wolder


----------



## Iserlohner (18 Februar 2011)

danke wolder... das war der fehler...

ich habe bei der eingabe am op "dezimal" nicht "hex" angegeben....


----------



## vierlagig (18 Februar 2011)

wolder schrieb:


> Wenn ich aber bei dem EA-Feld als Darstellung Hexadezimal angebe, dann ist die Eingabe, die ich tätige, schon im Hex-Format. Und da ich auf den ersten Blick bei dem OP77 keine Eingabe mit A-F machen kann, habe ich ziemlich sicher immer einen BCD-Code.
> 
> Gruß wolder



angenommen du hast recht, wo vermutest du dann den wandlungsfehler, den er uns im screenshot präsentiert hat?


----------



## wolder (18 Februar 2011)

Dass er die Eingabe eben nicht im Hex-Format macht, sondern im Integer.
Da geht die SPS bei z.B. 10 in Störung, da ja 10(int) nicht BCD-Code ist.

Aber das ist halt nur ne Vermutung.

edt: Vermutung hat gestimmt.


----------



## Iserlohner (18 Februar 2011)

Also Leute vielen Dank...

Ich glaube wir können das Thema beenden, werde aber bestimmt wieder mal eure Hilfe benötigen also weiter so und vielen vielen Dank.......... 


Euer Marc...


----------

