BTI in S7

userxyz

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

I need a conversion from ASCII to INT. This works, but...

Basically what I have is 3 byte's representing a temparature from 0 to 200 degrees celcius.

In this example: If you have 063 degrees for example, then I have 0 in the first byte, 6 in the second and 3 in the third, these are ASCII characters. As you know from the ASCII table, 1 ascii = 49 dec, so 6 = 54 and 3 = 51
54 - 48 and 51 - 48 gives us 6 and 3. The six is the second byte and is multiplied by 10. then you have 60 + 3. That's basically how I convert.

BUT
I didn't use BTI, and it works... ??? Why do you need BTI then ?

Code:
	  L	 #DBnr
	  T	 #DBxx
	  OPN   DB [#DBxx]
	  L	 DBB   34					// A
	  L	 48
	  -I	
	  L	 100
	  *I	
	  T	 #A1

	  L	 DBB   35
	  L	 48
	  -I	
	  L	 10
	  *I	
	  T	 #A2

	  L	 DBB   36
	  L	 48
	  -I	
	  T	 #A3

	  L	 #A1
	  L	 #A2
	  +I	
	  L	 #A3
	  +I	
	  T	 #A_Val
 
case

Like in this case (Year is an out parameter of the FC) I understand that u need to use BTI, but in my ASCII conversion, I don't need it I think ... ?

L B [AR1,P#0.0] // Byte 1
BTI
T #Year
 
There may be several roads to the same goal. Both are fine if they works.
I think that using BTI in stead of subtracting 48 is a little bit more transparant and easy to troubleshoot.

What were I thinking ?! I know, I was thinking about BCD, not ASCII.
 
Last edited:
ASCII is one form of coding. BCD is another. There is no connection between the BTI instruction and ASCII conversion.
 
no

no, but, in the case of my code, do I need to use BTI or not, that's my question...

Is my code okay ?

To me it looks like BTI is used when you want to send a bytevalue to an integervalue.

because I calculate with Byte and Integer, the PLC takes the Byte as an integer in the calculation...

Am I right ?

I'm a bit confused about the BTI instruction
 
BTI converts from BCD to Integer.
Input is a BCD coded value between -999 and +999.
Output is the same value coded as an Integer.

BCD is not the same as ASCII.
 
Here's an alternative implementation that converts the ASCII to BCD and then uses the BTI. No multiplies required. :)

Code:
	 L	 #DBnr
	 T	 #DBxx
	 OPN DB [#DBxx]
	 L	 DBD 34					//get all 3 digits
	 SRD 8						 //into bottom of acc
	 L	 DW#16#303030				//subtract 48 from each digit
	 -D	
	 PUSH							 //result in accu2
	 AW	W#16#F					 //isolate bottom digit
	 TAK 
	 SRD 4						 //shuffle right
	 +I								//add back bottom digit
	 PUSH							 //copy to accu2
	 SRD 8						 //shuffle again
	 SLD 4
	 TAK 
	 AW	W#16#FF					 //mask to leave relevant digits
	 +I								//form complete result in BCD
	 BTI							 //finally convert to integer
	 T	 #A_Val
 
hmm

The data is only 3byte's long !!!

L D[AR2 said:
Here's an alternative implementation that converts the ASCII to BCD and then uses the BTI. No multiplies required. :)

Code:
	 L	 #DBnr
	 T	 #DBxx
	 OPN DB [#DBxx]
	 L	 DBD 34					//get all 3 digits
	 SRD 8						 //into bottom of acc
	 L	 DW#16#303030				//subtract 48 from each digit
	 -D	
	 PUSH							 //result in accu2
	 AW	W#16#F					 //isolate bottom digit
	 TAK 
	 SRD 4						 //shuffle right
	 +I								//add back bottom digit
	 PUSH							 //copy to accu2
	 SRD 8						 //shuffle again
	 SLD 4
	 TAK 
	 AW	W#16#FF					 //mask to leave relevant digits
	 +I								//form complete result in BCD
	 BTI							 //finally convert to integer
	 T	 #A_Val
 
Here's the results from processing the string '1234'. As you can see the 4 is discarded and the computed result is 7b in hex, which is 123 in decimal.

bti1.JPG
 
ok

Ok, I understand, but is the BTI needed ?

L D[AR2 said:
Here's the results from processing the string '1234'. As you can see the 4 is discarded and the computed result is 7b in hex, which is 123 in decimal.

bti1.JPG
 
code

I tried to understand the code, but it's a bit too complex to understand for me, can you help me understand it pls...

Code:
L	 #DBnr
	 T	 #DBxx
	 OPN DB [#DBxx]
	 L	 DBD 34  	//get all 3 digits
	 SRD 8	  //into bottom of acc
	 L	 DW#16#303030  	//subtract 48 from each digit
	 -D

You load 4 Byte's, but then you do a shift of 8 bits, so now we have only 3 byte's left. 30Hex is 48dec; so you substract 48dec of each byte, so far, I understand it.

If we have 156 for example, then we have 49 53 and 54 decimal. You substract 48 of each, and you get 1 in the first byte, 5 in the second and 6 in the third...

then:

Code:
PUSH							 //result in accu2
	 AW	W#16#F					 //isolate bottom digit
	 TAK 
	 SRD 4						 //shuffle right
	 +I								//add back bottom digit
	 PUSH							 //copy to accu2
	 SRD 8						 //shuffle again
	 SLD 4
	 TAK 
	 AW	W#16#FF					 //mask to leave relevant digits
	 +I								//form complete result in BCD
	 BTI							 //finally convert to integer
	 T	 #A_Val
this part is way to complex for me...
 
The best way to understand it is to look at the accumulators to the right of the code, in Simons running example.

Also, look at it with HEX format in mind, not decimal, its easier.

The first part of the code took the HEX of ASCII '1234', which is 31323334, removed the right end '4' and changed to 010203 HEX.

The part of the code you can't understand, is all about removing the 0's, 10203 to 123 HEX (or same format as BCD 123).

PUSH, makes a copy of what is ACCU1 and puts it in ACCU2.

TAK switches ACCU1 and ACCU2.

When you look at the ACCU values at each instruction, you will see he is shifting out the 0's and adding the results so 010203 becomes 123.

123 HEX is the same format as 123 BCD. BCD just does not have the characters A to F.


The BTI instruction at the converts the 123 BCD remaining value into an INTEGER, so you can use that value in the code as a normal number.
 
Back
Top Bottom