ASCII to INTeger in S7

userxyz

Member
Join Date
May 2002
Location
any
Posts
2,768
Hi

When u receive SUCH ASCII telegram:

M +2.56m

it represents 2,56 meters in Characters.

How can I convert this to an integer value so that I can calculate with it ?





+
 
Hi Gerry,

First you have to convert the ASCII characters into BCD by removing the 30hex offset for every character (35hex -> 05hex).

Put all remaining digits together in one word (assuming it's not more than 4 digits). You might need several SLW instructions to get every digit in the correct place (05hex + 4 x SLW = 50hex / 02hex + 8 x SLW = 200hex).

Then use BTI to convert the BCD code into integer, and TADA!
 
well

well, weird, but when we set it to 18, we don't get the full telegram in our DB, when setting it higher (40), then we get the data like we want it...

About the conversion, i will try it
 
Do you actually receive the end characters 0Dhex <CR> and 0Ahex <LF>? Are they visible in the RCV DB?

If not, then the CP340 is just using character delay to determine the length of a telegram.
 
Here's one implementation to convert the strings to reals. I've set up DB1 to contain test strings and the resultant conversions. This has been tested with the supplied data using PLCSIM.

Code:
DATA_BLOCK DB 1
TITLE =
VERSION : 0.1

  STRUCT  
   aData : ARRAY  [1 .. 10 ] OF //Temporary placeholder variable
   STRING  [20 ]; 
   aResults : ARRAY  [1 .. 10 ] OF REAL ; 
  END_STRUCT ; 
BEGIN
   aData[1] := 'M +2.546m'; 
   aData[2] := 'M +2.547m'; 
   aData[3] := 'M +2.546m'; 
   aData[4] := 'M -2.546m'; 
   aData[5] := 'M +0.999m'; 
   aData[6] := 'M -0.999m'; 
   aData[7] := 'M +999.999m'; 
   aData[8] := 'M -999.999m'; 
   aData[9] := 'M +800.999m'; 
   aData[10] := 'M -800.999m'; 
   aResults[1] := 0.000000e+000; 
   aResults[2] := 0.000000e+000; 
   aResults[3] := 0.000000e+000; 
   aResults[4] := 0.000000e+000; 
   aResults[5] := 0.000000e+000; 
   aResults[6] := 0.000000e+000; 
   aResults[7] := 0.000000e+000; 
   aResults[8] := 0.000000e+000; 
   aResults[9] := 0.000000e+000; 
   aResults[10] := 0.000000e+000; 
END_DATA_BLOCK
FUNCTION FC 6 : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
  Ascii : POINTER ; 
END_VAR
VAR_OUTPUT
  rResult : REAL ; 
END_VAR
VAR_TEMP
  iDb : INT ; 
  dwptr : DWORD ; 
  rSum : REAL ; 
  rSign : REAL ; 
  iInteger : INT ; 
  rFraction : REAL ; 
END_VAR
BEGIN
NETWORK
TITLE =pointer to string data
	  L	 P##Ascii; 
	  LAR1  ; 
	  L	 W [AR1,P#0.0]; 
	  T	 #iDb; 
	  OPN   DB [#iDb]; 
	  L	 D [AR1,P#2.0]; 
	  T	 #dwptr; 
	  LAR1  ; 
NETWORK
TITLE =find the sign
	  L	 0.000000e+000; 
	  T	 #rSum; 
sign: L	 B [AR1,P#0.0]; 
	  +AR1  P#1.0; 
	  L	 '+'; 
	  ==I   ; 
	  JC	plus; 
	  TAK   ; 
	  L	 '-'; 
	  ==I   ; 
	  JC	mins; 
	  JU	sign; 
plus: L	 1.000000e+000; 
	  JU	sig; 
mins: L	 -1.000000e+000; 
sig:  T	 #rSign; 
NETWORK
TITLE =get units until '.'
unit: L	 B [AR1,P#0.0]; 
	  +AR1  P#1.0; 
	  L	 '.'; 
	  ==I   ; 
	  JC	unid; 
	  TAK   ; 
	  L	 '0'; 
	  -I	; 
	  T	 #iInteger; 
	  L	 #rSum; 
	  L	 1.000000e+001; 
	  *R	; 
	  L	 #iInteger; 
	  DTR   ; 
	  +R	; 
	  T	 #rSum; 
	  JU	unit; 
unid: NOP   0; 
NETWORK
TITLE =now get fractional part
	  L	 1.000000e-001; 
	  T	 #rFraction; 
dec:  L	 B [AR1,P#0.0]; 
	  +AR1  P#1.0; 
	  L	 'm'; 
	  ==I   ; 
	  JC	end; 
	  TAK   ; 
	  L	 '0'; 
	  -I	; 
	  DTR   ; 
	  L	 #rFraction; 
	  *R	; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
	  L	 #rFraction; 
	  L	 1.000000e+001; 
	  /R	; 
	  T	 #rFraction; 
	  JU	dec; 
end:  NOP   0; 
NETWORK
TITLE =
	  L	 #rSum; 
	  L	 #rSign; 
	  *R	; 
	  T	 #rResult; 
END_FUNCTION
ORGANIZATION_BLOCK OB 1
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1

VAR_TEMP
  OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ; //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ; //Priority of OB Execution
  OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ; //Reserved for system
  OB1_RESERVED_2 : BYTE ; //Reserved for system
  OB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ; //Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB	0,
		   rResult				  := DB1.DBD  220);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB   22,
		   rResult				  := DB1.DBD  224);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB   44,
		   rResult				  := DB1.DBD  228);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB   66,
		   rResult				  := DB1.DBD  232);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB   88,
		   rResult				  := DB1.DBD  236);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB  110,
		   rResult				  := DB1.DBD  240);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB  132,
		   rResult				  := DB1.DBD  244);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB  154,
		   rResult				  := DB1.DBD  248);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB  176,
		   rResult				  := DB1.DBD  252);
	  NOP   0; 
NETWORK
TITLE =
	  CALL FC	 6 (
		   Ascii					:= DB1.DBB  198,
		   rResult				  := DB1.DBD  256);
	  NOP   0; 
END_ORGANIZATION_BLOCK
 
hmm

Sparkz said:
Wow, LD! You're way out of my league...

(...humble sigh...)


hsss.JPG


DBB60, 61 and so on is old data.

I'm sending the speed + the length to the CP340.

Starting at DBB32 until DBB59, that's the full telegram

ending with CR LF



about the conversion, I don't have much experience with arrays..., maybe a level to high for me


so I'll try yours sparkz
 
Combo said:
hey, could u send the FC plz ?

All the code neccessary is present. Just copy/paste the code into a source folder and compile it, it will produce DB1, OB1 and FC6
 
Combo said:
what about IEC block FC39 from siemens

STRING to REAL

can this be used ?

I looked at this but the string format for FC39 is 2.34e+00, thats why I rolled my own.(I didn't check what FC39 did if you gave it 2.34 though)
 
Fc39

Description

The function FC39 converts a string to a variable in REAL data type format. The string must have the following format:

±v.nnnnnnnE±xx ± Signv 1 digit before the decimal pointn 7 digits after the decimal pointx 2 exponential digits
If the length of the string is smaller than 14, or if it is not structured as shown above, no conversion takes place and the binary result (BR) bit of the status word is set to “0". If the result of the conversion is outside the REAL range, the result is limited to the corresponding value and the binary result (BR) bit of the status word is set to “0".

Parameter Declaration Data Type Memory Area Description
S INPUT STRING D, L Input string
RET_VAL OUTPUT REAL I, Q, M, D, L Result
You can assign only a symbolically defined variable for the input parameter.




referring to the description, this can be used...

But I have a good string for this block in DB10.DBB35 to DB10.DBB45. In this ±v.nnnnnnnE±xx format. I think this block can do the job of ASCII measurement conversion to REAL.

The only problem I still have is, I know I have 10 byte's in DB10 that represent that format that I need to enter in in String input of FC39.

My question is: How do I need to enter it, in a pointer way or... ?


thanks for all the help I'm getting
 

Similar Topics

Hello, I am converting to iFIX 6.1 and talking to a PLC5. I have several TX tags that were looking at N32 addresses in the PLC5 and were getting...
Replies
4
Views
2,916
I know there's the DTOS Function, but I have a value of "35" that is really "0035", and that's how I want it converted. Looks like the function...
Replies
2
Views
1,521
Please Help On Allen Bradley PLC SLC500 I'm receiving Ascii string data values from a serial devices and put the value into a string file; How...
Replies
12
Views
4,826
Hi, I am having trouble with taking an Integer and somehow moving this number as part of an ascii string. Do I have to break it down and move 2...
Replies
4
Views
1,959
Is there a way to convert these integers (17476,16688,13110,12598) to Ascii character (DDA03616)? 17476 = 4444hex = DD on ascii chart 16688 =...
Replies
7
Views
6,733
Back
Top Bottom