Geeze... ffr58kk90... why you can't call yourself Tony... perhaps I should rename myself 34-22-34 just to add a bit of interest.
When receiving SERIAL, remember that SERIN, HSERIN etc have the HEX modifier which can convert HEX back to individual byte characters for you (consult the PBP manual on that), but this is the long explanation. It shows you HOW and WHY to do yourself...
First of all there’s no strings in PIC Basic. Everything is a number. When you receive a two-character HEX representation of an ASCII character (be it a numeric or non-numeric) where each of the two digits is in the ASCII range 0-F and want to turn it back into a single ASCII character (0-255), you first have to remember that those two HEX digits are ASCII. That is...
Zero (0) is actually Decimal 48
One (1) is actually Decimal 49... thru to...
Nine (9) is actually Decimal 57
Ten (A) is actually Decimal 65... thru to...
Fifteen (F) which is actually Decimal 70.
The first HEX Digit is the 16’s value, and the second HEX Digit is the units (0-15) value (base 16 arthmetic). So an ASCII lowercase Zed ‘z’ (which is a Decimal value 122) would be received as two digits HEX ‘7A’. We now have to turn this '7A' back into a single numeric 122. Let’s do this...
Consider the subroutine HEXConvert below...
'
' Subroutine converts ASCII-HEX to Numeric
‘ DataA is a byte variable
' ----------------------------------------
HEXConvert:
DataA=DataA-48
If DataA>9 then DataA=DataA-7
Return
DataA is an ASCII HEX variable. It’s only valid state is one of the sixteen possibles already described previously, that is (Decimal) 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69 or 70. Which represent 0-9 and A-F. You can now see that the first thing the subroutine HEXDEC does is reduce our (above) HEX/ASCII down to a single decimal number is the range 0-15.
Now since our incoming HEX is a TWO character string, consider this...
HEXWord var byte [2]
HEXWord(0)=”7”
HEXWord(1)=”A”
Assume that $7A has been received and the two ASCII characters “7” (which is actually Decimal 55) is in HEXWord(0), and “A” (which is actually Decimal 65) is in HEXWord(1)... now we run this program... (DataB is a byte variable)...
DataA=HEXWord(0):Gosub HEXConvert
DataB=DataA*16
DATA=HEXWord(1):Gosub HEXConvert
DataB=DataB+DataA
Let’s analyse these four lines. The first line takes the Most Significant Byte of our two byte ASCII HEX “String” (the ASCII “7” - remember it’s a Decimal 55), and reduces it to a numerical value of 7. The Second line takes this numerical 7 and multiplies it by 16 so that DataB equals 112 (remember that previously I said that the first character of the two-byte HEX is the 16’s value - base 16 arithmetic). In the third line we convert the Least Significant Byte (the ASCII “A” which is a Decimal 65) into the numeric value of ten. In the Fourth line we add the two together so that at the end DataB equals 122 (112 from the MSByte calculation and 10 from the LSByte calculation).
If you now look, DataB=122, which equals $7A which equals an ASCII lowercase “z”. We’ve taken two bytes of ASCII HEX and converted it down to one byte of equivalent numeric value.
Still awake? Glad one of us is.
As a final addition to all this, received numerics (eg a two character string) HEX "35" representing the decimal number 5 would be converted to decimal 53 (which is the ASCII "5")... so... to convert to an math integer of value 5 subtract Decimal 48 from our final DataB answer above.
DataB=DataB-48
That's how you would handle a two-character HEX string to integer for numeric math use. Naturally you only do that for ASCII numerals 0-9 (HEX "30" to "39") as it's not valid on any other non-numeric character.
Melanie
Bookmarks