B4J Question [IoT] timer in handler

derez

Expert
Licensed User
Longtime User
The code below is a handler working in OrangePi - turning traffic lights on and off.
The problem is that it works only in debug mode. When run in Release the handle sub is done but the timer doesn't tick !
When activating the jar in the OrangePi directly it doesn't work also.
Why ???:(
B4X:
'Handler class
Sub Class_Globals
    Public tmr As Timer
    Private state As Int = 0
End Sub

Public Sub Initialize
    tmr.Initialize("tmr",1000)
End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)

    Main.gp.DefinePin("PA11", True)
    Main.gp.DefinePin("PA12", True)
    Main.gp.DefinePin("PA13", True)

    Main.gp.WritePin("PA11",True)
    tmr.Enabled = True

End Sub

Sub tmr_tick
    state = (state + 1) mod 7
    Log(state)
    Select state
        Case 0                              ' red
            Main.gp.WritePin("PA11",True)
            Main.gp.WritePin("PA12",False)
            Main.gp.WritePin("PA13",False)
        Case 1
       
        Case 2
       
        Case 3
            Main.gp.WritePin("PA12",True)  ' + yellow
        '    Main.gp.WritePin("PA11",False)
        Case 4                             ' green
            Main.gp.WritePin("PA13",True)
            Main.gp.WritePin("PA12",False)
            Main.gp.WritePin("PA11",False)
        Case 5
                   
        Case 6
            Main.gp.WritePin("PA12",True)
            Main.gp.WritePin("PA13",False)
           
    End Select

End Sub
 
Last edited:

Roycefer

Well-Known Member
Licensed User
Longtime User
How did you add this Handler to the server object? If it's not single-threaded, the Handler will run in its own thread which probably doesn't have an event loop and therefore can't manage timer_tick events. Handler threads basically die after the Handle() method returns. You could call StartMessageLoop just before the end of the Handle() method, though I haven't tried this so I can't say whether it will work or not. You could also run this Handle in single-threaded mode (this is done in the srvr.AddHandler() method). There are a few more options available but they get more ugly and complex.
 
Upvote 0

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,

have a look at a possible solution here which uses multi-threading and a timer to run the experiment.
Note that I have not fully described the solution on the web page, but the source is well documented .. and it uses websockets.
 
Upvote 0

derez

Expert
Licensed User
Longtime User
Changing the addhandler to true did the trick !
Thanks Roycefer !
Thanks to rwblinn ,it is a handler not websocket so I used Roycefer's solution.
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You could call StartMessageLoop just before the end of the Handle() method, though I haven't tried this so I can't say whether it will work or not
I think that this is the best solution and it works. Just call StartMessageLoop to prevent the handler from finishing and then call StopMessageLoop in Timer_Tick event.
 
Upvote 0
Top