Home AMX User Forum NetLinx Studio
Options

ASCII to HEX string

Hi All, I'm trying to convert an incoming ASCII string to a HEX value. The incoming string contains an ASCII volume level such as '35' which is really the HEX value of the actual volume state of the device. I don't have a problem isolating the number from the incoming string, but I haven't found a way to convert it to a NetLinx HEX value. Any help would be appreciated.

Sample incoming string-- '!1VOL35'

Marc

Comments

  • Options
    viningvining Posts: 4,368
    Try using HEXTOI. Stores as a decimal value and just covert back a HEX string when using this value to send back to the device.
                          STACK_VAR CHAR cTRASH ;
    		    STACK_VAR INTEGER nFBS ;
    		    LOCAL_VAR INTEGER nVOL ;//probably global
    		    LOCAL_VAR INTEGER nPWR ;//probably global
    		    
    		    //cDevBuffer contains "'!1VOL35',13"  //globally declared var made into buffer.
    		    while (find_string(cDevBuffer,"13",1))
    			 {
    			 STACK_VAR CHAR cTempSTR[255] ;
    			 
    			 cTempSTR = REMOVE_STRING(cDevBuffer,"13",1) ;
    			 nFBS = find_string(cTempSTR,"13",1) ;
    			 if(nFBS > 1)
    			      {
    			      cTempSTR = GET_BUFFER_STRING(cTempSTR,nFBS-1) ;
    			      SELECT
    				   {
    				   ACTIVE(find_string(cTempSTR,"'!VOL'",1)):
    					{
    					cTRASH = REMOVE_STRING(cTempSTR,"'!VOL'",1) ;
    					nVOL = HEXTOI(cTempSTR) ;
                                                  }
    				   ACTIVE(find_string(cTempSTR,"'!PWR'",1)):
    					{
    					cTRASH = REMOVE_STRING(cTempSTR,"'!PWR'",1) ;
    					nPWR = HEXTOI(cTempSTR) ;
    					}
    				   ///continue
    				   }
    			      }
    			 }
    
  • Options
    adysadys Posts: 395
    you can do it like this

    strCmd = REMOVE_STRING(DATA.TEXT,'VOL ',1)
    strInfo = DATA.TEXT

    if(strCmd && (length_string(strCmd) > 0 ))
    {
    nBigByte = GET_BUFFER_CHAR(strInfo) // in your sample it will be 3
    nSmallByte = GET_BUFFER_CHAR(strInfo) // in your sample it will be 5

    nVolume = ATOI("nBigByte,nSmallByte")
    }
  • Options
    viningvining Posts: 4,368
    adys wrote:
    you can do it like this

    strCmd = REMOVE_STRING(DATA.TEXT,'VOL ',1)
    strInfo = DATA.TEXT

    if(strCmd && (length_string(strCmd) > 0 ))
    {
    nBigByte = GET_BUFFER_CHAR(strInfo) // in your sample it will be 3
    nSmallByte = GET_BUFFER_CHAR(strInfo) // in your sample it will be 5

    nVolume = ATOI("nBigByte,nSmallByte")
    }
    You can use data.text if the expected returned string is less that 255 or something but regardless I've found it to be a good habit to create buffers. It's just better.

    Using get_buffer-char to load the integer variable nBigByte or nSmallByte will likely cause a compiler warning w/o the use of TYPE_CAST or what ever that system function is.

    The end result is that you just coverted the ascii string value to an interger and not the hex value. Totally different result.
  • Options
    adysadys Posts: 395
    There is no compile warnings at all in this case, the vars declare as integer:

    INTEGER nBigByte
    INTEGER nSmallByte
    INTEGER nVolume

    CHAR strCmd[30]
    CHAR strInfo[100]


    And from what I see he want the decimal value of the volume...
    If he needs it in HEX he can convert it to hex with ITOHEX

    Is just one more way to do it, thats all :)
  • Options
    HedbergHedberg Posts: 671
    adys wrote:
    you can do it like this

    strCmd = REMOVE_STRING(DATA.TEXT,'VOL ',1)
    strInfo = DATA.TEXT

    if(strCmd && (length_string(strCmd) > 0 ))
    {
    nBigByte = GET_BUFFER_CHAR(strInfo) // in your sample it will be 3
    nSmallByte = GET_BUFFER_CHAR(strInfo) // in your sample it will be 5

    nVolume = ATOI("nBigByte,nSmallByte")
    }

    Two things:

    you are relying on the device sending exactly one complete string. If the device sends its strings out so that data.text is very likely to contain a complete string and nothing more, this is often ok. Some devices don't do this, however. You may find data.text to occasionally contain more than one string and sometimes an incomplete string. The "while" in VAVs example accounts for this (assuming that strings from the device have a standard ending character).

    The ASCII/hex representation in the string may be more than two bytes. and is likely if the possible volumes are from 0 through 255.

    If you are certain that data.text will contain exactly one complete string, you can put this all in one line:
    if(find_string(data.text,'!VOL',1)) nVolume = atoi(data.text)
    

    The ATOI function will ignore ascii characters that don't make sense as integers.
  • Options
    adysadys Posts: 395
    That is true.

    Vav solution is better and cover more scenarios.

    good to know this

    "The ATOI function will ignore ascii characters that don't make sense as integers"
  • Options
    viningvining Posts: 4,368
    Also because the device returns HEX values it is possible to recieve A-F values for volume and altough I've never tried ATOI on HEX letters A-F I beleive the ATOI function only works on acsii characters of decimal digits 0-9 which is why if you do ATOI("'ADD15'") returns the decimal value of 15. OK, I didn't actually run it to see but it should return 15.

    Just in case any one tries to use this I added and else statement to eliminate creating an infinite while loop should "13" end up in the begining of the buffer. In this example I added the "13" delimiter which the device may not actually provide.
    STACK_VAR CHAR cTRASH ;
         STACK_VAR INTEGER nFBS ;
         LOCAL_VAR INTEGER nVOL ;//probably global
         LOCAL_VAR INTEGER nPWR ;//probably global
         
         //cDevBuffer contains "'!1VOL35',13"  //globally declared var made into buffer.
         while (find_string(cDevBuffer,"13",1))
    	  {
    	  STACK_VAR CHAR cTempSTR[255] ;
    	  
    	  cTempSTR = REMOVE_STRING(cDevBuffer,"13",1) ;
    	  nFBS = find_string(cTempSTR,"13",1) ;
    	  if(nFBS > 1)
    	       {
    	       cTempSTR = GET_BUFFER_STRING(cTempSTR,nFBS-1) ;
    	       SELECT
    		    {
    		    ACTIVE(find_string(cTempSTR,"'!VOL'",1)):
    			 {
    			 cTRASH = REMOVE_STRING(cTempSTR,"'!VOL'",1) ;
    			 nVOL = HEXTOI(cTempSTR) ;
    			       }
    		    ACTIVE(find_string(cTempSTR,"'!PWR'",1)):
    			 {
    			 cTRASH = REMOVE_STRING(cTempSTR,"'!PWR'",1) ;
    			 nPWR = HEXTOI(cTempSTR) ;
    			 }
    		    ///continue
    		    }
    	       }
    	  else
    	       {
    	       cTRASH = REMOVE_STRING(cTempSTR,"13",1) ;
    	       }
    	  }
    
  • Options
    nancekj19nancekj19 Posts: 8
    I agree

    with vining, here is a sample copied out of a working Integra code block..



    DATA_EVENT[dvFAMILY_RCVR]
    {
    STRING:
    {
    cFAM_RCVR_BUF = "cFAM_RCVR_BUF,DATA.TEXT"
    WHILE(FIND_STRING(cFAM_RCVR_BUF,"$1A",1))
    {
    cFAM_RCVR_DATA = REMOVE_sTRING(cFAM_RCVR_BUF,"$1A",1)
    IF(FIND_STRING(cFAM_RCVR_DATA,"'!1PWR'",1))
    {
    IF(FIND_STRING(cFAM_RCVR_DATA,"'00'",1))
    {
    nFAM_RCVR_POWER = 0
    }
    ELSE IF(FIND_STRING(cFAM_RCVR_DATA,"'01'",1))
    {
    nFAM_RCVR_POWER = 1
    }
    }
    ELSE IF(FIND_STRING(cFAM_RCVR_DATA,"'!1MVL'",1))
    {
    REMOVE_STRING(cFAM_RCVR_DATA,"'MVL'",1)

    nFAM_RCVR_VOL = HEXTOI(LEFT_STRING(cFAM_RCVR_DATA,2))
    }
    }
    }
    }
  • Options
    HedbergHedberg Posts: 671
    "Also because the device returns HEX values it is possible to recieve A-F values"

    True. the function to use in this case is HEXTOI, and not ATOI.
  • Options
    Thanks to All

    Thanks to everyone for the help on this- I didn't get a chance to reply earlier, but your quick responses helped me work this out.
    Marc
Sign In or Register to comment.