Home AMX User Forum NetLinx Studio

The problem of multi-tasking. NI-3000

Nudge the, please, on the right idea how to solve the problem.

The controller works with three pairs of devices:
  1. port I/O > Relay Receiving event IO port starts the cycle lamp is flashing through the relay.
  2. T.Panel > Rs232, Tuner. Panel receives feedback (A complex algorithm with symbol-wise analysis of the string) and controls tuner.
  3. Mio4 > Rs232, Projector Feedback and control
Individually all pairs working stably.

The problem appears when the need to handle events from all devices.
For example, the IO port gets a permanent event and starts the cycle. At the same moment, tuner sends a large amount of feedback and, accordingly, is required to disassemble the cycle by using the string character by character.
In such a situation, pressing buttons MIO reaction occurs with great delay.


Is it possible to have Netlink prioritize?
For example, to stop the implementation of all cycles, processing feedback, during the execution of Button_event.

Share your experience, how to solve these problems ?!
In advance thank you very much.


Comments

  • ericmedleyericmedley Posts: 4,177
    I'm not sure what the issue is from your post. The short answer is that there is no apparent reason for there to be an issue with a processor handling events if the program is well designed. the list of devices you mention is very short and usually well within the range of horse-power needed.

    Can you post the code you're having trouble with? That will help us help you.
  • ericmedleyericmedley Posts: 4,177
    also, Netlinx is a single-threaded environment. by default all events are "suspended" while any event happens. When a button event is triggered, Within an event, things like waits and timed things can happen but they are set aside by other handlers. At its most basic level - Netlinx is always doing one thing at a time.
  • shr00m-dewshr00m-dew Posts: 394
    Sounds like a while loop in there some where. If a ni3000 can handle a slightly modified Autonomics module running to 14 touchpanels, it can easily handle what you are trying to do if programmed correctly. (I know Eric will understand that reference).

    Kevin D.
  • I think the problem lies in the cycles, from which I can not refuse. (Or do not understand how to do it)

    I correctly understand that while working cycle (triggered in the presence of the event in the IO port), a cycle that handles feedback from the tuner does not start?

    For example, here are two of my piece of code:

    ******Port IO event handler*****
    MODULE_NAME='signaliz' (DEV Relay, DEV io, DEV Panel)
    (***********************************************************)
    (***********************************************************)
    (*  FILE_LAST_MODIFIED_ON: 04/04/2006  AT: 11:33:16        *)
    (***********************************************************)
    (* System Type : NetLinx                                   *)
    (***********************************************************)
    (* REV HISTORY:                                            *)
    (***********************************************************)
    (*
        $History: $
    *)    
    (***********************************************************)
    (*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_DEVICE
    
    
    (***********************************************************)
    (*               CONSTANT DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_CONSTANT
    sirena_countdown     = 1
    svet_countdown         = 2
    
    (***********************************************************)
    (*              DATA TYPE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_TYPE
    
    (***********************************************************)
    (*               VARIABLE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_VARIABLE
    
    non_volatile integer stateflag //TRUE когда сигнализация включена
    
    
    
    long countdowntimes[2]
    //long sirena_countdowntimes[2]
    
    (***********************************************************)
    (*               LATCHING DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_LATCHING
    
    (***********************************************************)
    (*       MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW           *)
    (***********************************************************)
    DEFINE_MUTUALLY_EXCLUSIVE
    
    (***********************************************************)
    (*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
    (***********************************************************)
    (* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
    (* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)
    
    (***********************************************************)
    (*                STARTUP CODE GOES BELOW                  *)
    (***********************************************************)
    DEFINE_START
    switch (stateflag) {
        case true: on[Panel,678]
        case false: off [Panel,678]
    }
    (***********************************************************)
    (*                THE EVENTS GO BELOW                      *)
    (***********************************************************)
    
    
    DEFINE_EVENT
    
    button_event [Panel, 678] {push: {
    
            if (!stateflag) {on[Panel,678]}
            if (stateflag) {off[Panel,678]}
    }}
    
    channel_event [Panel, 678] {
        
        on: {stateflag = true}
        off: {stateflag = false}
    }
    
    channel_event [io,1] {
                
            
            on: { on[Panel, 680] // j&#1086;&#1090;&#1087;&#1088;&#1072;&#1074;&#1080;&#1090;&#1100; &#1085;&#1072; &#1087;&#1072;&#1085;&#1077;&#1083;&#1100; "&#1074;&#1086;&#1088;&#1086;&#1090;&#1072; &#1086;&#1090;&#1082;&#1088;&#1099;&#1090;&#1099;"
                countdowntimes[1] = 1000
                countdowntimes[2] = 1000
                timeline_create(svet_countdown,countdowntimes,2,timeline_relative,timeline_repeat)
                timeline_create(sirena_countdown,countdowntimes,2,timeline_relative,timeline_repeat)}                    
                        
                            
            off: {    off [Panel,680] // &#1086;&#1090;&#1087;&#1088;&#1072;&#1074;&#1080;&#1090;&#1100; &#1085;&#1072; &#1087;&#1072;&#1085;&#1077;&#1083;&#1100; "&#1074;&#1086;&#1088;&#1086;&#1090;&#1072; &#1079;&#1072;&#1082;&#1088;&#1099;&#1090;&#1099;"
                timeline_kill(sirena_countdown)
                timeline_kill(svet_countdown)
                off[relay,1]
                off[relay,2]
                }
    
    }
    
    
    timeline_event[svet_countdown]
    {
    //send_string 0, "'seq- ',itoa (timeline.sequence)"
    //send_string 0, "'rep- ',itoa (timeline.repetition)"
    
       if (timeline.sequence = 1) {on[relay,1]}
       if (timeline.sequence = 2) {off[relay,1]}
    }
    
    timeline_event[sirena_countdown]
    {
            stack_var waittime
            stack_var disabletime
            waittime = 250 //&#1086;&#1078;&#1080;&#1076;&#1072;&#1090;&#1100; &#1087;&#1077;&#1088;&#1077;&#1076; &#1074;&#1082;&#1083;&#1102;&#1095;&#1077;&#1085;&#1080;&#1077;&#1084; &#1089;&#1077;&#1082;&#1091;&#1085;&#1076; x2 ... 30x2=60
            disabletime  = 250 // &#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1079;&#1074;&#1091;&#1095;&#1072;&#1090;&#1100; &#1089;&#1080;&#1088;&#1077;&#1085;&#1077; &#1076;&#1086; &#1086;&#1090;&#1082;&#1083;&#1102;&#1095;&#1077;&#1085;&#1080;&#1103; &#1089; &#1087;&#1086;&#1074;&#1090;&#1086;&#1088;&#1085;&#1099;&#1084; &#1074;&#1082;&#1083;&#1102;&#1095;&#1077;&#1085;&#1080;&#1077;&#1084;, &#1089;&#1077;&#1082; x2
            send_string 0, "'seq- ',itoa (timeline.sequence)"
            send_string 0, "'rep- ',itoa (timeline.repetition)"
    
        SWITCH (stateflag) {
    
        case true:    {   if (timeline.repetition >= waittime ) {
                    switch (timeline.sequence) {
                    case 1: on[relay,2]
                    case 2: off[relay,2]
                    }
               }
              
               if (timeline.repetition >= waittime+disabletime ) {off[relay,2]
                                TIMELINE_RELOAD(sirena_countdown,countdowntimes,2)}
                                
                }
                
        case false: { off[relay,2]}
    }
    }
    



    ******Tuner feedback handler*****
    DATA_EVENT [dvReciv] { string: {
        
            //&#1103;&#1095;&#1077;&#1081;&#1082;&#1072; 101 - 1 &#1089;&#1090;&#1088;&#1086;&#1082;&#1072;
            //&#1103;&#1095;&#1077;&#1081;&#1082;&#1072; 102 - 2 &#1089;&#1090;&#1088;&#1086;&#1082;&#1072;
            //&#1103;&#1095;&#1077;&#1081;&#1082;&#1072; 103 - 3 &#1089;&#1090;&#1088;&#1086;&#1082;&#1072;
            //&#1103;&#1095;&#1077;&#1081;&#1082;&#1072; 104 - 4 &#1089;&#1090;&#1088;&#1086;&#1082;&#1072;
        if ( volButtonState = 0) {
            stack_var integer i
            stack_var char f_back [100]
          
            stack_var char razbor_simvol [80]
            stack_var char alone_char
    //      
    //        spc_char = null_str
            
            f_back = data.text
            
            if (find_string(data.text,'power=on!',1)) {SEND_COMMAND Panel,"'@PPN-Loading'" //&#1086;&#1090;&#1082;&#1083;&#1102;&#1095;&#1077;&#1085;&#1080;&#1077; &#1086;&#1082;&#1085;&#1072; &#1087;&#1088;&#1086;&#1080;&#1089;&#1093;&#1086;&#1076;&#1080;&#1090; &#1074; TPDesing
                                //wait 50
    //                            SEND_COMMAND Panel,"'@PPF-Loading'"
                                }
          
           if (find_string(f_back,'display=',1)) {remove_string(f_back,'display=0',1)
                                dispalay_string = f_back}
            
           else {dispalay_string = "dispalay_string,f_back"}
            
            //dispalay_string = mid_string(dispalay_string,3,100)
          
           if (length_string(dispalay_string) >=80 ) {
          //razbor_simvol = string_fn (dispalay_string)
            
         // send_char (razbor_simvol)  
          
          string_send (dispalay_string)
          
            }
            send_string 0, "'display_string - ',dispalay_string"
          
    //        SEND_COMMAND Panel, "'^TXT-101,0,',mid_string(dispalay_string,3,20)"
    //        SEND_COMMAND Panel, "'^TXT-102,0,',mid_string(dispalay_string,23,20)"
    //        SEND_COMMAND Panel, "'^TXT-103,0,',mid_string(dispalay_string,43,20)"
    //        SEND_COMMAND Panel, "'^TXT-104,0,',mid_string(dispalay_string,63,20)"
    
           }
           else { send_string 0 , "'datavolstate = ',itoa(volButtonState)"}
           }
    }
    
    
    DEFINE_FUNCTION char[80] string_send (char fString [100]){
            
            stack_var integer i
            stack_var integer n
            stack_var integer strLength
            stack_var razb_stroka [80]
            stack_var char specsimvol [3]
            
            strLength = length_string(fString)
            
            n = 0
            
                for (i=4; i<=strLength; i++) {
                
                n = n + 1
                
                razb_stroka = mid_string(fString,i,1)
                
               //spc_char = "spc_char,fb_char"
          
    //            SEND_COMMAND Panel, "'^TXT-',itoa(i),',0,',fb_char"
    //
    //            if (find_string(SpChar,"$EE,$82,$80",1)) { }
                
                
            switch (razb_stroka) {
                
                    case $EE: specsimvol = mid_string(fString,i,3)
                    
                    select {
                
                    
                        active(specsimvol = "$EE,$82,$80"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,T'"
                                    i = i+2}
                                    
                        active(specsimvol = "$EE,$82,$82"): {SEND_COMMAND Panel,"'^BMF-',itoa (n),',0,%F34%CF255%CTWhite'" //play
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,0041'"
                                    i = i+2}
                                    
                        active(specsimvol =  "$EE,$82,$97"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //play
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,0041'"
                                    i = i+2}
                                    
                        active(specsimvol = "$EE,$82,$85"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,A'"
                                    i = i+2}
                                
                        active(specsimvol = "$EE,$82,$84"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,C'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$92"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,F'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$87"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,G'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$8E"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,I'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$89"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,L'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$93"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,M'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$8C"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,R'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$8F"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,S'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$8A"): {i = i+2}
                        
                        active(specsimvol = "$EE,$82,$8B"): {i = i+2}
                        
                        active(specsimvol = "$EE,$82,$81"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //pause
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,0043'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$83"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //stop
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,0042'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$94"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //play revers
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,004B'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$98"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //play revers
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,004B'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$99"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'" //&#1087;&#1091;&#1089;&#1090;&#1072;&#1103; &#1079;&#1072;&#1083;&#1080;&#1074;&#1082;&#1072;
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$9A"): {i = i+2}
                        
                        active(specsimvol = "$EE,$82,$88"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF00%CTBlack'" //&#1047;&#1072;&#1075;&#1086;&#1075;&#1091;&#1083;&#1080;&#1085;&#1072;
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,0077'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$95"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //&#1089;&#1090;&#1088;&#1077;&#1083;&#1082;&#1072; &#1074;&#1087;&#1088;&#1072;&#1074;&#1086;
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,004E'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$96"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F34%CF255%CTWhite'" //&#1089;&#1090;&#1088;&#1077;&#1083;&#1082;&#1072; &#1074;&#1083;&#1077;&#1074;&#1086;
                                    SEND_COMMAND Panel, "'^UNI-',itoa(n),',0,004F'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$90"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF255%CTWhite'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,*'"
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$91"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'" // &#1087;&#1091;&#1089;&#1090;&#1072;&#1103; &#1079;&#1072;&#1083;&#1080;&#1082;&#1072;
                                    i = i+2}
                        active(specsimvol = "$EE,$82,$8D"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,Z'"
                                    i = i+2}
                        active(specsimvol = "$EE,$80,$80"): {i = i+8 //&#1101;&#1090;&#1080; &#1090;&#1088;&#1080; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083;&#1072; &#1083;&#1080;&#1096;&#1100; &#1095;&#1072;&#1089;&#1090;&#1100; 9&#1090;&#1080; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083;&#1100;&#1085;&#1086;&#1081; &#1089;&#1090;&#1088;&#1086;&#1082;&#1080;
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,E'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n+1),',0,N'"
                                    SEND_COMMAND Panel, "'^TXT-',itoa(n+2),',0,D'"
                                    n=n+2}
                        }
                    
                    
            default:    SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF255%CTWhite'"
                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,',razb_stroka"
                    break
                }
                
        
                
                
                }
              
            
                
    }
    
    
    
    
    


    P.S. If someone has the desire and free time, I can send the full project!

  • ericmedleyericmedley Posts: 4,177
    shr00m-dew wrote: »
    Sounds like a while loop in there some where. If a ni3000 can handle a slightly modified Autonomics module running to 14 touchpanels, it can easily handle what you are trying to do if programmed correctly. (I know Eric will understand that reference).

    Kevin D.
    Ha! I may someday put that module out. But, you'd all just laugh at me. :)
  • ericmedleyericmedley Posts: 4,177
    I'm sure I'm having difficulties with the language barrier and might not be understanding the problem.

    But, In the code present, there is a portion that deals with button feedback on the panel in which the feeback triggers a channel event (the feedback on the panel) then in turn starts a timeline. the timeline has two "ticks", each at one second intervals (1000ms) Those "Ticks" turn the relay on and off respectively. Then the whole thing repeats. So, you should see a relay pulsing on and off each second.

    In addition, within the timeline there is essentially a pair of constants which are counters (each is set to 250 if I recall) The timeline is keeping track of how many times it has fired. So when the whole timeline has run 250 times, it shuts itself off by turning off the feedback channel, thus "killing" the timeline.

    Is the thing I describe above seem to be killing your master? (not allowing it to do other stuff?)
  • IO port module works like this:

    1. If the IO port included - Includes relay 1 operation (1sec - On, 1 sec - off) ... endlessly until enabled port IO.
    2. If a certain time has passed, and IO port still included - in addition to the work include Relay2.
    3. button_event [Panel, and 678] and channel_event [Panel, 678] - a button on the panel, which allows you to disable Relay2.

    I also think that the main problem in this module. But, to be confirmed more experienced programmers that this solution of the problem "kills" the Master.
  • GregGGregG Posts: 251
    I think the switch statement in your "string_send" function may have an issue with code blocking. You have:
    switch (razb_stroka) {
        case $EE: specsimvol = mid_string(fString,i,3)
        select {
            active(specsimvol = "$EE,$82,$80"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,T'"
                 i = i+2}
    

    But I don't think that will include anything more than "specsimvol = mid_string(fString,i,3)" as part of the first case. And it will keep executing this whole select active section as part of the default case. You may want to add another layer of braces like this:
    switch (razb_stroka) {
        case $EE: {
            specsimvol = mid_string(fString,i,3)
            select {
                active(specsimvol = "$EE,$82,$80"): {SEND_COMMAND Panel,"'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'"
                    SEND_COMMAND Panel, "'^TXT-',itoa(n),',0,T'"
                     i = i+2}
    
  • viningvining Posts: 4,368
    GregG wrote: »
    I think the switch statement in your "string_send" function may have an issue with code blocking. You have:
    switch (razb_stroka) {
        case $EE: specsimvol = mid_string(fString,i,3)
        select {
            active(specsimvol = &quot;$EE,$82,$80&quot;): {SEND_COMMAND Panel,&quot;'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'&quot;
                SEND_COMMAND Panel, &quot;'^TXT-',itoa(n),',0,T'&quot;
                 i = i+2}
    

    But I don't think that will include anything more than "specsimvol = mid_string(fString,i,3)" as part of the first case. And it will keep executing this whole select active section as part of the default case. You may want to add another layer of braces like this:
    switch (razb_stroka) {
        case $EE: {
            specsimvol = mid_string(fString,i,3)
            select {
                active(specsimvol = &quot;$EE,$82,$80&quot;): {SEND_COMMAND Panel,&quot;'^BMF-',itoa(n),',0,%F19%CF00%CTBlack'&quot;
                    SEND_COMMAND Panel, &quot;'^TXT-',itoa(n),',0,T'&quot;
                     i = i+2}
    

    Yeah, I believe a case with out braces after will only execute the 1st line of code after where as all lines will exectute if enclosed in braces. Similar to how code after a Wait works. You would think the compiler would see that as a malformed switch case and not compile though.
  • May be so. I will correct this error.
    However, this part of the code itself operates.
    The problem comes when you need to handle both events IO port and feedback from tuner.

    Or something I do not to understand?
  • DraugarDraugar Posts: 27
    Could the SEND_COMMAND to the panel times (strLength/3) have anything to do with this? I've seen som issues when the network have a moment of interruptions, and the controller will hold for a brief moment before continuing pushing. I use to update the panel all at once instead of having if this then update, if this then update.
  • In fact, tests have shown that the problem in IO port event handling module (when the relay switch ON).
    This triggers an infinite loop and the system can not respond quickly to other commands.


    I think we should try to put the code handling events IO port in the "buffer" ... and return to its implementation only if the controller has a free system time.

    But, I do not know how to do it correctly. I will try....

    I would appreciate any advice or example code.

    If I succeed, I'll show how I solved the problem
  • ericmedleyericmedley Posts: 4,177
    In fact, tests have shown that the problem in IO port event handling module (when the relay switch ON).
    This triggers an infinite loop and the system can not respond quickly to other commands.


    I think we should try to put the code handling events IO port in the "buffer" ... and return to its implementation only if the controller has a free system time.

    But, I do not know how to do it correctly. I will try....

    I would appreciate any advice or example code.

    If I succeed, I'll show how I solved the problem


    Can you post the code in which the infinite loop occurs? Then perhaps we can help.
  • I have shown this module code in the above statement.
    I will repeat it (remove all unnecessary and translated into English commentary)
    MODULE_NAME='signaliz' (DEV Relay, DEV io, DEV Panel)
    
    DEFINE_CONSTANT
    Siren_countdown     = 1
    flash_countdown         = 2
    
    
    DEFINE_VARIABLE
    
    non_volatile integer stateflag //TRUE then Signaling is ON
    
    long countdowntimes[2]
    
    
    (***********************************************************)
    (*                STARTUP CODE GOES BELOW                  *)
    (***********************************************************)
    DEFINE_START
    
    //Check the status of the buttons on the touch panel
    
    switch (stateflag) {
        case true: on[Panel,678]
        case false: off [Panel,678]
    }
    (***********************************************************)
    (*                THE EVENTS GO BELOW                      *)
    (***********************************************************)
    
    
    DEFINE_EVENT
    (**************Using the button on the touch panel****************)
    
    button_event [Panel, 678] {push: {
    
            if (!stateflag) {on[Panel,678]}
            if (stateflag) {off[Panel,678]}
    }}
    
    channel_event [Panel, 678] {
        
        on: {stateflag = true}
        off: {stateflag = false}
    }
    
    (************End of using the button on the touch panel*********)
    
    
    //Check the state of the port IO1
    
    channel_event [io,1] {
                
            // If channel is on - Create a timer that will trigger the relay.
            on: { on[Panel, 680] // Send to panel "Door open"
                countdowntimes[1] = 1000
                countdowntimes[2] = 1000
                timeline_create(flash_countdown,countdowntimes,2,timeline_relative,timeline_repeat)
                timeline_create(siren_countdown,countdowntimes,2,timeline_relative,timeline_repeat)}                    
                        
                            
            off: {    off [Panel,680] // Send to panel "Door close"
                timeline_kill(siren_countdown)
                timeline_kill(flash_countdown)
                off[relay,1]
                off[relay,2]
                }
    
    }
    
    
    
    timeline_event[flash_countdown]
    {
    
    //relay1 - 1Sec ON, 1 Sec OFF
       if (timeline.sequence = 1) {on[relay,1]}
       if (timeline.sequence = 2) {off[relay,1]}
    }
    
    timeline_event[siren_countdown]
    {
            stack_var waittime
            stack_var disabletime
            waittime = 250 //Waiting time before switching Relay2
            disabletime  = 250 // Working time Relay2, before disconnecting and reconnecting
    
    
       //If button on the touch Panel is on - start using Relay2
     SWITCH (stateflag) {
    
        case true:    {   if (timeline.repetition >= waittime ) {
                    switch (timeline.sequence) {
                    case 1: on[relay,2]
                    case 2: off[relay,2]
                    }
               }
              
               if (timeline.repetition >= waittime+disabletime ) {off[relay,2]
                                TIMELINE_RELOAD(siren_countdown,countdowntimes,2)}
                                
                }
                
        case false: { off[relay,2]}
    }
    }
    
  • viningvining Posts: 4,368
    Eric requested additional code because there were no for or while loops or recursive functions that would cause an infinite loop in the initial posted code so if there is an inifinte loop it has be caused in some other code block not shown. Send_strings to panels or diagnostics can also bog down the processor if done toofast like in define program at every pass but it looks like your code just sends via the 1000ms repeating TL which isn't terrible.
  • GregGGregG Posts: 251
    I never use the buttons on a touch panel directly in logic statements, they are not reliable sources of information. (They all go off if the panel loses power or connection).

    I also don't see the point of doing that TIMELINE_RELOAD() when you didn't change the timing at all. Maybe you meant to use TIMELINE_SET, to reset the timeline.repetition back to the begining?

    Here's an example using a feedback timeline, and also combining your 2 identical timelines.
    MODULE_NAME='signaliz' (DEV Relay, DEV io, DEV Panel)
    
    DEFINE_CONSTANT
    one_second_countdown = 1
    feedback_timeline    = 2
    
    DEFINE_VARIABLE
    non_volatile integer stateflag //TRUE then Signaling is ON
    long feedback_time[1]
    long countdowntimes[2]
    
    DEFINE_START
    feedback_time[1] = 300
    countdowntimes[1] = 1000
    countdowntimes[2] = 1000
    // Start a permanently repeating timeline for feedback
    Timeline_Create(feedback_timeline,feedback_time,1,timeline_relative,timeline_repeat)
    
    DEFINE_EVENT
    (**************Using the button on the touch panel****************)
    button_event [Panel, 678] { push: { stateflag = !stateflag }}
    
    timeline_event[feedback_timeline]
    {
      [Panel, 678] = stateflag
    }
    (************End of using the button on the touch panel*********)
    
    //Check the state of the port IO1
    channel_event [io,1] {
            // If channel is on - Create a timer that will trigger the relay.
            on: {  // Send to panel "Door open"
                timeline_create(one_second_countdown,countdowntimes,2,timeline_relative,timeline_repeat)
                    }                    
            off: { // Send to panel "Door close"
                timeline_kill(one_second_countdown)
                off[relay,1]
                off[relay,2]
                }
    
    }
    
    timeline_event[feedback_timeline]
    {
      [Panel, 680] = [io,1]
    }
    
    timeline_event[one_second_countdown]
    {
    stack_var waittime
    stack_var disabletime
        waittime = 250 //Waiting time before switching Relay2
        disabletime  = 250 // Working time Relay2, before disconnecting and reconnecting
    
        //relay1 - 1Sec ON, 1 Sec OFF
       if (timeline.sequence = 1) {on[relay,1]}
       if (timeline.sequence = 2) {off[relay,1]}
    
       //If button on the touch Panel is on - start using Relay2
       if (stateflag) {
          if (timeline.repetition >= waittime ) {
             switch (timeline.sequence) {
                case 1: on[relay,2]
                case 2: off[relay,2]
             }
            }
          if (timeline.repetition >= waittime+disabletime ) {off[relay,2]
             TIMELINE_SET(one_second_countdown,0)}
        }
        Else { off[relay,2]}
    }
    
  • ericmedleyericmedley Posts: 4,177
    vining wrote: »
    Eric requested additional code because there were no for or while loops or recursive functions that would cause an infinite loop in the initial posted code so if there is an inifinte loop it has be caused in some other code block not shown. Send_strings to panels or diagnostics can also bog down the processor if done toofast like in define program at every pass but it looks like your code just sends via the 1000ms repeating TL which isn't terrible.


    Troubleshooting: so rare nowadays it's a fricken super power. :)
  • viningvining Posts: 4,368
    ericmedley wrote: »


    Troubleshooting: so rare nowadays it's a fricken super power. :)

    Yeah I've been toubleshooting my entire life, actually no, I've been getting in trouble my entire life, that sounds more accurate. ;)
Sign In or Register to comment.