Home AMX User Forum NetLinx Studio

ITOHEX Problem

TurnipTruckTurnipTruck Junior MemberPosts: 1,485
Greetings Again,

I am using ITOHEX in a serial string which I am sending to a device.

The device interprets all data as the ASCII representation of the hex values. Therefore if I want to send it three $FFs the command would be SEND_STRING dvDEVICE,'FFFFFF'

The problem is this: For example if I want to send a 5 the device must see '05' not just the '5' that the ITOHEX command sends. Values greater than hex F are not an issue.

I can IF-THEN it to pack an extra '0' into the string for values under hex 10, but that is not very glorious, especially when several variables make up the command.

Any ideas?

Thank you.

Comments

  • Joe HebertJoe Hebert Junior Member Posts: 2,159
    Format
    The problem is this: For example if I want to send a 5 the device must see '05' not just the '5' that the ITOHEX command sends. Values greater than hex F are not an issue.
    There is more than one way to accomplish your goal but I'm partial to the FORMAT function. FORMAT is the equivalent to ITOA or ITOHEX on steroids.

    Here is some example code. Check out the help file for a list of all possible formatting options
    DEFINE_DEVICE
    
    dvTP = 10001:1:0
    
    DEFINE_VARIABLE
    
    CHAR	cByte1 = 5
    CHAR	cByte2	= 32
    CHAR	cByte3	= $0A
    
    DEFINE_EVENT
    
    BUTTON_EVENT [dvTP,1] {
    
       PUSH: {
          //this will send out the string '05200A'
          SEND_STRING 0, "FORMAT('%02X',cByte1),FORMAT('%02X',cByte2),FORMAT('%02X',cByte3)"
       }
    }
    
  • Very simple

    Here is a simple way to get your ASCII '0' in front of the '5' to make '05'.
    This function should work for any integer 0-255.
    Define_Device
    dvDEV	=  5001:1:0
    dvTP	= 10001:1:0
    
    Define_Variable
    Char cString[2]
    
    Define_Function fnFormat_HEX(nNumber)
    {
      cString = Right_String(" '0',ITOHEX(nNumber)",2)
    }
    
    Define_Event
    
    Button_Event[dvTP,1]
    {
      Push:
      {
        fnFormat_HEX(5)
        Send_String dvDEV,"cString "  // Should send out '05'
      }  
    }
    
  • DHawthorneDHawthorne Old Timer Posts: 4,584
    ITOHEX is for human readability, not for sending to a device, unless that device wants the ASCII representation of a hex value (I never understood why, but I've seen it). Your problem is the single quotes, they are telling the compiler you want ASCII. If you want to send a pure, unconverted HEX 5, the leading zero is not important. But send it as "5", not as '5'. For values over 9, you need to add the $ so the compiler knows it's not decimal, so F needs to be sent as "$F" - no single quotes. No conversion is necessary. Just remember that it is a string, and you have to specific the individual CHAR elements, breaking them apart with commas. Single quotes automatically cocatenate them, but also convert to ASCII.

    In other words, the way you type your value into the SEND_STRING has your conversions built in.

    SEND_STRING DEVICE, "$F,$F,$F,$F,$F,$F"
    and
    SEND_STRING DEVICE, "15, 15, 15, 15, 15, 15"

    ... are the same thing.

    Likewise, "5", and "$5" and "$05" are identical as well. Using '5', however, is going to get you 53, or $35. 'F' = 70, or $46. 'FFFFFF', as in your example, is really "$46, $46, $46, $46, $46, $46" or "70, 70, 70, 70, 70, 70".

    Clear as mud yet? :)
  • DHawthorne wrote:
    ITOHEX is for human readability, not for sending to a device, unless that device wants the ASCII representation of a hex value (I never understood why, but I've seen it).

    Dave,

    This is exactly what TrunipTruck is asking for; the ASCII representation of a hex value.

    He needs to format a send_string as an ASCII representation of HEX. I have seen this requirement quite a bit. MODBUS protocol comes to mind as an example.

    The data might calculate out as an integer expression "7,2" (two bytes - tens and one to perhaps represent a temperature set point), but the receiving device needs to see '0702' (4 bytes).

    Brian
  • DHawthorneDHawthorne Old Timer Posts: 4,584
    Ah, I thought he was saying the ASCII representation of the hex was the problem ... I misread it.
  • joe hebert is very right.. use

    FORMAT('%02X',AnInteger)

    where FORMAT will return a padded string of the integer value.

    the '%' symbol indicates start of conversion. the '0' represents the padding character. the '2' represents how much padding to perform. the 'X' means reveal the integer as hex. use 'D' if you want to reveal the decimal value.

    so, %03D would return the string 010 if you passed an integer of 10.
    or, %03X would return the string 00A if you passed an integer of 10.

    i use the format command to convert variable volume levels directly to command string to devices. an example for an Integra receiver is..

    !1MVL%02X

    will allow the variable volume control string to be sent. (this is an example of converting a hex value to a string that Dhawthorne mentioned, as in why :) (i sometimes wonder myself))
  • i just wanted to make a slight suggestion regarding B Clements example.

    it's also a valid example. i justed wanted to highlight that define_function can return a value, so there is no need for an external (global and perhaps overwritable from another process) string.

    i am probably preaching to the converted, or stating the obvious or performing some other foot in mouth routine; but i just wanted to clear that one up :)

    <code>
    define_constant
    MAXBUFFER = 64

    Define_Device
    dvDEV = 5001:1:0
    dvTP = 10001:1:0

    Define_Function char[MAXBUFFER] fnFormat_HEX(integer nNumber)
    {
    return Right_String(" '0',ITOHEX(nNumber)",2)

    // or return FORMAT('%02X',nNumber)
    }

    Define_Event

    Button_Event[dvTP,1]
    {
    Push:
    {
    Send_String dvDEV,fnFormat_HEX(5) // Should send out '05'
    }
    }
    </code>
  • Great points!

    Thanks Richard, both good posts.

    I can honestly say I have never played with the format command, but it looks pretty cool.

    There are always multiple ways to do the same thing. I believe it is just a matter of style and level of comfort with the method. Any reduction in typing is always a good thing.

    Brian

    P.S. I wonder which method TurnipTruck decided to use?

    Also, I believe this thread should be moved to Tips and Tricks.
  • Peter KnappPeter Knapp Junior Member Posts: 20
    FORMAT is a wonderful tool!

    There are so many things that can be done with format. As was previously stated it is like ITOHEX or ITOA on steriods. It was introduced in the NetLinx Programmer or ProgrammerII course, but was not probably given as much time as it deserved - there are so many things that needed to be covered.

    The prefixing a '0' routine Brian posted works great, but the format command only requires a single statement. Way elegant!

    PDK
  • TurnipTruckTurnipTruck Junior Member Posts: 1,485
    Thank you very much for all of the suggestions!

    Someone was wondering which method I would use. I haven't tried any yet! Hopefully sometime this weekend. Appearantly there's some snow coming here, perfect weather for code-tweaking!

    The use of FORMAT the Joe Hebert suggested seems like what I'll try. It seems to fit best into my personality of programming.

    Didi I mention how helpful these forums can be???? :)
  • Chip MoodyChip Moody Junior Member Posts: 727
    Hopefully sometime this weekend. Appearantly there's some snow coming here, perfect weather for code-tweaking!

    TT, where are you located? I'm in NJ - getting the start of what is supposed to be 8 - 12 inches of snow...

    - Chip
Sign In or Register to comment.