Page 1 of 1

Sleeping tasks without Sleep()

Posted: 20 January 2008, 16:47 PM
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

Re: Sleeping tasks without Sleep()

Posted: 20 January 2008, 17:14 PM
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.

Re: Sleeping tasks without Sleep()

Posted: 20 January 2008, 17:33 PM
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