Home AMX User Forum NetLinx Studio

DEFINE_FUNCTION

Hi, can someone link me to an example of this ( or post one ). I have never used one before. How to employ it also escapes me.

Thanks

Best Answer

Answers

  • PatGPatG Posts: 42

    Excellent thanks

  • PatGPatG Posts: 42

    Here is the example given in the course material, all of which makes sense to me, except when calling it I'm not sure what sBuffer is referring to. I know I need the return but I don't get what this sBuffer is which is wherein the return would reside I'm guessing

  • PatGPatG Posts: 42

    Sorry here is the image url https://imgur.com/a/BGbmegi

  • viningvining Posts: 4,368

    sBuffer for this checksum function should contain all those hex values but this snippet doesn’t show where or how that gets populated.

  • HARMAN_ChrisHARMAN_Chris Posts: 597

    Pat - the screenshot is from the overview video and is more of a static example. Did the content that followed the overview, and gave real examples inside Netlinx Studio help clarify this concept for you? Be sure to watch the concept review video at the end of the section which will walk through the completed exercise and demonstrate one way to solve for the task.

  • PatGPatG Posts: 42

    @HARMAN_Chris said:
    Pat - the screenshot is from the overview video and is more of a static example. Did the content that followed the overview, and gave real examples inside Netlinx Studio help clarify this concept for you? Be sure to watch the concept review video at the end of the section which will walk through the completed exercise and demonstrate one way to solve for the task.

    I did a few times but the example they use in that case is quite a bit different from the one I posted. I have a method that works but it's no where near as elegant as I think this could be. For example I have a device the will return different length strings depending on the command so I have a function for each which is like

    DEFINE_FUNCTION CHAR fnChecksum6 (CHAR cPROJ_BUFFER[]) //Checksum for projector strings
    {
    STACK_VAR CHAR Result
    Result = cPROJ_BUFFER[1]+cPROJ_BUFFER[2]+cPROJ_BUFFER[3]+cPROJ_BUFFER[4]+cPROJ_BUFFER[5]
    RETURN Result
    }

    And that's only for returned strings, I have different functions for different length send_strings, all to calculate the checksum. I feel like I'm defeating the purpose of using a function.

  • ericmedleyericmedley Posts: 4,177

    I cannot tell what kind of variable cPROJ_BUFFER[] is. I'm assuming it's a char.

    Netlix is a bit funn when it comes to type casting. What you might think of as a char in other environments is not exactly what Netlinx does. Can you post what the string you're working with is?

  • HARMAN_ChrisHARMAN_Chris Posts: 597
    edited June 2019

    Can you leverage a FOR loop with the LENGTH_STRING(cProj_Buffer[]) as the loop count limiter within a single function?

    Like Eric mentioned, I was concerned about data types, but after trying several combinations of ATOI or HEXTOI - it didn't end up needing it to correctly perform the additive math I was going for in this demo. We still do not have the full details of what you are trying to accomplish, but based on my assumptions - here is what I wrote to test the function. NOTE - as a calculation, you need this function to be an INTEGER and not a CHAR for the return type.

    PROGRAM_NAME='FunctionTest'
    DEFINE_DEVICE
    dvTP = 10001:1:0
    
    DEFINE_CONSTANT
    INTEGER nTestBtns[] =
    {
        1,
        2,
        3
    }
    
    DEFINE_VARIABLE
    CHAR cSampleData[3][10]
    
    DEFINE_FUNCTION INTEGER fnCheckSum (CHAR cPROJ_BUFFER[])
    {
        STACK_VAR INTEGER nResult;
        STACK_VAR INTEGER nTempCounter;
    
        SEND_STRING 0, "'fnCheckSum called with cPROJ_BUFFER LENGTH of ',ITOA(LENGTH_STRING(cPROJ_BUFFER))";
    
        FOR(nTempCounter=1; nTempCounter<= LENGTH_STRING(cPROJ_BUFFER); nTempCounter++)
        {
        nResult = nResult + cPROJ_BUFFER[nTempCounter]
        }
        RETURN nResult;
    }
    
    DEFINE_START
    cSampleData[1] = "$10"; // SUM = 16
    cSampleData[2] = "$10,$11,$5E"; // SUM = 127
    cSampleData[3] = "$10,$11,$5E,$24"; // SUM = 163
    
    DEFINE_EVENT
    BUTTON_EVENT [dvTP, nTestBtns]
    {
        PUSH:
        {
        SEND_STRING 0, "'RETURNED SUM = ', ITOA(fnCheckSum(cSampleData[GET_LAST(nTestBtns)]))"
        }
    }
    
  • PatGPatG Posts: 42

    Thanks everyone, I did have some success in that the function works when I send strings but not on the ones I receive. I think it's because a received string will already contain a checksum, which ends up added to the rest of the string and THEN my function is coming up with a checksum based on that, if that makes any sense.

    Here is my function if you're interested:

    DEFINE_FUNCTION integer fnChecksum (CHAR cSend_Proj[]) //Checksum for strings to projector
    {
    STACK_VAR integer i
    STACK_VAR CHAR ckSum
    for(i=1;i<=LENGTH_STRING(cSend_Proj);i++)
    {
    ckSum = ckSum + cSend_Proj[i]
    }
    RETURN ckSum
    }

    And to execute

        cInput_String = "inPROJCOMP, fnChecksum(inPROJCOMP)" //$19" 
    SEND_STRING dvProj,"cInput_String" //Component
    

    Where inPROJCOMP is just a constant containing all the hex values.

    If I am right about the send vs receive string I can live with it like this. Just getting it to work on the sent strings saved a lot of code. THanks again for all your help.

  • ericmedleyericmedley Posts: 4,177

    One thing you might do (I do this always as a matter of course) is to change
    STACK_VAR CHAR ckSum
    to
    STACK_VAR CHAR ckSum[1]

    It may seem counter-intuitive since a one-celled char array is implied by the first statement. but I find that Netlinx seems to like a little help when it comes to arrays. Like I said earlier, Netlinx is a bit funny when it comes to Types. Most other languages are not so wonky when it comes to variables.

Sign In or Register to comment.