Home AMX User Forum NetLinx Studio
Options

Hexadecimal Conversions

Hi..

I am trying to write a program to control TACT amplifier, an excellent amplifier with a creepy rs232 protocol

my client wants to ramp the volume up and down using a bar graph, so i created a level event for this bar graph to store the last level value of it and make some calculations to convert this level to two hex words..using ITOHEX conversion keyword which returns an ascii string.

My problem is how to send this new hex value back to the device?

Comments

  • Options
    mpullinmpullin Posts: 949
    Could you post the protocol?
  • Options
    SensivaSensiva Posts: 211
    Didn't want to annoy you :D

    SET MASTER LEVEL
    $08,$01,$80,$6D,$01,$xx1,$xx2,$xx3
    LEVEL = GAIN x 10
    GAIN 00.0 = 000
    GAIN 00.1 = 001
    GAIN 01.0 = 010
    GAIN 01.3 = 013
    CONVERT LEVEL TO 16BIT HEX
    xx1= MOST 8BIT
    xx2= LEAST 8BIT
    xx3 = (SUM OF ALL SEGMENTS) AND FF
    EXAMPLE: SET TO GAIN 62.2
    LEVEL = 62.2 x 10 = 622
    LEVEL(HEX)=026E
    xx1=02 xx2=6E xx3=(8+1+80+6D+01+2+6E) AND FF=67
    FINAL STRING $08,$01,$80,$6D,$01,$02,$6E,$67
  • Options
    AMXJeffAMXJeff Posts: 450
    $08,$01,$80,$6D,$01,$xx1,$xx2,CS

    EXAMPLE: SET TO GAIN 62.2
    LEVEL = 62.2 x 10 = 622

    // Answer
    DEFINE_VARIABLE
    CHAR MSG[100];
    INTEGER LEVEL;
    
    DEFINE_FUNCTION INTEGER CalcChecksum(CHAR cMsg[])
    {
    	STACK_VAR INTEGER nLoop;
    	STACK_VAR INTEGER nCS;
    	
    	nCS = 0;
    	
    	FOR (nLoop = 1; nLoop <= LENGTH_STRING(cMsg); nLoop++)
    		nCS = ((nCS + cMsg[nLoop]) & $FF);
    		
    	RETURN nCS;
    }
    
    DEFINE_START
    
    LEVEL = 622;
    
    MSG = "$08,$01,$80,$6D,$01,((LEVEL / $100) % $100),(LEVEL % $100)";
    
    MSG = "MSG, CalcChecksum(MSG)";
    
    
  • Options
    SensivaSensiva Posts: 211
    Two Questions

    Thanks for your piece of code , i really appreciate it :)
    but there are two questions out of my head now
    1st:: You didn't convert the integer LEVEL into HEX, and then divided LEVEL by $100.... is this a valid method.. i mean how netlinx could do such a math dividing a decimal value by a hexa value.

    2nd:: i can realize a new concept from your code.. which is in netlinx a character type variable can hold characters whatever it's representations?

    Thanx again
  • Options
    mpullinmpullin Posts: 949
    A representation of data is just that. nVariable = 49; nVariable = '1'; nVariable = $31; All these put the same value into nVariable. Similarly, nVariable = 100 / $31; is the same as nVariable = 100 / 49; There is no need to translate from "hex" to "integer" in order to do math.
  • Options
    AMXJeffAMXJeff Posts: 450
    Good Question

    Question 1 Answer:

    Decimal, Hex and Binary are just three different way at viewing numerical values.

    A computer always see the values as binary. Where a human can see the numerical value in any way that make most sence to him. With out talking about a string literal representation of numerics. Just talking straight numerics, we use the Value that make most sence to us.

    Dec Hex Binary
    622 == 26E == 0000001001101110 == no conversion needed.

    Decemel is Base 10
    Hex is Base 16
    Binary Base 2

    It is easier for me to translate from base 16 to base 2 then it is for me to translate from base 10 to base 2. Each Digit in a hexidecimal number represents four binary digits.

    0 2 6 E
    0000 0010 0110 1110

    So....
    DEFINE_VARIABLE
    
    INTEGER VAR1 = 622;
    INTEGER VAR2 = $26E;
    
    DEFINE_PROGRAM
    
    IF (VAR1 == VAR2)
    {
      // THIS IS TRUE!!!!!!!!!!!!!!!!!
    }
    
    

    Good reading in this link...
    http://mathforum.org/dr.math/faq/faq.bases.html

    Question 2 Answer:

    Not all variable types can be used in this fashion. NetLinx allows integer variable to be placed in char arrays. NetLinx truncates the top byte in this mode. Thereby leaving only the lower byte. The math that I did made sure NetLinx used the information that I needed.
    DEFINE_VARIABLE
    INTEGER VAR1 = 622; // SAME AS $26E
    INTEGER VAR2;
    INTEGER VAR3;
    
    DEFINE_PROGRAM
    
    // VAR2 = $02, TOP BYTE
    VAR2 = ((VAR / $100) % $100);
    
    // VAR3 = $6E, LOWER BYTE
    VAR3 = (VAR % $100);
    
    
  • Options
    SensivaSensiva Posts: 211
    Ok AMXJeff

    Nice.. but i am completely aware about based numeric systems...
    when i have read about conversion keywords i thought that variable can hold the value in its assigned base, i mean when assigning $26E to VAR1 it means that i can't use it in Send_string commands, or why there is a keyword ITTOHEX or HEXTOI ???,it is little confusing... but i will do some practice to figure this out, and i appreciate your help

    Now... assume that i have two TP buttons for Volup(21) and Voldn(20)
    and these are the rs232 commands
    $06,$01,$80,$6E,$01,$F6 // volup
    $06,$01,$80,$6E,$00,$F5 // voldn

    now i wanna stack the two butt events like this
    Button_Event [tp,21] //volup
    Button_Event [tp,20] //voldn
    {
        push:
        {
            
        }
    }
    
    i don't want to use switch case for Button.input.channel
    i wanna use the relation between the two commands (the bold segment)
    by doing some math like But.inp.chan - 20 then convert to hex , build the string -i don't care about the Checksum calcs now - and send it!!
    i hope you got what i wanna say :)
  • Options
    AMXJeffAMXJeff Posts: 450
    HEXTOI and ITOHEX do not do what you think they do. ITOHEX converts from an Integer value to a string literial representation of hex. HEXTOI converts from a string literial representation of hex to an integer value. In the protocol you showed us, it is not looking for a string literial representation of hex. It is looking for individual bytes of data.

    so...
    DEFINE_VARIABLE
    CHAR cStringLiterial[] = '026E'
    INTEGER nInteger;
    
    DEFINE_PROGRAM
    
    // nInteger = 622
    nInteger = HEXTOI(cStringLiterial);
    
    
  • Options
    AMXJeffAMXJeff Posts: 450
    Second Item

    No need to convert to hex, same reasons as above...
    DEFINE_FUNCTION INTEGER CalcChecksum(CHAR cMsg[])
    {
    	STACK_VAR INTEGER nLoop;
    	STACK_VAR INTEGER nCS;
    	
    	nCS = 0;
    	
    	FOR (nLoop = 1; nLoop <= LENGTH_STRING(cMsg); nLoop++)
    		nCS = ((nCS + cMsg[nLoop]) & $FF);
    		
    	RETURN nCS;
    }
    
    DEFINE_EVENT
    
    Button_Event [tp,21] //volup
    Button_Event [tp,20] //voldn
    {
        push:
        {
            STACK_VAR CHAR MSG[100];
    
            // HEX $01 == DECIMAL 1, HEX $00 == DECIMAL 0
            MSG = "$06,$01,$80,$6E,BUTTON.INPUT.CHANNEL - 20"
    
            MSG = "MSG, CalcChecksum(MSG)";
    
            SEND_STRING dvRS232,"MSG";
        }
    }
    
    
  • Options
    SensivaSensiva Posts: 211
    Conclusion

    Thanx...

    So.. At last the conclusion is as all devices communicate with each other in Binary code... so i don't have to care about conversion because when i notate $26E will tell the master that it has to convert from hex to binary
    '26E' convert from ASCII to binary
    26 convert from decimal to binary
    and i can make one variable hold as many bases as i want
    VAR="$26E,'AsciiString',26"
    and when sending it , the master gonna do the job

    Thanx Jeff... you made my day :D

    but one more silly question: why do you terminate your line with this [size=+2];[/size]?
  • Options
    AMXJeffAMXJeff Posts: 450
    Habit

    Since I am a programmer in many languages, I use the semi-colon at the end of the line bacause it is a habit. NetLinx allows it, so I do not have to change. It does help NetLinx find the end of line better, in some cases it is needed.

    This code cause a syntax error, the compiler thinks the first square bracket belongs to the variable decleration, assuming it is an array.
    DEFINE_FUNCTION SOMETHING()
    {
        STACK_VAR CHAR cTest
    
        [dvRS232,1] = ![dvRS232,1]
    }
    
    


    The semi-colon tells the compiler where the end of line is, and fixes the syntax issue.
    DEFINE_FUNCTION SOMETHING()
    {
        STACK_VAR CHAR cTest;
    
        [dvRS232,1] = ![dvRS232,1];
    }
    
    
  • Options
    SensivaSensiva Posts: 211
    Thanx for the update

    I consider this as one of the fabioulus things in Netlinx , in your case you do programming in many other languages, so when doing some Netlinx you will not suffer the confusion.

    Cheers
Sign In or Register to comment.