PDA

View Full Version : hex ascii help please



ffr58kk90
- 21st October 2003, 17:22
Hi can anyone help a newbie with PBP.

I am trying to log data from a piece of kit that outputs its data in 'hex ascii', by this I mean that for example the number "154307" would output as "313534333037"
I can read this in as a string but how do I (simply!) convert it into numeric variables that I can perform calculation on?
Ideally, if the above was the time, I would want to get it to hours as a byte, mins as a byte and seconds as a byte.
The other problem is that the data I need to get is not just numbers, there are also letters e.g. "READY" would be "5245414459"
as I just need to log / display the letters, this would be ok converted to an ascii string

Thanks for any help

Tony

Melanie
- 21st October 2003, 19:47
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

ffr58kk90
- 21st October 2003, 21:12
Hi Melanie

Thank you very much for your reply, after reading your reply and working through it with a selection of received data, I can now understand how it works,
For some reason, my brain went awol last night whilst reading the serin2 description, I got myself mighty confused!!.
again, many thanks for the help Melanie.


Ps. just for info, I own an ex-military fitted for radio (FFR) landrover and the 58kk90 was the military registration number, thats where the user name came from.

Tony.

Melanie
- 22nd October 2003, 07:32
Now I thought pretty much all vehicles for the last thirty years have been 'Fitted For Radio' - that's what the universally standard oblong hole in the dash is for...

BertMan
- 2nd December 2005, 04:53
Wow, this was exatly what I was looking for. Melanie, you chopped my 50 lines of code down to about 8 with your HEXConvert routine. I am receiving a 3 byte hex so I had to add in the extra 16^2. BTW, funny how well the search engine works. I think I will use it more often.

Ioannis
- 2nd December 2005, 09:23
perhaps I should rename myself 34-22-34 just to add a bit of interest.

Hmm, is this unit in cm?

Ioannis

Melanie
- 2nd December 2005, 09:41
Hmmm... I knew the English to Greek translation on Babelfish was running slow... but two years? Trust me, certain measurements look better in Imperial rather than metric.

Ioannis
- 2nd December 2005, 19:50
Aha! Now looks much better!

And to stay on topic that is 56-38-56 in hex!

Ioannis

keithdoxey
- 2nd December 2005, 20:29
Aha! Now looks much better!

And to stay on topic that is 56-38-56 in hex!

Ioannis

I *was* going to say that there is something seriously wrong with your maths Ioannis

By my calculation the Hex for 34-22-34

would be 22-16-22

Octal would be 42-26-42.

As I said, I *was* going to say that but I finally figured out how you arrived at the numbers you did.

Inches >> cm >> hex

NavMicroSystems
- 2nd December 2005, 22:18
...perhaps I should rename myself 34-22-34 just to add a bit of interest.


Melanie, then you would have to post some more images to prove that as well as the "traffic stopping" legs ;-)

sayzer
- 29th December 2006, 22:09
I was going through the posts again and saw this HEX conversion.

Here was my solution for HEX issues in RTC chips.

I still kiss the hands of experts though.



'HexVal is the incoming HEX value.
'DecVal is the product in Decimal.
'Go ahead and put more numbers in the same concept.


LOOKDOWN HexVal,[0,1,2,3,4,5,6,7,8,9,$10,$11,$12,$13,$14,$15,$16,$1 7,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29, $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$4 2,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54, $55,$56,$57,$58,$59],DecVal


END



May be his could be more explanatory to some...


----------------------------