PDA

View Full Version : Passing Variables by reference more than 1 level deep?



DavidM
01-19-2008, 09: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, 01:05 AM
Some actual code would help explain it more. Can you post your program, please?

-Phil

deSilva
01-20-2008, 01: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, 07: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, 08: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, 08: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, 08: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, 09: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, 09: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, 09: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, 02: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