View Full Version : Passing Variables by reference more than 1 level deep?
DavidM
01-19-2008, 08:51 PM
Hi,
I have a LONG variable defined in my VAR Block.
I have an OBJECT defined in my OBJ Block.
I can pass a reference to that variable from my main method to another method that is in another OBJECT ( another .spin file)
by using the @ symbol before the variable name.
When that method is called I can work with the referenced variable by using..
LONG [ MyReferencedVariable ] : = 1 ( to write the variable)
MyVariable := LONG [ MyReferencedVariable ] ( to read the variable)
so far this works.. http://forums.parallax.com/images/smilies/smile.gif
But, then I start a new cog in the method which was called and it runs correctly for a short period, but when it finishes I want it to update my referenced variable, of which I can't seem to get it to work!
What I mean is, re-referencing the variable again ( more than 1 level) does not seem to work for me.
Q1) How do I get this COG to modify the referenced variable?
I hope I explained it??
Thanks
Dave M
Phil Pilgrim (PhiPi)
01-20-2008, 12:05 AM
Some actual code would help explain it more. Can you post your program, please?
-Phil
deSilva
01-20-2008, 12:54 AM
You most likely need no "second indirection".. Just use the reference as such. A pointer is a pointer is a pointer...
DavidM
01-20-2008, 06:35 AM
Hi,
Here is my code..
there are two spin files
'' -------------START OF MAIN CODE----------------
CON
_CLKMODE =XTAL1 +PLL16X
_XINFREQ =5_000_000
VAR
BuzzerPin = 27
OBJ
Buzzer : "Buzzer.Spin"
VAR
LONG vBuzzerState
PUB MAIN
Buzzer.Beep ( BuzzerPin, 1000, 1000, 4 , @vBuzzerState)
WAITCNT(1_000_000+CNT)
Buzzer.Beep ( BuzzerPin, 1000, 1000, 3 , @vBuzzerState)
----------END OF MAIN CODE.SPIN ------------------
----------START OF BUZZER.SPIN --------------------
'' Controls a Buzzer via a transistor.
'' Uses a COG so as not to halt system
VAR
LONG BuzzerStack[20]
OBJ
Timing : "Timing.spin"
PUB Beep ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ,vBuzzerState)
IF LONG[vBuzzerState] == 0
LONG[vBuzzerState] := COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ) , @BuzzerStack )
PUB BeepRun ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps )
DIRA[vBuzzerPin] := 1
REPEAT vNoOfBeeps
OUTA[vBuzzerPin] := 1
Timing.pause1ms(vOnDuration)
OUTA[vBuzzerPin] := 0
Timing.pause1ms(vOffDuration)
LONG[vBuzzerState] :=0 ''<----- THIS IS THE PART I CAN'T GET TO WORK!!!!
COGSTOP(COGID)
Phil Pilgrim (PhiPi)
01-20-2008, 07:06 AM
To eliminate visually confusing the variable with its address, I would rename your vBuzzerState parameter in Beep to something else. Now, since you don't pass the address of vBuzzerState to the new cog, it's going to use a separate instance of that variable, as declared in your VAR section. To use the same instance, either pass the address of the original variable to BeepRun, or declare that variable in a DAT section.
-Phil
DavidM
01-20-2008, 07:23 AM
Hi Phil,
Do you mean like this..
'' -------------START OF MAIN CODE----------------
CON
_CLKMODE =XTAL1 +PLL16X
_XINFREQ =5_000_000
VAR
BuzzerPin = 27
OBJ
Buzzer : "Buzzer.Spin"
VAR
LONG vBuzzerState
PUB MAIN
Buzzer.Beep ( BuzzerPin, 1000, 1000, 4 , @vBuzzerState)
WAITCNT(1_000_000+CNT)
Buzzer.Beep ( BuzzerPin, 1000, 1000, 3 , @vBuzzerState)
----------END OF MAIN CODE.SPIN ------------------
----------START OF BUZZER.SPIN --------------------
'' Controls a Buzzer via a transistor.
'' Uses a COG so as not to halt system
VAR
LONG BuzzerStack[20]
OBJ
Timing : "Timing.spin"
PUB Beep ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ,vBuzzerState)
IF LONG[vBuzzerState] == 0
LONG[vBuzzerState] := COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps , @vBuzzerState ) , @BuzzerStack )
PUB BeepRun ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ,vBuzzerState)
DIRA[vBuzzerPin] := 1
REPEAT vNoOfBeeps
OUTA[vBuzzerPin] := 1
Timing.pause1ms(vOnDuration)
OUTA[vBuzzerPin] := 0
Timing.pause1ms(vOffDuration)
LONG[vBuzzerState] :=0
COGSTOP(COGID)
Phil Pilgrim (PhiPi)
01-20-2008, 07:59 AM
No. And that's why I implore you again to change the name of the vBuzzState parameter in Beep. It's too confusing. What you're now sending to BeepRun is the address of that parameter. Here's the right way:
PUB Beep ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps, x)
IF LONG[vBuzzerState] == 0
LONG[vBuzzerState] := COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps, x ) , @BuzzerStack )
-Phil
DavidM
01-20-2008, 08:11 AM
Hi Phil,
I just tried your example..
The variable vBuzzerState variable is not recognized
So do you mean this..
PUB Beep ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps, x)
IF LONG[x] == 0
LONG[x] := COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps, x ) , @BuzzerStack )
regards
Dave M
Phil Pilgrim (PhiPi)
01-20-2008, 08:21 AM
Oh, I missed a couple instances of the variable. Now your overall objective is even more confusing. cognew returns the ID of the newly-started cog. Is that what you want to assign to vBuzzerState (before it gets set to zero in BeepRun, that is)? Perhaps you could explain in simple terms what it is you're trying to do. Meanwhile, I'm off to a dinner engagement...
Thanks,
-Phil
DavidM
01-20-2008, 08:36 AM
yes Phil,
I am trying to store the store the cog number in vBuzzerState, This variable is kept in the MAIN METHOD.
I want external methods to manage it, in order to keep my MAIN METHOD clean.
This code runs the first time, but the cog won't update the variable ( i.e set it to zero 0 , meaning no cog is running for this routine.
The trick is to get any method including COGS and external objects to work with GLOBAL Variables
Dave M
DavidM
01-20-2008, 01:15 PM
OK,
I got it WORKING! As Phil tried to say, My variables were wrong, you cant use the same name for the variable, So I added Ptr ( for pointer) at the end of the same variable name
[code]
'' -------------START OF MAIN CODE----------------
CON
_CLKMODE =XTAL1 +PLL16X
_XINFREQ =5_000_000
VAR
BuzzerPin = 27
OBJ
Buzzer : "Buzzer.Spin"
VAR
LONG BuzzerState
PUB MAIN
Buzzer.Beep ( BuzzerPin, 1000, 1000, 4 , @BuzzerState)
WAITCNT(100_000_000+CNT) <- This counter was to short to test!!! My Bad!
Buzzer.Beep ( BuzzerPin, 1000, 1000, 3 , @BuzzerState)
----------END OF MAIN CODE.SPIN ------------------
----------START OF BUZZER.SPIN --------------------
'' Controls a Buzzer via a transistor.
'' Uses a COG so as not to halt system
VAR
LONG BuzzerStack[20]
OBJ
Timing : "Timing.spin"
PUB Beep ( BuzzerPin, OnDuration, OffDuration, NoOfBeeps ,BuzzerStatePtr) <---- I added the letters Ptr at the end of the variable
IF LONG[BuzzerStatePtr] == 0
LONG[BuzzerStatePtr] := COGNEW( BeepRun(BuzzerPin, OnDuration, OffDuration, NoOfBeeps , BuzzerStatePtr ) , @BuzzerStack )
PUB BeepRun ( BuzzerPin, OnDuration, OffDuration, NoOfBeeps ,BuzzerStatePtr)
DIRA[BuzzerPin] := 1
REPEAT NoOfBeeps
OUTA[BuzzerPin] := 1
Timing.pause1ms(OnDuration)
OUTA[vBuzzerPin] := 0
Timing.pause1ms(OffDuration)
LONG[BuzzerStatePtr] :=0 <-- This resets the "COG NUMBER variable back in the MAIN METHOD/MEMORY to 0
regards
Dave M