Teil eines DINT's-Wert kopieren

churchill

Level-2
Beiträge
193
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

Eine Anlage liefert mir über Ethernet ein 8-stelliger DINT-Wert, z.B.
57081201 was die Sorten-Nr. des produzierten Papiers entspricht. Je nach Papiersorte ändert sich diese Nummer sowie auch die Grammatur die aber immer 3-Stellig bleibt..

Frage: Ich sollte aus dieser DINT-Nummer die 4., 3., und die 2.-letzte Stelle auf ein anderes DBD od. DBW kopieren. Also in diesem Fall wäre es den Wert 120, was die Grammatur des Papiers entspricht.

Beispiel: DB300.DBD20 -> 57081201-> 120 auf DB301.DBD od. DBW20

Hat jemand von euch einen Hinweis, Tips, oder sogar eine elegante Lösung in der Schublade? Wäre euch sehr dankbar. Bin nämlich noch nicht auf das Resultat gekommen. :roll:

Besten Dank im voraus.
mfG churchill
 
Hallo,
wenn ich das Problem richtig verstanden habe, handelt es sich um einen 32-Bit Hex-Wert also um DW#16#57081201.
Dann sollte dieses Programm dein Problem lösen.

L DB300.DBD20 // Wert von der Anlage (z.B. DW#16#57081201)
SRW 4 // rechte Tetrade rausschieben
L W#16#FFF // Maske für die 3 Stellen
UW
T DB301.DBW 20 // ins Ziel kopieren

mfg. Rayk :D
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo churchill,

so wird's gehen, falls es sich tatsächlich um DINT (32-bit-Festpunktzahl) handelt:


Code:
      L     L#57081201                  //bzw. DB200.DBD..
      L     10
      /D    
      L     1000
      MOD                               //Ergebnis im Akku1



Gruß, Onkel
 
Titel: Teil eines DINT's-Wert kopieren mit Stringverarbeitun

Hallo Churchill,

ein weiterer Vorschlag:
Den DINT Wert mit den String IEC-Funktionen bearbeiten.
DINT mit FC 5 in String umwandeln
die drei Ziffern mit FC26 herauskopieren
Rueckwandlung auf DINT oder Int mit FC37 oder FC38
 
DINT

Hallo,

man kann aber auch den DINT-Wert in BCD wandeln, dann 4 Stellen nach rechts schieben, den linken Teil ausfiltern (Vorzeichen??) und dann wieder in INT oder DINT wandeln.

MfG
André Räppel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Erstmals vielen Dank für eure Hilfsbereitschaft.
Die Lösung mit den Strings hab ich auch schon ausprobiert--->ist aber für das Resultat das ich brauche viel zu aufwändig und geschwollen :wink:, trotzdem vielen Dank.
Der Lösungsvorschlag von André werde ich sicherlich ausprobieren, vielen Dank.
Da es sich um eine 32-Bit-Festpunktzahl handelt hab ich die Lösung von Onkel Dagobert verwendet, was auch wunderbar funktioniert. Besten Dank.
Eigentlich wenn man es sich genauer anschaut und überlegt, ist es ziemlich einfach. Ich sollte meine mathematische Kenntnisse wohl vertiefen müssen :D

Nochmals Vielen Dank an alle und einen schönen Sonntag.

mfG churchill
 
Hallo zusammen

Es erinnert mich an einen vergangenen Beitrag der ich noch eine Lösungserklärung schuldig bin.
Hier klicken
Naja, die Lösung ist eigentlich ganz simpel:

L #High_Word
L 10000
*D
L #Low_Word
+D
T #Ret_Val

Damit kann man die zwei Festpunktzahlen 16-Bit in einer 32-Bit zusammensetzen.

Ich möchte auch gestehen, dass ich den MOD-Befehl nicht gekannt habe.
Danke nochmals für eure Hilfe.

mfG churchill
 
gern geschehen

Hallo churchill,

gern geschehen :p !

Ich denke mal, daß es nicht viele Anwendungen gibt bei der die MOD-Rechnung sinnvoll eingesetzt werden kann. Wer braucht in einer Steuerung schon den Rest einer ganzzahligen Division? Daher wird sie sicherlich von vielen Programmieren beim Nachdenken oftmals garnicht berücksichtigt.

Ein sehr interessanter, eigentlich fast schon genialer Fall für die MOD-Anweisung ist die Berechnung eines Zeigers für ein Umlaufregister, ein FiFo oder auch für einen Aufrufverteiler. Es geht mit MOD sehr viel eleganter als mit Vergleichen und Rücksetzen des #REGISTER_ZEIGER über Sprungbefehle. Bei jedem Aufruf wird #REGISTER_ZEIGER um 1 erhöht. Ist #REGISTER_ZEIGER=#MAX_ANZAHL, liefert MOD das Ergebnis "0" und es wird wieder von vorne gezählt.

Code:
//*** Umlaufregister mit MOD
      L     #REGISTER_ZEIGER
      L     #MAX_ANZAHL
      MOD   
      T     #REGISTER_ZEIGER            // 0..(MAX_ANZAHL-1)

//*** Register-Bearbeitung
      ...
      ...

//*** Pointer erhöhen
      L     #REGISTER_ZEIGER
      L     1
      +I    
      T     #REGISTER_ZEIGER

Gruß, Onkel
 
naja ich glaub so das optimale für ein sr ist der befehl doch nicht...

1. geht nicht bei registern die in beide richtungen laufen (zeiger wird nicht auf <0 überwacht)

2. wenn die registerbreite nicht durch die registerlänge teilbar ist, oder einfach nur der zeiger (aus welchen gründen auch immer) "verrutscht" läuft er über das registerende hinaus weil die mod anweisung ja nur "0" liefert wenn er genau die registerlänge erreicht.
 
Hallo Markus,

Markus schrieb:
naja ich glaub so das optimale für ein sr ist der befehl doch nicht...

1. geht nicht bei registern die in beide richtungen laufen (zeiger wird nicht auf <0 überwacht)

Das verstehe ich nicht so ganz. Der Zeiger wird niemals <0.



Markus schrieb:
2. wenn die registerbreite nicht durch die registerlänge teilbar ist, oder einfach nur der zeiger (aus welchen gründen auch immer) "verrutscht" läuft er über das registerende hinaus weil die mod anweisung ja nur "0" liefert wenn er genau die registerlänge erreicht.

In diesen (aus welchen gründen auch immer) :D - Fällen hat man natürlich ein Problem, egal wie man den Zeiger berechnet. Zur Adressierung könnte man bei Bedarf ein Offset dazuaddieren.


Gruß, Onkel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Onkel Dagobert schrieb:
Das verstehe ich nicht so ganz. Der Zeiger wird niemals <0.

Code:
u rueck             //zb förderkette
spb rueck

l zeiger
l registerbreite
+i
t zeiger


rueck nop 0

un reuck
spb end

l zeiger
l registerbreite
-i
t zeiger                            // dieser zeiger darf nicht <0 werden wenn die
                                      // kette lange rückwärts läuft

end: nop 0
 
Zurück
Oben