Home AMX User Forum AMXForums Archive Threads Tips and Tricks

Best practice question (migrate from ni to nx)

Hi,

I'm currently updating an ni system to a nx-4200. I have 2 questions regarding code structure.

I presume the ni program was originally an accent because a lot of work were done in define program ( feedback, serial parsing) and no define_function only define_call.

1). I'm creating ? timeline_event to provide feedback. It is better to use everything in the timeline_event with a timeline. S?quence or create a function feedback() and recall it inside the timeline. Prior i was using my feedback() in define_program but with the nx serie is no more recommand?s to use

2) do i still using define_call or replace them with define_fonction.


Thanks for your input.

Comments

  • ericmedleyericmedley Posts: 4,177
    Functionally speaking I don't think it matters one way or another whether you put all the feedback code right in the Timelin_event or pass it out to a function. Since Netlinx is not a multi-thread language you can almost think of a function (or call for that matter) as a GOTO. I still do it as a matter of principle as I like to keep my code clean and I like to keep work-a-day code in my functions. That way there's typically only one place I need to go to make global changes to a section of code that might be hit by several events other than just a FB timeline. (For example if a TP comes online, I might want to update the same FB set)


    I actually don't use define_call myself as it's left over from olden days of yore... But I think it still works just fine in the NX series procs.

    You also might want to take a look at the modules being used. There may be newer ones.
  • GregGGregG Posts: 251
    Personally, I like to put multiple event blocks for the same feedback timeline around in the code, near where they apply, like:
    Button_Event[dvTP, BTN_DEVICE1_POWER]
    {
        Push: SendDevice1PowerOn()
    }
    Timeline_Event[TL_FEEDBACK]
    {
        [dvTP, BTN_DEVICE1_POWER] = nDevice1PowerOn
    }
    
    Button_Event[dvTP, BTN_DEVICE2_POWER]
    {
        Push: SendDevice2PowerOn()
    }
    Timeline_Event[TL_FEEDBACK]
    {
        [dvTP, BTN_DEVICE2_POWER] = nDevice2PowerOn
    }
    
  • RaphayoRaphayo Posts: 111
    Correct me if i'm wrong, but i think the difference between define_call & Define_function is that the code line wait the completion of define_call before to continue instead of the define_function the code continue during the process of the function. Am I Correct?


    For the TP Feedback, it will be better to have a timeline_event for everyTP who will be activate if the tp goes online.


    GregG approach for timeline is very easy to read, button_event follow by timeline_event.

  • ericmedleyericmedley Posts: 4,177
    Raphayo wrote: »
    Correct me if i'm wrong, but i think the difference between define_call & Define_function is that the code line wait the completion of define_call before to continue instead of the define_function the code continue during the process of the function. Am I Correct?


    For the TP Feedback, it will be better to have a timeline_event for everyTP who will be activate if the tp goes online.


    GregG approach for timeline is very easy to read, button_event follow by timeline_event.

    Nope, they work the same. Here's a little test program to illustrate.
    PROGRAM_NAME='test'
    
    DEFINE_DEVICE
    
    vdv_MyDevice    =    34001:01:1
    
    define_function fn_My_Function(){
        stack_var integer fun_loop;
        for(fun_loop=5;fun_loop;fun_loop--){
            send_string 0," 'fun_loop=',itoa(fun_loop)"
            }// for
        send_string 0, 'Fun_Step_2';
        send_string 0, 'Fun_Step_3';
        } // def_fun
    
    define_call 'My_Call'{
        stack_var integer call_loop;
        for(call_loop=5;call_loop;call_loop--){
            send_string 0," 'call_loop=',itoa(call_loop)";
            } // for
        send_string 0, 'Call_Step_2';
        send_string 0, 'Call_Step_3';
        } // def_call
    
    DEFINE_EVENT
    
    
    
    button_event[vdv_MyDevice,1]{
        push:{
            send_string 0, 'Before the Call';
            call 'My_Call'
            send_string 0, 'After the Call';
            }
        } //b_e
    
    
    button_event[vdv_MyDevice,2]{
        push:{
            send_string 0, 'Before the Function';
            fn_My_Function();
            send_string 0, 'After the Function';
            }
        } //b_e
    


    and the result
    The Call
    >(0000057955) Before the Call
    (0000057956) call_loop=5
    (0000057957) call_loop=4
    (0000057957) call_loop=3
    (0000057957) call_loop=2
    (0000057957) call_loop=1
    (0000057958) Call_Step_2
    (0000057958) Call_Step_3
    (0000057958) After the Call
    

    the function
    (0000072100) Before the Function
    (0000072101) fun_loop=5
    (0000072101) fun_loop=4
    (0000072101) fun_loop=3
    (0000072102) fun_loop=2
    (0000072102) fun_loop=1
    (0000072102) Fun_Step_2
    (0000072102) Fun_Step_3
    (0000072102) After the Function
    

    Here again, netlinx is not multi-thread.
  • What I do usually, I don't use define_program for any of the feedback code as much as I can, because the feedback state will change when a device (the controlled device) will send a message notifying that, which will be received in the code through data_event (if modules are not used) or through channel_event, level_event or data_event (if module is used)
    so what I do I update my buttons in these events, which will make the button state changes only when the device send a notification about that, which make very sense, why should I keep updating the touch panel every one second, personally I treat this as overload on the master and network
    I hope that this could help
  • GregG wrote: »
    Personally, I like to put multiple event blocks for the same feedback timeline around in the code, near where they apply, like:
    Button_Event[dvTP, BTN_DEVICE1_POWER]
    {
    Push: SendDevice1PowerOn()
    }
    Timeline_Event[TL_FEEDBACK]
    {
    [dvTP, BTN_DEVICE1_POWER] = nDevice1PowerOn
    }
    
    Button_Event[dvTP, BTN_DEVICE2_POWER]
    {
    Push: SendDevice2PowerOn()
    }
    Timeline_Event[TL_FEEDBACK]
    {
    [dvTP, BTN_DEVICE2_POWER] = nDevice2PowerOn
    }
    


    I love the organization of doing it that way. Is there any real-world drawback to having it spread out everywhere like that?
  • GregGGregG Posts: 251
    I can say that I have never noticed any performance impact from separating it compared to keeping it all in a single event. I'm not sure how the netlinx compiler deals with duplicates of the same event internally.

    However, I also don't do very much feedback in timelines of any sort, due to the performance effects of constantly updating feedback for things that have not changed.
  • mushmush Posts: 287
    GregG wrote: »
    I can say that I have never noticed any performance impact from separating it compared to keeping it all in a single event. I'm not sure how the netlinx compiler deals with duplicates of the same event internally.

    However, I also don't do very much feedback in timelines of any sort, due to the performance effects of constantly updating feedback for things that have not changed.
    This is my observation and practice also.
  • mushmush Posts: 287
    DEFINE_PROGRAM was actually deprecated in NetLinx but was retained to allow easy transition from Axcess. DEFINE_CALLS and some other things were also retained for the same reason.
Sign In or Register to comment.