Sleeping tasks without Sleep()

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.
Post Reply
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Sleeping tasks without Sleep()

Post by Don_Kirby »

I came across a situation today in which I am unsure how to implement.

Consider the basic flashing LED routine:

Code: Select all

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...

Code: Select all

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?

Perhaps like this?

Code: Select all

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&#40;ButtonActive&#41; OR &#40;&#40;Timer&#40;&#41; + FlashTime&#41; < SavedTime&#41;
			Call Sleep&#40;0&#41; 'Do Nothing
		Loop
		
		Call PutPin&#40;RedLED, zxOutputHigh&#41; 'Turn off the LED
		SavedTime = Timer&#40;&#41; 'and store the current time again
		
		Do while NOT&#40;ButtonActive&#41; OR &#40;&#40;Timer&#40;&#41; + FlashTime&#41; < SavedTime&#41;
			Call Sleep&#40;0&#41; '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
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Sleeping tasks without Sleep()

Post by dkinzer »

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.
- Don Kinzer
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Re: Sleeping tasks without Sleep()

Post by Don_Kirby »

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.

-Don
Post Reply