Problem setting gadgets with delay [SOLVED]

Just starting out? Need help? Post your questions and find answers here.
bmcs
User
User
Posts: 21
Joined: Sat Apr 01, 2017 12:47 pm

Problem setting gadgets with delay [SOLVED]

Post by bmcs »

Hi Folks,
I am writing a small, relatively simple, program to interface with an external control board via a DLL. The DLL functions are working perfectly and I have no issue there. My problem is with setting the gadget sates in the GUI in one case. Rather than generating a load of "red herrings", by adding pointless DLL code calls to this post, I have created a working example extracted from the real code. The GUI looks ridiculous, because I have not repositioned the gadgets within the window used for the real program.
The GUI has and number of buttons to trigger functions, in 2 cases one button turns on 8 digital outputs and another turns them off. In the GUI I have used 8 checkboxes that are set and cleared accordingly. There is no problem here, everything works as expected. The issue is that I have another "Test" button, which is meant to call same procedures as the other 2 buttons, separated by a short delay eg. Delay(500) that I cannot get to work. The end objective is add more actions than this simple digital on/of feature to this "Test" button loop. Any thoughts?

Code: Select all


Enumeration
  #WINDOW_MAIN
  #CHECKBOX_DIG_OUT_1
  #CHECKBOX_DIG_OUT_2
  #CHECKBOX_DIG_OUT_3
  #CHECKBOX_DIG_OUT_4
  #CHECKBOX_DIG_OUT_5
  #CHECKBOX_DIG_OUT_6
  #CHECKBOX_DIG_OUT_7
  #CHECKBOX_DIG_OUT_8
  #BUTTON_ALL_DIG_ON
  #BUTTON_ALL_DIG_OFF
  #BUTTON_OUT_TEST
EndEnumeration

Procedure Open_Window_Main()
  If OpenWindow(#WINDOW_MAIN, 0, 0, 640, 400, "Interface Demo",  #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
    CheckBoxGadget(#CHECKBOX_DIG_OUT_1, 370, 100, 30, 20, "1")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_2, 400, 100, 30, 20, "2")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_3, 430, 100, 30, 20, "3")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_4, 460, 100, 30, 20, "4")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_5, 490, 100, 30, 20, "5")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_6, 520, 100, 30, 20, "6")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_7, 550, 100, 30, 20, "7")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_8, 580, 100, 30, 20, "8")
    ButtonGadget(#BUTTON_ALL_DIG_ON, 10, 150, 120, 30, "Set All Digital")
    ButtonGadget(#BUTTON_ALL_DIG_OFF, 10, 190, 120, 30, "Clear All Digital")
    ButtonGadget(#BUTTON_OUT_TEST, 10, 320, 120, 30, "Output Test")
  EndIf
EndProcedure

Procedure DigAllOn()
  For i = #CHECKBOX_DIG_OUT_1 To #CHECKBOX_DIG_OUT_8
    SetGadgetState(i, #PB_Checkbox_Checked)
  Next i
  ; Here the DLL function is called
EndProcedure

Procedure DigAllOff()
  For i = #CHECKBOX_DIG_OUT_1 To #CHECKBOX_DIG_OUT_8
    SetGadgetState(i, #PB_Checkbox_Unchecked)
  Next i
  ; Here the DLL function is called
EndProcedure

; In the real program all the previous code is in a pbi file
; The following code is in the pb file
; Obviously the pbi file is included at this point

Open_Window_Main()

Repeat
  EventID.l = WaitWindowEvent(100) ; 100Ms is adaquate for this program
  If EventID = #PB_Event_Gadget
    Select EventGadget()
      Case #BUTTON_ALL_DIG_ON
        DigAllOn()
      Case #BUTTON_ALL_DIG_OFF
        DigAllOff()
      Case #BUTTON_OUT_TEST
        DigAllOn()  ; This works WITHOUT the delay, but fails with it.
        ; Remove the following 3 lines and the above procedure is called
        Delay(500)  ; PROBLEM! Nothing happens in this Case statement
        ; Also tried creating a custom delay With ElapsedMilliseconds()
        DigAllOff() ; This simply never happens.
    EndSelect
  ElseIf EventID = #PB_Event_Timer
    ; Here the board inputs are read and processed
    ; Without the timer the real program falls apart in many ways
  EndIf
  
Until EventID = #PB_Event_CloseWindow

Last edited by bmcs on Mon Jul 10, 2017 9:36 am, edited 1 time in total.
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Problem setting gadgets with delay

Post by skywalk »

Your code dominated the event loop.

Code: Select all

Enumeration
  #WINDOW_MAIN
  #CHECKBOX_DIG_OUT_1
  #CHECKBOX_DIG_OUT_2
  #CHECKBOX_DIG_OUT_3
  #CHECKBOX_DIG_OUT_4
  #CHECKBOX_DIG_OUT_5
  #CHECKBOX_DIG_OUT_6
  #CHECKBOX_DIG_OUT_7
  #CHECKBOX_DIG_OUT_8
  #BUTTON_ALL_DIG_ON
  #BUTTON_ALL_DIG_OFF
  #BUTTON_OUT_TEST
EndEnumeration
Procedure Open_Window_Main()
  If OpenWindow(#WINDOW_MAIN, 0, 0, 640, 400, "Interface Demo",  #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
    CheckBoxGadget(#CHECKBOX_DIG_OUT_1, 370, 100, 30, 20, "1")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_2, 400, 100, 30, 20, "2")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_3, 430, 100, 30, 20, "3")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_4, 460, 100, 30, 20, "4")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_5, 490, 100, 30, 20, "5")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_6, 520, 100, 30, 20, "6")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_7, 550, 100, 30, 20, "7")
    CheckBoxGadget(#CHECKBOX_DIG_OUT_8, 580, 100, 30, 20, "8")
    ButtonGadget(#BUTTON_ALL_DIG_ON, 10, 150, 120, 30, "Set All Digital")
    ButtonGadget(#BUTTON_ALL_DIG_OFF, 10, 190, 120, 30, "Clear All Digital")
    ButtonGadget(#BUTTON_OUT_TEST, 10, 320, 120, 30, "Output Test")
  EndIf
EndProcedure
Procedure DigAllOn()
  For i = #CHECKBOX_DIG_OUT_1 To #CHECKBOX_DIG_OUT_8
    SetGadgetState(i, #PB_Checkbox_Checked)
  Next i
  ; Here the DLL function is called
EndProcedure
Procedure DigAllOff()
  For i = #CHECKBOX_DIG_OUT_1 To #CHECKBOX_DIG_OUT_8
    SetGadgetState(i, #PB_Checkbox_Unchecked)
  Next i
  ; Here the DLL function is called
EndProcedure
Procedure DigToggle(tDelay.i)
  DigAllOff()
  Delay(tDelay)
  DigAllOn()
EndProcedure
Open_Window_Main()
Repeat
  EventID.l = WaitWindowEvent(100) ; 100Ms is adaquate for this program
  If EventID = #PB_Event_Gadget
    Select EventGadget()
    Case #BUTTON_ALL_DIG_ON
      DigAllOn()
    Case #BUTTON_ALL_DIG_OFF
      DigAllOff()
    Case #BUTTON_OUT_TEST
      CreateThread(@DigToggle(),1000)
    EndSelect
  ElseIf EventID = #PB_Event_Timer
    ; Here the board inputs are read and processed
    ; Without the timer the real program falls apart in many ways
  EndIf
Until EventID = #PB_Event_CloseWindow
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Problem setting gadgets with delay

Post by RASHAD »

Hi
skywalk post the first method
Next the second one

Code: Select all

Open_Window_Main()

AddWindowTimer(0,123,10)

Repeat
  Select WaitWindowEvent() ; 100Ms is adaquate for this program
  Case #PB_Event_CloseWindow
      Quit = 1
      
  Case #PB_Event_Timer
      If trigger = 1
         DigAllOn()         
         x + 10
      EndIf
      If x = 500
        trigger = 0
        x = 0
        DigAllOff()
      EndIf
      
  Case #PB_Event_Gadget
    Select EventGadget()
      Case #BUTTON_ALL_DIG_ON
        DigAllOn()
      Case #BUTTON_ALL_DIG_OFF
        DigAllOff()
      Case #BUTTON_OUT_TEST
        trigger = 1

    EndSelect
  EndSelect
 
Until Quit = 1
Egypt my love
User avatar
gurj
Enthusiast
Enthusiast
Posts: 693
Joined: Thu Jan 22, 2009 3:48 am
Location: china
Contact:

Re: Problem setting gadgets with delay

Post by gurj »

ok:

Code: Select all

       WindowEvent()
       SetGadgetState(i, #PB_Checkbox_Checked)
      Next i
      WindowEvent()
my pb for chinese:
http://ataorj.ys168.com
bmcs
User
User
Posts: 21
Joined: Sat Apr 01, 2017 12:47 pm

Re: Problem setting gadgets with delay

Post by bmcs »

skywalk wrote:Your code dominated the event loop.
Thanks skywalk, your help is much appreciated. Like so may things in my coding (in)ability, I overlooked the need for threading. I can now see the need for threading in other parts of this little program.
bmcs
User
User
Posts: 21
Joined: Sat Apr 01, 2017 12:47 pm

Re: Problem setting gadgets with delay

Post by bmcs »

RASHAD wrote:Hi
skywalk post the first method
Next the second one
Thanks for your always helpful input RASHAD, but my example was misleading in that it omitted the AddWindowTimer, which exists in the real program.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Problem setting gadgets with delay

Post by RASHAD »

You can add more than one timer for examp.

Code: Select all

AddWindowTimer(0,123,10)
AddWindowTimer(0,150,10)

Repeat
  Select WaitWindowEvent() ; 100Ms is adaquate for this program
  Case #PB_Event_CloseWindow
      Quit = 1
     
  Case #PB_Event_Timer
      If trigger = 1 And EventTimer() = 123
         DigAllOn()         
         x + 10
      EndIf
      If EventTimer() = 123 And x = 500
        trigger = 0
        x = 0
        DigAllOff()
      EndIf
      If EventTimer() = 150
        Debug "OK"
      EndIf
Egypt my love
bmcs
User
User
Posts: 21
Joined: Sat Apr 01, 2017 12:47 pm

Re: Problem setting gadgets with delay

Post by bmcs »

Yet again I thank you RASHAD. I had already started down the wrong road with timers in this program and you have pointed me in the right direction.
Post Reply