PDA

View Full Version : ASCii To HEX?



mpgmike
- 9th March 2018, 16:44
I'm working with an ELM327 OBD II Interpreter. The serial data is in the form of ASCii, intended to communicate with a PC Serial Port (yea, from a decade ago). If I send Request "01 05" (for Coolant Temp) it has to be in the form of ASCii. The Response would begin "41 05" then the value, all in ASCii. This means the first received byte is the upper nibble of the first Hex character, the second byte the lower nibble, and so forth. The PBP3 Reference Manual lists a HEX Modifier. The example leaves lots of ambiguity as to how it should be used. I am open to any suggestions on how to structure the "unraveling" code.

richard
- 9th March 2018, 21:08
to parse a variable number of hex2 chars I use this


where U_RXBUFF[] contains the string to be parsed
k contains the length of the input string
STR_inx contains the length of the OUTPUT string
txbuff[] contains the PARSED the OUTPUT string

get_data:
STR_inx=0
k.0=0 ;must be even
while k
ARRAYREAD U_RXBUFF ,[SKIP ((STR_inx+1)<<1),hex2 txbuff[STR_inx] ]
'Debug "k ",#k,9,#STR_inx,9,hex txbuff[STR_inx],13,10
STR_inx=STR_inx+1
k=k-2
wend
RETURN


IF your fomat is fixed just

serin2 .... [hex2 var1,hex2 var2,.........]

mpgmike
- 9th March 2018, 23:49
Here is what I came up with today:



Grab_ELM:
IF Ebit = 0 THEN ;Indicates 1st Nibble ASCii Character
Ebyt0 = RCREG1 ;Load Upper Nibble into Ebyt0
ELSEIF Ebit = 1 THEN ;Indicates 2nd Nibble ASCii Character
Ebyt1 = RCREG1 ;Load Lower Nibble into Ebyt1
ENDIF
TOGGLE Ebit ;Set Up to Load Lower Nibble, or Upper Nibble of Next Character
IF Ebit = 1 THEN ;Just Loaded Upper Nibble, Still Need Lower Nibble
@ INT_RETURN
ELSE
;Combine HEX[Ebyt[0], Ebyt[1]]
IF (Ebyt0 => $30) AND (Ebyt0 <= $39) THEN ;Characters 0 >> 9
ElmIn = (Ebyt0 - $30) << 4 ;Shifts to Upper Nibble
ELSEIF (Ebyt0 => $41) AND (Ebyt0 <= $46) THEN ;Characters A >> F
ElmIn = (Ebyt0 - $37) << 4 ;Shifts to Upper Nibble
ENDIF
IF (Ebyt1 => $30) AND (Ebyt1 <= $39) THEN ;Characters 0 >> 9
ElmIn = ElmIn + (Ebyt1 - $30) ;Adds to Upper Nibble
ELSEIF (Ebyt1 => $41) AND (Ebyt1 <= $46) THEN ;Characters A >> F
ElmIn = ElmIn + (Ebyt1 - $37) ;Adds to Upper Nibble
ENDIF
IF (ElmIn = $0D) OR (ElmIn = $20) THEN ;Carriage Return or Space
@ INT_RETURN ;Ignore & Return
ELSEIF (ElmIn <> $0D) AND (ElmIn <> $20) AND (ElmIn <> $3E) THEN
Eval[ElmCt] = ElmIn
ELSEIF ElmIn = $3E THEN ;">", End Of Transmission
ELM_Rec = 0 ;Can now send next Request
ElmCt = 0 ;Next BYTE In = New
ElmDat = 1 ;Must Decipher Eval[x]
Ebit = 0 ;Ensures 1st Character Loads into Ebyt0
@ INT_RETURN ;Return
ENDIF
ElmCt = ElmCt + 1 ;Will Load Next Character
@ INT_RETURN ;Return

At least I have variables to work with in a Hex format. From there I have other subroutines to dissect the content.

Art
- 27th April 2018, 17:39
I don’t think there’s any modifier that would pull out one byte being represented as a pair of bytes.
There’s no neat way to deal with ASCII, but everything after the first return could be a part of the main program though.
The main program knows by the state of Ebit when it’s supposed to act on the input just as the code above does.

mpgmike
- 27th April 2018, 19:03
Not sure if there's a short cut, but the code I posted is working.

Art
- 27th April 2018, 19:35
Generally, it’s very beneficial for interrupts to be as short as possible.
I’m not sure how BASIC interrupts work.
Working is the main thing :D