Step 7 String Zahl in INT

EPaulo

Level-1
Beiträge
91
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich versuche gerade eine Zahl die ich in einem String empfange in eine Int zu wandeln so das sich sie für weiter zwecke verwenden kann.
Aber es will nicht so recht funktionieren.

Im Bild zu sehen ist das ich die Zahl 98 empfange, aber in der ausgabe an mein Variable RCV_BYTE (ist ein INT) steht dann nur DEZ 51 statt der 98.

L #RCV_BUFFER.RCV_BYTE[4] // 1. Zeichen
L #RCV_BUFFER.RCV_BYTE[3] // 2. Zeichen
SLW 4
OW
L #RCV_BUFFER.RCV_BYTE[2] // 3. Zeichen
SLW 8
OW
L #RCV_BUFFER.RCV_BYTE[1] // 4. Zeichen
SLW 12
OW
T #RCV_BYTE

////////////////////////////////////////////////////////////////

L #RCV_BUFFER.RCV_BYTE[4] // 1. Zeichen
L 48
-I
L 10
>I
TAK
SPBN WZ1
L 7
-I
WZ1: T #RCV_CUT // Wert


L #RCV_BUFFER.RCV_BYTE[3] // 2. Zeichen
L 48
-I
L 10
>I
TAK
SPBN WZ2
L 7
-I
WZ2: L 16
*I
L #RCV_CUT
+I
T #RCV_CUT // Wert erhöhen um 2. Stelle


L #RCV_BUFFER.RCV_BYTE[2] // 3. Zeichen
L 48
-I
L 10
>I
TAK
SPBN WZ3
L 7
-I
WZ3: L 256
*I
L #RCV_CUT
+I
T #RCV_CUT // Wert erhöhen um 3. Stelle


L #RCV_BUFFER.RCV_BYTE[1] // 4. Zeichen
L 48
-I
L 10
>I
TAK
SPBN WZ4
L 7
-I
WZ4: L 4096
*I
L #RCV_CUT
+I
T #RCV_CUT // Wert erhöhen um 4. Stelle

Bei dieser Methode steht dann 98 in der Variable aber 98HEX ich benötige aber 98DEZ





Was mach ich falsch, findet jemand den Fehler?

Danke im Voraus
 
Zuletzt bearbeitet:
Mit was programmierst du denn? TIA oder Classic?

In TIA gibt es dafür fertige Bausteine, bei Classic weiß ich es nicht....
 
Im Bild zu sehen ist das ich die Zahl 98 empfange
In welchem Bild?
Wie sieht denn die empfangene Zeichenfolge aus, die Du in einen INT umwandeln willst?

Dein Programmcode sind das zwei verschiedene Versuche?
Warum erzeugst Du im ersten Teil ein 16-Bit-Word und speicherst es in #RCV_BYTE (ein Byte?)
Im zweiten Programmteil wandelst Du einen Hexadezimal-String in ein INT - Warum das?

Üblicherweise entnimmt man von vorn nach hinten Zeichen für Zeichen aus der ASCII-Zeichenfolge, wandelt das ASCII-Zeichen in eine Dezimalzahl (Ziffer) (z.B. durch Subtraktion von 48 (der Wert des ASCII-Zeichens '0')), multipliziert den bereits umgewandelten Zahlenwert mit 10 und addiert die Ziffer. Dann erhält man eine Dezimalzahl.

In beiden Programmteilen multiplizierst Du jede Ziffer mit 16 anstatt mit 10 und erhältst deshalb eine BCD-Zahl anstatt eine Dezimalzahl. Du könntest nun trotz falschem Rechenweg am Ende einfach die BCD-Zahl in Dezimal wandeln mit der Anweisung BTD - besser wäre es aber, gleich richtig mit 10 zu multiplizieren.

In Step7 classic gibt es fertige Funktionen STRNG_I und STRNG_DI (in der Bibliothek "Standard Library/IEC Function Blocks").

Harald
 
@TE:
Wie von Paul geschrieben gibt es dafür auch einen fertigen FC (aus der Siemens-Bibliothek) der das macht. Das hat nichts mit SCL oder AWL zu tun. Und den gab es auch schon bei Classic ... 8)

Dessen ungeachtet ... wenn du deinen Hilfswert nicht mit 16,256,etc. multiplizieren würdest sondern mit dem Dekadenwert (1,10,100,1000) dann würde dein Baustein vermutlich auch funktionieren ...
Du erzeugst ja nun einen HEX-Wert ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Im String stehen die Zahlen bestimmt als ASCII-Code, oder ?

Dann von jeder Zahl W#16#30 abziehen und mit 1000, 100 10 oder 1 multiplizieren. Alle 4 Zahlen dann summieren und du hast deine Zahl im INT-Format. Oder bin ich jetzt auf dem falschen Dampfer ?
 
Dann von jeder Zahl W#16#30 abziehen und mit 1000, 100 10 oder 1 multiplizieren. Alle 4 Zahlen dann summieren und du hast deine Zahl im INT-Format. Oder bin ich jetzt auf dem falschen Dampfer ?
@LiLaStern:
Das ist doch das, was Harald in #4 schon geschrieben hat. Ob man nun 48 dezimal oder 30 hexadezimal subtrahiert ...
3 x 16^1 + 0 x 16^0 = 48
Wünsche Dir ein schönes (laaanges?) WE,
Gruss, Heinileini
 
Zuviel Werbung?
-> Hier kostenlos registrieren
L #RCV_BUFFER.RCV_BYTE[4] // 1. Zeichen
L #RCV_BUFFER.RCV_BYTE[3] // 2. Zeichen
SLW 4
OW
L #RCV_BUFFER.RCV_BYTE[2] // 3. Zeichen
SLW 8
OW
L #RCV_BUFFER.RCV_BYTE[1] // 4. Zeichen
SLW 12
OW
T #RCV_BYTE

Code:
// Version 1 ergänzt um 5 Anweisungen:
// 4 x Ausblenden der linken Tetrade (20 wird zu 00, 30 zu 00, 31 zu 01 ... 39 zu 09) durch UW W#16#0F
//     alternativ
//     "PseudoAusblenden" der linken Tetrade (30 wird zu 00, 31 zu 01 ... 39 zu 09) durch DEC 48 (Subtraktion von 48)
// 1 x Umwandlung von BCD in Dual
// DEC 48 ist ausreichend, wenn alle 4 Bytes keine anderen Zeichen als '0' ... '9' enthalten!
// UW W#16#0F ist besser: interpretiert zusätzlich ' ' (Leerzeichen) als 0 
// das ist sinnvoll, wenn im empfangenen String vorlaufende '0' durch ' ' ersetzt sind!
// 8ung: Enthält keine Prüfung auf unzulässige Zeichen! Auch Vorzeichen sind unzulässig!
//
L   #RCV_BUFFER.RCV_BYTE[4] // 1. Zeichen von rechts
[COLOR=#0000ff]UW  W#16#0F[/COLOR]   // linke Tetrade löschen oder mit [COLOR=#0000ff]DEC 48[/COLOR] subtrahieren von 48 bzw. 30hex
L   #RCV_BUFFER.RCV_BYTE[3] // 2. Zeichen von rechts 
[COLOR=#0000ff]UW  W#16#0F[/COLOR]   // linke Tetrade löschen oder mit [COLOR=#0000ff]DEC 48[/COLOR] subtrahieren von 48 bzw. 30hex
SLW 4         // entspricht Multiplikation mit 16
OW            // wahlweise ist +I oder +D möglich
L   #RCV_BUFFER.RCV_BYTE[2] // 3. Zeichen von rechts
[COLOR=#0000ff]UW  W#16#0F[/COLOR]   // linke Tetrade löschen oder mit [COLOR=#0000ff]DEC 48[/COLOR] subtrahieren von 48 bzw. 30hex
SLW 8         // entspricht Multiplikation mit 256
OW            // wahlweise ist +I oder +D möglich
L   #RCV_BUFFER.RCV_BYTE[1] // 4. Zeichen von rechts
[COLOR=#0000ff]UW  W#16#0F[/COLOR]   // linke Tetrade löschen oder mit [COLOR=#0000ff]DEC 48[/COLOR] subtrahieren von 48 bzw. 30hex
SLW 12        // entspricht Multiplikation mit 4096
OW            // wahlweise ist +D möglich
[COLOR=#0000ff]BTD[/COLOR]           // BCD int Dual konvertieren
T   #RCV_BYTE // "BYTE" in VariablenName ist irreführend ;o)
Dasgleiche noch einmal, aber mit umgekehrter Richtung der Abarbeitung der 4 Bytes.
Zusätzlich 2 überflüssige Befehle eingefügt: L 0 und das erste OW. Hier völlig nutzlos,
aber als zweiter Schritt hilfreich, wenn man vorhat, eine ProgrammSchleife daraus zu machen ...
... immerhin drängt sich dieser Gedanke auf, weil in dieser Variante (das ZwischenErgebnis!)
immer nur um 4 BitPositionen verschoben wird (das war der "erste Schritt").
Code:
L   0    // nur erforderlich, wenn nach dem ersten UW W#16#0F das OW steht
L   #RCV_BUFFER.RCV_BYTE[1] // 4. Zeichen von rechts
UW  W#16#0F   
OW       // Entbehrlich. Dient dem Angleichen an das sich wiederholende "Schema" weiter unten    
SLW 4    // schieben um jeweils "nur" 1 Tetrade, weil das ZwischenErgebnis geschoben wird     
L   #RCV_BUFFER.RCV_BYTE[2] // 3. Zeichen von rechts
UW  W#16#0F   
OW            
SLW 4    // schieben um jeweils "nur" 1 Tetrade, weil das ZwischenErgebnis geschoben wird     
L   #RCV_BUFFER.RCV_BYTE[3] // 2. Zeichen von rechts
UW  W#16#0F  
OW            
SLW 4    // schieben um jeweils "nur" 1 Tetrade, weil das ZwischenErgebnis geschoben wird     
L   #RCV_BUFFER.RCV_BYTE[4] // 1. Zeichen von rechts
UW  W#16#0F   
OW            
BTD           
T   #RCV_BYTE
 
Zuletzt bearbeitet:
Zurück
Oben