Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
Calling ByRef in Task's

 
Post new topic   Reply to topic    Forum Index -> ZBasic Language
Author Message
hakha4



Joined: 02 Jun 2009
Posts: 30
Location: Moholm Sweden

Posted: 22 September 2009, 22:11 PM    Post subject: Calling ByRef in Task's Reply with quote

Hi!
Trying to control relay's with Netmedia LCD+. ZBasic doc says it's not recommended to pass value to task's ByRef. Code below works if I pass a value ByREf in an ordinary Sub but not in a task. Tried to preserve the RelayStatus value in a tmpRelayStatus variable but still not working. Could anyone give me a hint how to get Byref to work in a task. Tried to solve the problem by reading the doc's/forum but I'm stucked. Any help would be appreciated
Regards Hucke

[/code]
test.bas
'***************************''''
'
'
'
'
'
Sub Main

RelaysALL_OFF' set relay's off and initialize 'tmpRelayStatus' to &H00

Do

'#### DON't WORK
CallTask SwitchRelay(tmpRelayStatus,3,1),RelayStack
CallTask SwitchRelay(tmpRelayStatus,4,1),RelayStack


'#### WORKING
call SwitchRelay(tmpRelayStatus,2,1)
call SwitchRelay(tmpRelayStatus,1,1)

Loop

End Sub


' Relay_1.Bas
'
' Public Sub Relays_OFF()- turn OFF ALL relays
' Sub SwitchRelay(ByRef RelayStatus as Byte, ByVal RelayNumber as Byte)
'
'Call RelaysALL_OFF() in Sub Main to set all relay's off as default and to set 'tmpRelayStatus'

Public RelayMsg(0 to 7) As String

Public RelayStack(1 To 73) As Byte
Public tmpRelayStatus As Byte 'to hold value of RelayStatus
'********************************************************************************************

Sub SwitchRelay(Byref RelayStat as Byte,ByVal RelayNumber as Byte,ByVal tmpStatus As Byte)
' Turns ON/OFF specified relay 1-8
If RelayNumber > 8 Then
Exit Sub
End If

Select Case tmpStatus
Case 1'On
Call PutBit(RelayStat, RelayNumber-1, 1)
Case 0'Off
Call PutBit(RelayStat, RelayNumber-1, 0)
End Select

Call PutByte_3(&H12)
Call PutByte_3(RelayStat XOR &Hff)
Relay_Msg(RelayStat)
Call Delay(0.0)
End Sub


Public Sub RelaysALL_OFF()
Dim RelayStatus As Byte

RelayStatus = &H00
Call PutByte_3(&H12) ' relay command
Call PutB_3(RelayStatus XOR &Hff) ' turn OFF all relay's
Call Relay_Msg(RelayStatus)

tmpRelayStatus = RelayStatus
End Sub

Public Sub Relay_Msg(ByRef RelayStatus As Byte)
Dim X As Integer
Dim Y As Integer
Dim TmpBitStatus As Byte
Dim tmpMsg As String
Dim tmpPos As Byte

RelayMsg(0) = "Pump = "
RelayMsg(1) = "Chlor = "
RelayMsg(2) = "VP = "
RelayMsg(3) = "Sun = "
RelayMsg(4) = "Light1 ="
RelayMsg(5) = "Light2 ="
RelayMsg(6) = "Light3 ="
RelayMsg(7) = "Light4 ="

tmpPos = 0

For X = 0 To 7
TmpBitStatus = GetBit(RelayStatus, X)

tmpMsg = RelayMsg(X) & Cstr(TmpBitStatus)

If tmpPos > 79 Then
tmpPos = 0
End If

LCDSetCursorPosition(tmpPos)
PutStr_3 tmpMsg
tmpPos = tmpPos + 10

Next
End Sub
Back to top
GTBecker



Joined: 18 Jan 2006
Posts: 457
Location: Cape Coral

Posted: 23 September 2009, 0:17 AM    Post subject: Reply with quote

This worthless, unrelated post has been deleted.

Last edited by GTBecker on 23 September 2009, 2:18 AM; edited 1 time in total
Back to top
mikep



Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX

Posted: 23 September 2009, 1:06 AM    Post subject: Reply with quote

I think Tom misunderstood your question. Here is a working test program that passes parameters by reference to a task.
Code:
Dim taskStack(1 to 100) as Byte

Public Sub Main()
   Dim tmpRelayStatus as Byte
   tmpRelayStatus = &H00
   Debug.Print "Outside task "; tmpRelayStatus
   CallTask RelayTask(tmpRelayStatus), taskStack
   Call Sleep(1.0)
   Debug.Print "Outside task "; tmpRelayStatus
   Do ' loop forever
   Loop
End Sub

Public Sub RelayTask(ByRef relayStatus as Byte)
   Debug.Print "Inside task "; relayStatus
   relayStatus = &H55
   Debug.Print "Inside task "; relayStatus
   Do ' loop forever
   Loop
End Sub
The compiler issues the warning as documented in CallTask about passing parameters by reference (ByRef) and the code produces the expected output of
Code:
Outside task 0
Inside task 0
Inside task 85
Outside task 85

I am not sure exactly what the problem is that you are having. Can you describe a little more what is failing and where? Reading the code it looks like you could simply use a module level variable. Here is the same example as above rewritten with a module level variable.
Code:
Dim relayStatus as Byte
Dim taskStack(1 to 100) as Byte

Public Sub Main()   
   relayStatus = &H00
   Debug.Print "Outside task "; relayStatus
   CallTask RelayTask(), taskStack
   Call Sleep(1.0)
   Debug.Print "Outside task "; relayStatus
   Do ' loop forever
   Loop
End Sub

Public Sub RelayTask()
   Debug.Print "Inside task "; relayStatus
   relayStatus = &H55
   Debug.Print "Inside task "; relayStatus
   Do ' loop forever
   Loop
End Sub
Back to top
GTBecker



Joined: 18 Jan 2006
Posts: 457
Location: Cape Coral

Posted: 23 September 2009, 2:14 AM    Post subject: Reply with quote

> ... Tom misunderstood your question...

Quite right. I read LCD-X; sorry.
Back to top
hakha4



Joined: 02 Jun 2009
Posts: 30
Location: Moholm Sweden

Posted: 23 September 2009, 4:29 AM    Post subject: Reply with quote

Thank's Mike for reply. I've tried Your approach earlier but missed to put 'Sleep' between calls!. Sleep (1.0) solved the problem.
Regards Hucke
Back to top
hakha4



Joined: 02 Jun 2009
Posts: 30
Location: Moholm Sweden

Posted: 23 September 2009, 16:15 PM    Post subject: Reply with quote

By the way. Are there any thumb roles for when to use delay/pause in Task's .I thougt one of the advantages with task's was that the procedure finish before next call is launched.
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 666

Posted: 23 September 2009, 17:20 PM    Post subject: Reply with quote

hakha4 wrote:
By the way. Are there any thumb roles for when to use delay/pause in Task's .I thougt one of the advantages with task's was that the procedure finish before next call is launched.


For me, the only rule of thumb is the more general case very issue that the compiler warned about when using ByRef variable passing. That issue is sharing of resources between processes, RAM being one of them.

You have to be very careful about how you share all this stuff because another process may become active when the other proces was in the middle of doing something and got suspended by a task switch. If you assume that a certain process runs to completion without interruption (i.e. it is "atomic"), then sometimes you will have some very odd and hard-to-figure-out problems.

By passing values "ByVal", the task has its own variable, and is not dependent on other tasks behaving in any specific manner. Go ahead and pass by reference, but be careful!

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 23 September 2009, 20:17 PM    Post subject: Reply with quote

hakha4 wrote:
I thougt one of the advantages with task's was that the procedure finish before next call is launched.
On the contrary, unless you take special steps to prevent it, a procedure may be "paused" to allow another task to run at almost any time. That's why you need to think carefully about how data is shared between tasks when you code your application.

hakha4 wrote:
ZBasic doc says it's not recommended to pass value to task's ByRef.
The reason for the recommendation (and the warning) is that, if not done correctly, the task can end up using a pointer to a variable that no longer exists. This can happen if a task in invoked using a reference to a local variable of a procedure when that procedure terminates (and thus causes the local variable to vanish) prior to the task using the reference.

If you pass a module-level variable to the task, it will exist as long as the program is running so the variable's lifetime is not an issue. You can use the #pragma warning directive to suppress the warning if you know for certain that what you're doing is OK. In retrospect, there may be a way to modify the compiler so that it doesn't issue the warning if the variable passed by reference is defined at the module level.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZBasic Language Time synchro. with the server - Timezone/DST with your computer
Page 1 of 1

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group