Step 7 INT (DINT) Differenzen berechnen mit Überlauf und negativen Werten

Senator42

Level-2
Beiträge
927
Reaktionspunkte
80
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Forum

Aufbau:
S7 Classic !

S7-300 und eine Zählerkarte an der ein Inkrementagleber (Spur A,B,Z) angschlossnen ist.
Aus dem Register kann ich den akt. Zählerstand lesen.

nun Vorwärtsbewegung:
0 ... 32767, dann -32768 ... bis -1, dann 0, danach wieder 1...32767


Problem:
bei jedem neuen OB1-Durchlauf möchte ich die Differenz zum letzten OB1-Durchlauf erhalten.

Beispiel 1:
alter wert: +32760, aktWert +32767, diff = +7 soweit OK

Beispiel 2:
alter wert: +32767, aktWert -32750, diff = -65517 geht nicht: Zahlenbereich zu gross
die Rechnung +32767 - 32750 ergibt +17
32767=7FFFh; -32750=8012h; diff ist aber 19

Wie bekomme ich das in den Griff ?

Die Beispiele sind jetzt zum Verständnis 16 Bit.
Tatsächlich habe ich 32 Bit.
Also DINT, und damit kann ich die Zahl nicht auf den nächst größeren Bereich hochziehen, wie mit ITD.

Was mir noch einfällt:
Die DINT in REAL wandeln und damit arbeiten. Ich weis aber noch nicht, ob mir dadurch ein paar Werte im Einerbereich "durch die Lappen" gehn, und das ganze damit zu ungenau wird.


Verwendungszweck / Maschine:
an einer Position wird ein Teil gemessen.
Ist das Ergebnis "Ausschuss", dann schreibe ich eine Konstannte in ein DB.DBD[n].
Bei jedem OB1-Durchlauf möchte ich DB.DBD[n] um die Differenz (diff) verringern.
Wenn im DB.DBD[n] 0 oder kleiner steht, wird ausgeworfen in den Ausschuß.
Das DB.DBD[n] wäre nun wieder frei für eine weitere "Verwendung". Belegungsbitmap.
Ich habe so viel DB.DBDs, wie in die Strecke an Teilen passt.

Das ergibt quasi ein Schieberegister.
Die Konstannte ist der Weg von Mesßstelle zum Ausschuß.

----
Ich habe schon herumprobiert (mit Excel):
7ffe 32766
7fff 32767
ffffff8000 -32768
ffffff8001 -32767
ffffff8002 -32766
ffffffffff -1

Das Problem hierbei ist die 8000h wo ich als Differenz ABS 1 bekomme
bei 8001h dann ABS aber 0, was aber zu 32767 (7FFF) ja 2 ist.

Steh grad im Regen !
 
Hallo,
ich würde es wie folgt machen :
- du machst deinen Zählerstand erstmal zu einem DINT
- ist der Folgewert > als der letzte Wert dann bildest du die Differenz wie schon von dir geschildert
ist der Folgewert kleiner als der letzte Wert (oder Negativ) dann addierst du 65536 drauf und bildest dann die Differenz ...

Gruß
Larry

Korrigiert wegen zunächst falschen Offset ...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Solange die Zählerstand-Differenz von einer Abfrage zur nächsten nicht größer als 32767 Inkremente ist bei 16-Bit INT (bzw. 2147483647 bei 32-Bit DINT), kann man einfach subtrahieren und braucht den Überlauf nicht beachten - die Differenz ist automatisch richtig. :D Das hat die Zweierkomplement-Darstellung von Integer/Ganzzahlen so an sich :cool:

Schau mal dieses Codebeispiel für die Differenzberechnung und anschließendes Aufsummieren auf eine relative Position

Harald
 
Solange die Zählerstand-Differenz von einer Abfrage zur nächsten nicht größer als 32767 Inkremente ist bei 16-Bit INT (bzw. 2147483647 bei 32-Bit DINT), kann man einfach subtrahieren und braucht den Überlauf nicht beachten - die Differenz ist automatisch richtig. :D Das hat die Zweierkomplement-Darstellung von Integer/Ganzzahlen so an sich :cool:
Antwort von Radio Eriwan: Im Prinzip ja, aber:
Falls der Positionsgeber nicht die vollen 16 Bit oder 32 Bit liefert, sondern weniger Bits, dann ist es wichtig, dass man vor der Differenzbildung die Positionswerte vorzeichenrichtig auf 16 bzw 32 Bit erweitert.
Gruß
Erich
 
Noch ein Trick bei Zählern > 16 Bit: man muß gar nicht den vollen Zählerstand von 32 Bit oder 24 Bit oder xx Bit nutzen, man kann auch einfach nur die unteren 16 Bit verwenden und mit 16-Bit-Operationen rechnen. Das Ergebnis wird nicht ungenauer, es muß nur sichergestellt sein, daß die Differenz zur vorherigen Abfrage nicht größer als +/- 32767 ist. Im Prinzip würde sogar ein 8-Bit-Zähler reichen, wenn zwischen den Abfragen nicht mehr als 127 Impulse eingehen können - der Hardware-Zähler muß nur die max mögliche Zählerstandveränderung puffern können für den Zeitraum zwischen den Zählerstand-Abfragen. Nur die kleine Zählerstandveränderung (Differenz) ist interessant wenn man die Differenzen auf eigene Zählerstandsvariablen aufaddiert.

Harald
 
Zurück
Oben