Shop OBEX P1 Docs P2 Docs Learn Events
Convert hex to dec — Parallax Forums

Convert hex to dec

RobbanRobban Posts: 124
edited 2007-03-10 11:17 in BASIC Stamp
Hi!

How do i convert hex to dec?
like

"1A F8" -> 6904

Regards
Robert
«1

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-05 20:42
    If you're receiving it via SERIN or some other I/O statement, you can use the HEX formatter. Look at the section of the PBasic manual on SERIN.
  • RobbanRobban Posts: 124
    edited 2007-03-05 20:49
    i go the value 1a f8 from a serin string and now i want it to be displayed as 6904 on my lcd

    my command for the lcd is
    serin 1,16468,[noparse][[/noparse]skip6,str hexstr\5]
    .
    .
    .
    serout 2,84,[noparse][[/noparse] hexstr(i)]
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-05 21:18
    In your postings, you look like you have two pairs of hex digits separated by a space. Is that true? Is it necessary to have the space?

    Is there some reason why you're not using the HEX formatter for processing your input text? If your format is indeed "HHbHH" where "HH" are hex digits and "b" is a blank, you could use this input statement to get the value into the word variable x:
    SERIN 1,16468,[noparse][[/noparse] skip6,hex2 x.highbyte,skip1,hex2 x.lowbyte]
    


    To display as a decimal number on the lcd, you'd use:
    SEROUT 2,84,[noparse][[/noparse] DEC x]
    
  • RobbanRobban Posts: 124
    edited 2007-03-05 22:07
    yes...there IS a blank between them

    here is my program

    hexstr var byte (6)
    i var byte
    main:
    serout 0,16468,[noparse][[/noparse]"010C",13]
    serin 1,16468,[noparse][[/noparse]skip 6,hex2 hexstr.highbyte,skip 1,hex2 hexstr.lowbyte]
    for i =1 to 4
    serout 2,84,[noparse][[/noparse]dec hexstr]
    next
    serout 2,84[noparse][[/noparse]"?n"]
    change row on display
    pause 1000
    goto main

    but i get Hightbyte marked and "Expected a smaller-siza variable modifier

    *confused*
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-05 22:23
    You can't use hexstr which is a byte variable. You have to use a variable declared as a word. You may need to review the PBasic manual section on memory allocation and variables.
  • RobbanRobban Posts: 124
    edited 2007-03-06 19:40
    there must be a ghost in my stamp....:-(

    i wrote instead

    hexstr var word
    main:
    serout 0,16468,[noparse][[/noparse]"010C",13]
    serin 1,16468,[noparse][[/noparse]skip 6,hex2 hexstr.highbyte,skip 1,hex2 hexstr.lowbyte]
    serout 2,84,[noparse][[/noparse]dec hexstr]
    serout 2,84[noparse][[/noparse]"?n"]
    change row on display
    pause 1000
    goto main

    When i connect the stamp to my laptop with this program it works perfectly using a teminalprogram like Hyperterminal or Pbasic:s term.
    However i intend to connect the stamp to my ELM327 see link for more info

    http://www.elmelectronics.com/DSheets/ELM327DS.pdf

    And when i plug it in i dont get anything.
    so i modified the program and came up with this

    hexstr var word
    main:
    serout 0,16468,[noparse][[/noparse]"010C",13]
    serin 1,16468,[noparse][[/noparse]skip 6,hexstr.highbyte,hexstr.lowbyte]
    serout 2,84,[noparse][[/noparse]hexstr.highbyte,hexstr.lowbyte]
    serout 2,84[noparse][[/noparse]"?n"]
    change row on display
    pause 1000
    goto main

    and using this program with the elm i only get the "1A"
    if i then change the SKIP 6 to SKIP 10 then i only get the "F8"
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-06 19:54
    The ELM327DS documentation is not very good, but there's a hint that there may be a character (maybe a blank?) before the first hex digit. This means that your should use skip 7 instead of skip 6. With your second version, you should only get two characters displayed. That's what you asked for. You really should reread the SERIN section of the PBasic manual and the related Appendix with more formatter examples.

    I also think you could use "SERIN 1,16468,[noparse][[/noparse]hex junk, hex junk, hex hexstr.highbyte, hex hexstr.lowbyte]". The OSD chip is providing a sequence of hex values always separated by blanks (and ended with a return probably). The hex formatter skips any blanks, then processes any number of hex digits up to the next delimiter (blank or return) which is exactly what you need. You won't need the initial skip formatter because there really are two hex numbers in front of the ones you want and the "hex junk" will process them and they'll be ignored. junk needs to be some unneeded byte variable.
  • RobbanRobban Posts: 124
    edited 2007-03-06 21:25
    hmmm....now i got my 1a and F8 as two variables.
    i hade to add on the serin....

    serin tx,baud,[noparse][[/noparse]skip 6,hexstr.highbyte,hexstr.lowbyte,skip1, hexstr2.highbyte,hexstr2.lowbyte]

    so now i got 2 varibles with hex..
    is there some kind of formular to multiply/devide etc to get the 6904?

    if so How??

    Post Edited (Robban) : 3/6/2007 9:40:06 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-06 21:54
    Please, you're doing it the hard way. Using the HEX input formatter is much much easier. If you really want to compute it yourself, you can:
    if hexstr.highbyte >= "0" and hexstr.highbyte <= "9" then
       hexstr.highbyte = hexstr.highbyte - "0"
    endif
    if hexstr.highbyte >= "A" and hexstr.highbyte <= "F" then
       hexstr.highbyte = hexstr.highbyte - "A" + 10
    endif
    
    


    You do the same thing with lowbyte substituted for highbyte, then do:
    hexstr = hexstr.highbyte shl 4 + hexstr.lowbyte
    


    Then you do the whole thing the same for hexstr2, then do:
    hexstr = hexstr shl 8 + hexstr2
    


    Your result is in hexstr.
  • RobbanRobban Posts: 124
    edited 2007-03-07 08:08
    Yes, using the HEX would be much easeier but when i add it to· my program as you told me,i don´t get anything on the display/screen...
    ·
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-07 14:18
    It's always hard to debug something 2nd hand. If the complicated method works for you, great. I strongly suggest that you reread the SERIN (and SEROUT) sections on the formatters, particularly HEX and its variations (since it should work for you), go over the examples there and in the appendix, and carefully examine your data stream (from the ELM327). If you can, connect your transmit line from the ELM to both the PC and the Stamp so you can monitor what comes back. Also, have your terminal program show you the "invisible" characters (if it can) like return and line feed since the Stamp does see those.
  • RobbanRobban Posts: 124
    edited 2007-03-07 17:16
    i wrote the program and used HEX2 as you said with my laptop ,basic stamp and the "stationary" computer as a sender (1af8)
    and i got just as you said...6904 on the laptop and lcd....
    but when i got down to the car nothing happens....
    i also made a program that displays both 1a and f8 (with my computers) and when i got down to the car...all i got was 1a and f...

    *soon getting a HEX headache* wink.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-07 17:48
    For some reason, what you think you're getting from the ELM is not what you're actually getting. Your Stamp program works when you send it what you think it should be getting (the "1a f8"). It may be that the Stamp is not fast enough to set up for the second formatter (HEX2) before the ELM starts sending the next character. You may have to use the "str hexstr\5" and do the hex to decimal conversion explicitly as I showed you and change the variables as in:
    for i = 0 to 1
    if hexstr(i) >= "0" and hexstr(i) <= "9" then
       hexstr(i) = hexstr(i) - "0"
    endif
    if hexstr(i) >= "a" and hexstr(i) <= "f" then
       hexstr(i) = hexstr(i) - "A" + 10
    endif
    next
    for i = 3 to 4
    if hexstr(i) >= "0" and hexstr(i) <= "9" then
       hexstr(i) = hexstr(i) - "0"
    endif
    if hexstr(i) >= "a" and hexstr(i) <= "f" then
       hexstr(i) = hexstr(i) - "A" + 10
    endif
    next
    value = hexstr(0) shl 12 + hexstr(1) shl 8 + hexstr(3) shl 4 + hexstr(4)
    
    


    Note that "value" must be declared as a word and "hexstr" as a 5 byte array.
  • RobbanRobban Posts: 124
    edited 2007-03-07 19:15
    ok, i will try what you said...
    But i wonder one thing...

    If tyou remember i used the

    hexstr var byte

    serout tx,baud,[noparse][[/noparse]"010c",13]
    serin rx,baud,[noparse][[/noparse]skip 6 str hexstr/5]
    for i =1 to 6
    debug hexstr(i)
    next
    end

    and when i used this and plugged it in to the elm i got my 1A F8 on the screen
    Now i wonder...is there any way that i can convert this to 6904 despite it is "Var byte"
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-07 20:44
    Please look at my previous posting. That is exactly what it was about ... converting the 5 characters containing 4 hex digits into a 16 bit integer that can be sent to the LCD using the DEC formatter.
  • RobbanRobban Posts: 124
    edited 2007-03-07 21:30
    okej...have written the program, but what is Shl?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-07 21:42
    Sorry. My mistake. In PBasic it's "<<". In some other Basic versions it's "SHL", means the same thing (SHift Left).
  • RobbanRobban Posts: 124
    edited 2007-03-08 15:39
    ok...i wrote your program but i had sum trouble with some lines so i had to modify it a little....
    here it is...

    hexstr VAR Byte(5)
    hexa VAR Word
    i VAR Byte
    value VAR Word

    main:

    SEROUT 0,16468,[noparse][[/noparse]"010c",13]
    SERIN 1,16468,[noparse][[/noparse]SKIP 6, STR hexstr\5]



    FOR i=0 TO 1
    IF hexstr(i)>="0" AND HEXstr(i) <="9" THEN a
    IF hexstr(i)>="a" AND hexstr(i)<="f" THEN b
    ENDif

    a:
    hexstr(i)=hexstr(i)-"0"
    b:
    hexstr(i)=hexstr(i)-"A"+10


    NEXT
    FOR i=3 TO 4
    IF hexstr(i)>="0" AND HEXstr(i) <="9" THEN c
    IF hexstr(i)>="a" AND hexstr(i)<="f" THEN d

    c:
    hexstr(i)=hexstr(i)-"0"

    d:
    hexstr(i)=hexstr(i)-"A"+10


    NEXT
    value=hexstr(0)<< 12 + hexstr(1) << 8 +hexstr(3) << 4 + hexstr(4)
    PAUSE 1000
    DEBUG DEC value
    SEROUT 2,84,[noparse][[/noparse]DEC value,"?n"]
    GOTO main



    SEROUT 2,84,[noparse][[/noparse]"?n"]
    PAUSE 100
    GOTO main


    when i send 1a f8 i get 45249, not the 6904,why?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 16:03
    1) There's an additional mistake I made. I had noticed that your chip puts out lower case letters ("a"-"f") and I had originally written the code for upper case letters ("A"-"F"). I changed the letters in the IF statements, but not in the assignment statements.

    2) That won't fix your problem though. When you modified what I wrote, you changed the logic so it won't work. You didn't say why you changed it and I assume you either have an old version of the PBasic editor or you didn't specify the newer version of the syntax in a compiler directive and the editor probably complained about the THEN/ENDIF form of the IF statement. Here's a version with the "old" syntax:
    for i = 0 to 1
    if hexstr(i) < "0" or hexstr(i) > "9" then skip1x
       hexstr(i) = hexstr(i) - "0"
    skip1x:
    if hexstr(i) < "a" or hexstr(i) > "f" then skip2x
       hexstr(i) = hexstr(i) - "a" + 10
    skip2x:
    next
    for i = 3 to 4
    if hexstr(i) < "0" or hexstr(i) > "9" then skip3x
       hexstr(i) = hexstr(i) - "0"
    skip3x:
    if hexstr(i) < "a" or hexstr(i) > "f" then skip4x
       hexstr(i) = hexstr(i) - "a" + 10
    skip4x:
    next
    value = hexstr(0) << 12 + hexstr(1) << 8 + hexstr(3) << 4 + hexstr(4)
    

    Post Edited (Mike Green) : 3/8/2007 4:07:32 PM GMT
  • RobbanRobban Posts: 124
    edited 2007-03-08 18:21
    ave tried this also but no luck....wonder....does your lines work even if the elm send 22 0E also?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 18:38
    What I wrote should work for any HHbHH sequence of 2 pairs of hex digits separated by any character as long as the hex digits use lower case letters. If you want to include upper case letters, you need to add something like:
    if hexstr(i) < "A" or hexstr(i) > "F" then skip5x
      hexstr(i) = hexstr(i) - "A" + 10
    skip5x:
    


    You need to have a version of this for each loop (with different labels).

    It's not at all helpful for you to tell me "but no luck". It gives me no useful information. I would strongly suggest that you use DEBUG statements to examine what's happening as your program goes along. When I get stuck, I sometimes put a DEBUG statement after every assignment statement and every input statement so I can see what's actually happening to the variables in my program. I usually use the DEC formatter so I can see the actual numeric value (if there's a character I'm storing in the variable and it's not printable). Don't just copy what I give you. Figure out how it works. Simulate your program on a piece of paper with a column for each variable and each line represents another point in time as your program executes. Figure out what the IF statements do. Figure out what the FOR statements do, step by step if needed.
  • RobbanRobban Posts: 124
    edited 2007-03-08 18:40
    I made also a big mistake....The Elm DOES send Capital letter (1A F8)
    Where down in the car and tried it and all i got was a constant number.
    I begin to understand your lines...:-D
    I just hooked up the stamp between my computer ,using one computer with pbasic term to send my hex...and the aother to show me the hex for each (i) and a debug dec value
    and this is what i got

    1: 1
    1: A
    2: F
    2: 8
    4931

    Shouldn´t the value be 6904?
    when i was down in the car....this was a constant value of 4931.



    Post Edited (Robban) : 3/8/2007 6:58:41 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 18:57
    I think you need to take some time to understand what the statements I gave you are supposed to do. Something like this:
    if x < "0" or x > "9" then skip1
      x = x - "0"
    skip1:
    if x < "A" or x > "F" then skip2
      x = x - "A" + 10
    skip2:
    


    If x contains a character, the first IF statement checks whether the character is a digit. If so, it subtracts the value of the character "0" to give a number between 0 and 9. If the character is outside of the range, nothing changes. The second IF statement checks to see if the character is an upper case letter between "A" and "F". If so, it subtracts the value of the character "A" and adds ten to give a number between 10 and 15. This is the way to translate a single hex digit to an equivalent numeric value. You can add another IF statement to take care of the lower case letter situation.

    In your case, I simply repeated this logic 4 times, once for each hex digit, then combined the 4 "nibbles" to make a 16 bit numeric value which you can display using a DEC formatter with a SEROUT statement.
  • RobbanRobban Posts: 124
    edited 2007-03-08 19:35
    oki...i begin the get the hang of what you mean,but what i don´t get is why i don´t get the value to 6904? it only shows 5272
    I calculated it and it´s missing 1632...

    Post Edited (Robban) : 3/8/2007 7:51:33 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 20:13
    Like I said, work through your situation on paper, using your actual program as a guide. I think you'll see where the error is.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 20:27
    Unsoundcode just pointed out to me that I left off needed parenthesis around the terms of this statement:
    value = hexstr(0) << 12 + hexstr(1) << 8 + hexstr(3) << 4 + hexstr(4)
    


    Unsoundcode is absolutely right (I keep confusing PBasic and Spin sometimes). It should be:
    value = (hexstr(0) << 12) + (hexstr(1) << 8) + (hexstr(3) << 4) + hexstr(4)
    
  • RobbanRobban Posts: 124
    edited 2007-03-08 20:40
    done....but now i get a value of 21912
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 20:43
    How about posting your actual program as an attachment to your next reply?
  • RobbanRobban Posts: 124
    edited 2007-03-08 20:51
    okej...here it is....not that i had to modify the str string and for..

    ' {$STAMP BS2}

    k VAR Byte
    hexstr VAR Byte(5)
    hexa VAR Word
    i VAR Byte
    value VAR Word

    main:
    SEROUT 0,16468,[noparse][[/noparse]"010c",13]
    SERIN 1,16468,[noparse][[/noparse]STR hexstr\11]
    FOR i=6 TO 11

    SEROUT 2,84,[noparse][[/noparse]hexstr(i)] - display the hex on lcd

    NEXT

    FOR k = 6 TO 7
    IF hexstr(i) < "0" OR hexstr(i) > "9" THEN skip1x
    hexstr(i) = hexstr(i) - "0"
    skip1x:
    IF hexstr(i) < "a" OR hexstr(i) > "f" THEN skip2x
    hexstr(i) = hexstr(i) - "A" + 10
    skip2x:
    NEXT
    FOR k = 9 TO 10

    IF hexstr(i) < "0" OR hexstr(i) > "9" THEN skip3x
    hexstr(i) = hexstr(i) - "0"
    skip3x:
    IF hexstr(i) < "a" OR hexstr(i) > "f" THEN skip4x
    hexstr(i) = hexstr(i) - "A" + 10
    skip4x:
    NEXT
    value =(hexstr(6) << 12) + (hexstr(7) << 8) + (hexstr(9) << 4) + hexstr(10)


    DEBUG "hex1:",hexstr(0),CR
    DEBUG "hex2:",hexstr(1),CR
    DEBUG "hex3:",hexstr(3),CR
    DEBUG "hex4:",hexstr(4),CR
    DEBUG "hex5:",hexstr(6),CR
    DEBUG "hex6:",hexstr(7),CR
    DEBUG "hex7:",hexstr(9),CR
    DEBUG "hex8:",hexstr(10),CR
    DEBUG DEC value
    SEROUT 2,84,[noparse][[/noparse]"?n",DEC value] - display the value on lcd
    PAUSE 1000
    'GOTO main

    Post Edited (Robban) : 3/8/2007 8:55:47 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-08 21:05
    In your modifications, you've created more problems than you've fixed. You really need to read the manual.

    1) You're now treating hexstr as an 11 character string, but it's only declared as a 5 character string. You have to either make hexstr bigger or go back to the way it was (as a 5 character string).

    2) You never fixed the IF statements. They're testing for lower case letters, but the assignment that follows is converting them as if they were upper case. I noted my error earlier and said you should fix it. I also suggested adding another IF/assignment/label for the upper case letters and you haven't done it yet. Please, if I make a suggestion, please, either protest the change and give me your reasons (which may be perfectly correct), or make the changes as I've given them. Otherwise, I will think you're doing one thing, but you've done another, and I can't understand why my suggestion doesn't work.
Sign In or Register to comment.