Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Sub Main()
Const FlashTime as Single = 1.0
Const RedLED as Byte = C.1
Do
Call PutPin(RedLED, zxOutputLow)
Call Sleep(FlashTime)
Call PutPin(RedLED, zxOutputHigh)
Call Sleep(FlashTime)
Loop
End Sub
If we add a concurrent task to monitor some user input...
Public ButtonActive as Boolean
Sub ButtonTask()
Const ButtonPin as Byte = C.2
Do
If NOT(CBool(GetPin(ButtonPin))) Then 'inverted logic
ButtonActive = True
Call Sleep(0.1) 'Sleep to debounce
End If
Loop
End Sub
...how can I get Sub Main to interrupt the sleep call to do something else if the user presses the button (i.e. to blink a different LED) if the task is suspended via the call to Sleep?
Sub Main()
Const FlashTime as Single = 1.0 * 512.0
Const RedLED as Byte = C.1
Dim SavedTime as Single
Do
Call PutPin(RedLED, zxOutputLow) 'Turn on the LED
SavedTime = Timer() 'Store the current Time
Do while NOT(ButtonActive) OR ((Timer() + FlashTime) < SavedTime)
Call Sleep(0) 'Do Nothing
Loop
Call PutPin(RedLED, zxOutputHigh) 'Turn off the LED
SavedTime = Timer() 'and store the current time again
Do while NOT(ButtonActive) OR ((Timer() + FlashTime) < SavedTime)
Call Sleep(0) 'ZZzzz
Loop
Loop
End Sub
Then there is just the issue of the RTC rolling over to deal with. Is this the correct method to implement this, or is there another?
Don_Kirby wrote:[H]ow can I get Sub Main to interrupt the sleep call to do something else if the user presses the button (i.e. to blink a different LED) if the task is suspended via the call to Sleep?
You can wake up a task that is sleeping (or waiting for an event, etc.) by using ResumeTask(). Depending on the delays that you're using in Main() that may lead to a noticeable interruption of the rhythm.
Depending you what else you have going on, it might be a better design to move the blinking down to another task and have Main() be a coordinator that takes input from some tasks and provides data used by other tasks to do their jobs.
dkinzer wrote:[...]it might be a better design to move the blinking down to another task and have Main() be a coordinator that takes input from some tasks and provides data used by other tasks to do their jobs.
That is in fact what I am doing, I was just trying to boil it down to the smallest possible application for the sake of explaining the issue.
I currently have it implemented using a method similar to my previous post, which works correctly.
The next step would be to have a delay routine that can take an expression as a parameter, as well as the delay time whereas the routine would delay until either the time expired, or the expression evaluated false.