ASCII -> Integer

winniepuh

Level-1
Beiträge
7
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

Ich habe folgendes Problem:
Über eine Schnittstelle wird eine 4-stellige Zahl eingelesen, die im ASCII-Format vorliegt. Diese Zahl ist zur weiteren Verarbeitung in einer Integerzahl umzuwandeln.

Die Lösung soll möglichst kurz in Form eines FC sein, der einen Input (ASCII-Wert als Doppelwort) und einen Output (Integer) hat.

Hat jemand einen Vorschlag, wie ich das lösen könnte?

Ich hatte an die Standard-Funktion STRG_I (String -> Integer) gedacht. Dazu müsste ich aus dem Doppelwort allerdings zunächst einen String bekommen.

Grüße,
WP
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
volker schrieb:
mit der fc38 warst du doch schon nah dran. nimm doch einfach die fc37.

Dann habe ich jetzt noch das Problem, dass die ASCII-Zeichenfolge in einem DoubleWord vorliegt. Wie kann ich die in einen String konvertieren? FC37/38 nehmen das DWORD nicht.

Grüße,
WP
 
Zuletzt bearbeitet:
[quote="winniepuh dass die ASCII-Zeichenfolge in einem DoubleWord vorliegt. [/quote]

also das verstehe ich nicht so ganz.
gib mal ein beispiel.

hast du für eine 4stellige zahl 4 doppelworte vorliegen, oder was?
 
volker schrieb:
also das verstehe ich nicht so ganz.
gib mal ein beispiel.

hast du für eine 4stellige zahl 4 doppelworte vorliegen, oder was?

Die 4-stellige Zahl befindet sich in einem Doppelwort. Ich habe einen FC mit dem Input ASCII (DWORD) und dem Output INTEGER (INT).
Im FC soll aus die ASCII-Zeichenfolge in eine Integerzahl umgerechnet werden.

Als Beispiel für das Doppelwort:
HEX: 31323334

Als Ergebnis müsste dann die Integerzahl 1234 rauskommen.

Jetzt klar?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ok dann geht das mit den fc's nicht. ich kenn auch keinen der sowas machen würde.

wenn du nur zahlen hast (ohne komma) würde folgendes funktionieren.
gibt bestimmt noch bessere möglichkeiten. aber diese funktioniert.

awl-quelle
Code:
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1


VAR_TEMP
  ascii_l : DWORD ;	
  ascii_r : DWORD ;	
  zahl : DINT ;	
  einer : DINT ;	
  zehner : DINT ;	
  hunderter : DINT ;	
  tausender : DINT ;	
END_VAR
BEGIN
NETWORK
TITLE =ascii-zahl -> integer

      L     L#3132; 
      DTB   ; 
      T     #ascii_l; 

      L     L#3334; 
      DTB   ; 
      T     #ascii_r; 

      L     LW     1; 
      BTI   ; 
      L     30; 
      -I    ; 
      L     1000; 
      *I    ; 
      T     #tausender; 

      L     LW     3; 
      SRW   8; 
      BTI   ; 
      L     30; 
      -I    ; 
      L     100; 
      *I    ; 
      T     #hunderter; 

      L     LW     5; 
      BTI   ; 
      L     30; 
      -I    ; 
      L     10; 
      *I    ; 
      T     #zehner; 

      L     LW     7; 
      SRW   8; 
      BTI   ; 
      L     30; 
      -I    ; 
      T     #einer; 

      L     #einer; 
      L     #zehner; 
      +D    ; 
      L     #hunderter; 
      +D    ; 
      L     #tausender; 
      +D    ; 
      T     #zahl; 

END_FUNCTION
 
volker schrieb:
ok dann geht das mit den fc's nicht.
Soweit war ich auch gerade. :wink:
Ich habe mir nun auch selbst eine Lösung programmiert und muss die noch testen. Ob ich dazu heute noch komme, muss ich mal sehen.
Wenn mein Code läuft, melde ich mich und veröffentliche ihn hier.

volker schrieb:
ich kenn auch keinen der sowas machen würde.
Wir benötigen die Zahl aber als Integer zur Weiterverarbeitung.
Der Wert ist ein Messwert, der von einer Distanzmessung über eine CP340 (ASCII-Mode) kommt.

Grüße & Dank,
WP
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Rainer Hönle schrieb:
volker schrieb:
awl-quelle
Muss überall geändert werden in
Code:
      L     48; // = 0x30
      -I    ;

:?: Wieso?
der code ist getestet und hat hier in der simulation einwandfrei gelaufen.

mit itb mache ich zunächst einmal aus 3132 dez (12) 3132 hex
nun werden beide ziffer voneinander getrennt und mit bti wieder in eine dez gewandelt. das ergibnis ist also 31 und 32. von beiden wird 30 dez abgezogen um den wert der ziffer zu erhalten. das ergebnis ist also 1 und 2.
 
Würde diese Variante auch funktionieren?

Code:
      L     DW#16#31323334              // bzw. den Wert über die Schnittstelle
      L     DW#16#F0F0F0F
      UD                                // Akku enthält DW#16#01020304
      T     MD     0                    // oder temp ....
      L     MB     0
      L     1000
      *D    
      T     MD     4
      L     MB     1
      L     100
      *D    
      L     MD     4
      +D    
      T     MD     4
      L     MB     2
      L     10
      *D    
      L     MD     4
      +D    
      L     MB     3
      +D    
      T     MD     4                   // Das Ergebnis als Integer

Wenn ja, kann noch weiter optimiert werden?
Kommen eigentlich negative Werte auch vor? Dort funktioniert obiger Code nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Rainer Hönle schrieb:
[D.h. am Anfang müsste L W#16#3132 und nicht L L#3132 stehen. Daher vermutlich unser gedanklicher Unterschied.

ok. ich bin davon ausgegangen, das der wert als dez vorliegt. sollte der wert als hex vorliegen, kann man das dtb vor dem transfer in ascii_l und ascii_r sparen.

ja, ihr code funktioniert auch.

sollten negative werte vorkommen, würde das die sache natürlich verkomplizieren, da man zuerst nach dem vorzeichen suchen muss.
 
volker schrieb:
sollten negative werte vorkommen, würde das die sache natürlich verkomplizieren, da man zuerst nach dem vorzeichen suchen muss.

Negative Werte kommen nicht vor.

Mein Code sieht wie folgt aus:

Code:
      L     #ASCII                      // ASCII-Wert in Akku laden
      TAD                               // Bytes im Akku tauschen 4-3-2-1 -> 1-2-3-4
      L     DW#16#30303030
      -D    
      T     #ASCII_1                    // 1er Stelle speichern
      SRD   8
      T     #ASCII_10                   // 10er Stelle speichern
      SRD   8
      T     #ASCII_100                  // 100er Stelle speichern
      SRD   8

      L     1000
      *I                                // 1000er Stelle gewichten
      T     #INT1000

      L     #ASCII_100
      L     100
      *I                                // 100er Stelle gewichten
      T     #INT100

      L     #ASCII_10
      L     10
      *I                                // 10er Stelle gewichten

      L     #ASCII_1                    // Addition der einzelnen Stellen
      +I    
      L     #INT100
      +I    
      L     #INT1000
      +I    
      T     #INTEGER

Das Tauschen der Bytes im Akku ist nötig, da die Werte in der Reihenfolger Einer, Zehner, Hunderter, Tausender in der Eingabevariable stehen.

Grüße & Dank,
Felix
 
Zurück
Oben