Shop OBEX P1 Docs P2 Docs Learn Events
Hexadecimal conversions and trimming outputs...? — Parallax Forums

Hexadecimal conversions and trimming outputs...?

ChemikalChemikal Posts: 32
edited 2009-05-04 09:06 in Propeller 1
Evening all,

I am working with some outputs from a XBee, and some results are returned in hexadecimal which I want to convert to their decimal equivalents...

How would I do the following?:
I am receiving "313131" (hexadecimal), storing it as a variable "myNI", and want to convert it to the binary equivalent of "111", storing it to another variable...?

I tried playing with the Numbers object, and when I enter NUM.fromstr(myNI,{format}), where I have tried using 'HEX' as the format, it says it is missing an expression term?, or 'Num#Dec', as I have seen used before, results in a strange number and I cannot figure out the 'Num#' part of that use from the notes in the Numbers object file...


Also, how does one trim a hex 'string'? (It's not a string, per se... it's a variable that I have saved as a long)
ie: I have "0C125"... how do I trim the "0C" off the front, leaving just the "125"?



Appreciate the help,
- Josh

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2009-05-01 07:18
    Hello Josh,

    without any code that you have tried it is hard to explain what wen wrong.

    If you receive bytes you should receive them into an array of bytes.
    you wrotethat you stored the received hex "313131" into a variable.

    This is possible to do but not the best way of storing hexadecimal bytes
    as you have to deal with bitshifting to get this done

    It is much easier to receive bytes into a bytearray.

    I stop here explaining to show you how important it is to have DETAILS.

    From this explanation you have just a LITTLE idea of what has to be done
    and for me it is the same from what you have written
    I have only a LITTLE idea of what you want to to

    So please explain the details and what you want to do in the end

    I bet there will be other, easier and more elegant solutions to your problem
    if you describe what you want to do in the end.

    best regards

    Stefan
  • ChemikalChemikal Posts: 32
    edited 2009-05-01 16:55
    Stefan, ease up.

    It is as a byte array in the receive buffer, but that is constantly being flushed, so I cannot keep the bytearray around for long. It would not be beneficial to save it to another bytearray, as I am simply looking to display it on a LCD screen, which is why I need a decimal format so that a person can make sense of it and match it to the actual configuration data (the XBee is configured for some terms with decimal format, but queuing the XBee results in hexadecimal output of the same term).

    I am just getting into being comfortable working with hexadecimal and I know how to go from hex to dec by hand, but I was wondering if there was already a boxed solution before I went and made my own code for it when I would like to be focusing on other items.


    I don't think what I asked is that vague... I have myNI = "313131", and I guess I want to group that into groups of two, and then output the hexadecimal equivalents ($31=1) into a combined string: "111", OR any other more elegant method... that's just how I would do it at this time

    But the only way I can think of doing that would be to have some sort of a trim command or method (is there one?)... ie: take 2 numbers, trim off the rest, and start saving it to an array, such as:

    NI{0} := 31
    NI{1} := 31
    NI{2} := 31
    (* I am using {} so the forum doesnt parse the brackets)
    then convert each to hex and recombine, which I also cannot find any information on how to do (combining data)... I know how to do it in five or so other languages for PHP, PERL, and Python (ie: FinalString := NI{0} . NI{1} . NI{2} )... but I do not know how to do it with Spin... bit shifting?

    Post Edited (Chemikal) : 5/1/2009 5:02:38 PM GMT
  • simonlsimonl Posts: 866
    edited 2009-05-01 17:36
    @chemikal: I'll try to explain the "NUM#DEC" bit for you:

    Say you declared the numbers object like this:
    OBJ
      NUM : "Numbers"
    



    That's where the "NUM" part comes from.

    The # symbol is an Object-Constant reference; it is used to reference a constant that was defined in the NUM object.

    So; NUM#DEC is effectively getting the value of constant "DEC" from the Numbers object, to save you having to enter the DEC value yourself.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    “Before you criticize someone, you should walk a mile in their shoes. That way when you criticize them, you are a mile away from them and you have their shoes.” - Jack Handey.
  • simonlsimonl Posts: 866
    edited 2009-05-01 17:49
    Hmmm; Hex 31 is the string value of "1", hence the "111" == "313131".

    I'm not sure why NUM.fromstr( myNI, NUM#DEC ) doesn't give what you're expecting. Are you sure myNI is what you expect? Maybe you could try
    NUM.fromstr( @myNI[noparse][[/noparse] 0 ], NUM#DEC )
    


    I'm not able to test that right now, so I'm just guessing!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    “Before you criticize someone, you should walk a mile in their shoes. That way when you criticize them, you are a mile away from them and you have their shoes.” - Jack Handey.
  • ChemikalChemikal Posts: 32
    edited 2009-05-01 18:45
    Simonl,

    Thanks for the clarification - makes sense now. I did not know that was the method for referencing a constant defined in another object - good to know.

    when I tried entering it manually: NUM.fromstr(313131,NUM#DEC), I got "0" as a result I believe... doesn't it require some identifier so that it knows that I am entering a hexadecimal that should be grouped into groups of two? How does it know that 313131 is a hexadecimal? I tried $313131 and $31_31_31 to no result...

    Also, back to my combining strings question, how would I add a '$' to the front of a number?... I have the variable myNI = 313131... how can I add a '$' to the front to make it '$313131'?
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-01 18:59
    What do you think is fromstring doing?? It converts a string to a binary number. I'd guess that fromstr will return a long.
    So, the first parameter is a pointer to a string. If you want to give a value directly, then you would write:

    value:=NUM.fromstr( string( "111" ), NUM#HEX )

    The second parameter is giving the format of the string. If you use NUM#DEC this would also work with that string, because 1 is a valid number in decimal as well, but the result will be different. If you look at the memory where the string is stored you would see:
    $31 $31 $31 because $31 is the ascii code of "1"

    If you want to convert different hexadecimals to a value, it makes sense to have a byte buffer which will keep the ascii characters:
    VAR
    byte number[noparse][[/noparse]9]

    This buffer would be big enough to store 8 hexadecimal digits (which is the max for a 32 bit value)·plus the 0 for string termination.

    number[noparse][[/noparse] 0 ]:=$31
    number[noparse][[/noparse] 1 ]:=$31
    number[noparse][[/noparse] 2 ]:=$31
    number[noparse][[/noparse] 3 ]:=$00

    value:=NUM.fromstr( @number, NUM#HEX )

    Post Edited (MagIO2) : 5/1/2009 7:04:44 PM GMT

  • ChemikalChemikal Posts: 32
    edited 2009-05-04 03:37
    Ok, I am better with my understanding of hexadecimals and was able to convert my previous hex result with a case statement and some multipliers - works great, thanks for the help... but after moving onward, I now have an interesting issue:

    This response I receive from my XBee contains the number I am looking for when I look at the hex, but it seems like it is in decimal within it? This is what I mean:

    I am looking to extract "125" from the buffer, as I am queuing my XBee's configuration and that is the proper response... here is my code for clarification:

    API_Query(string("ID"))                               'AT Command: ID, PAN ID
      bytefill(@API_Buffer,0,200)                           'Zero out API buffer so it can be used to collect XB response
      waitcnt(40_000_000 + cnt)                             'Give the buffer some time to fill in response to the question
      index:=0
      repeat while (API_Buffer[noparse][[/noparse]index++] := SER.rxcheck(XBEE)) <> -1
      repeat index from 8 to 11
        myID := ( myID << 8 ) | API_Buffer[noparse][[/noparse]index]
    


    That is where I am getting the long 'myID' from. Reading the value,

    LCD.hex(myID,8)
    


    results in: '0125C0FF'

    How can I get that number for use as a decimal variable... say, get it to a variable 'myIDnum' == 126?

    Reading it as bytes, I can only get '01' and '25'.... I can trim down my long via 'repeat index from 8 to 9', to have only '00000125' output, but that is still hexadecimal... with a nested decimal(?)... I don't know what to do here...


    Thanks guys -
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-04 09:06
    Is the 0 in '0125C0FF' part of the ID as well? If yes:
    myIDnum := myID>>16

    If no:
    myIDnum := myID>>16 & 0x0fff

    I think you still miss some parts in the puzzle. The way that data is stored in a CPU is in bits - there is no other way! What the bits mean is defined by the program that uses these bits. In your case the bits represent an ID. myID = '0125C0FF' is stored as %0000_0001_0010_0101_1100_0000_1111_1111. When you call the LCD.hex function you call some part of code which translates this bitpattern to a human readable format - a hex-string. If you call LCD.dec instead, you call a part of code which translates this bitpattern to a decimal string. Both strings will look different, but the number behind is the same.
    If you calculate in SPIN you don't calculate in HEX or in DEC. The CPU only knows binary. SPIN of course knows $ and % and decimals, but this will be translated to binary during compilation.
Sign In or Register to comment.