Shop OBEX P1 Docs P2 Docs Learn Events
Passing Variables by reference more than 1 level deep? — Parallax Forums

Passing Variables by reference more than 1 level deep?

DavidMDavidM Posts: 626
edited 2008-01-20 06:15 in Propeller 1
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 [noparse][[/noparse] MyReferencedVariable ] : = 1 ( to write the variable)
MyVariable := LONG [noparse][[/noparse] MyReferencedVariable ] ( to read the variable)

so far this works.. 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

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-01-19 17:05
    Some actual code would help explain it more. Can you post your program, please?

    -Phil
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-19 17:54
    You most likely need no "second indirection".. Just use the reference as such. A pointer is a pointer is a pointer...
  • DavidMDavidM Posts: 626
    edited 2008-01-19 23:35
    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[noparse][[/noparse]20]
    
         
    OBJ
        Timing : "Timing.spin"
          
    PUB Beep ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ,vBuzzerState)
    
        IF LONG[noparse][[/noparse]vBuzzerState] == 0 
           LONG[noparse][[/noparse]vBuzzerState] :=  COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ) , @BuzzerStack )
                
    PUB BeepRun ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps )
    
        DIRA[noparse][[/noparse]vBuzzerPin]   := 1
              
        REPEAT vNoOfBeeps
        
          OUTA[noparse][[/noparse]vBuzzerPin] := 1 
          Timing.pause1ms(vOnDuration)
        
          OUTA[noparse][[/noparse]vBuzzerPin] := 0
          Timing.pause1ms(vOffDuration)
          
        LONG[noparse][[/noparse]vBuzzerState] :=0                     ''<----- THIS IS THE PART I CAN'T GET TO WORK!!!!
    
        COGSTOP(COGID)
    
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-01-20 00:06
    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
  • DavidMDavidM Posts: 626
    edited 2008-01-20 00:23
    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[noparse][[/noparse]20]
    
         
    OBJ
        Timing : "Timing.spin"
          
    PUB Beep ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ,vBuzzerState)
    
        IF LONG[noparse][[/noparse]vBuzzerState] == 0 
           LONG[noparse][[/noparse]vBuzzerState] :=  COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps , @vBuzzerState ) , @BuzzerStack )
                
    PUB BeepRun ( vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps ,vBuzzerState)
    
        DIRA[noparse][[/noparse]vBuzzerPin]   := 1
              
        REPEAT vNoOfBeeps
        
          OUTA[noparse][[/noparse]vBuzzerPin] := 1 
          Timing.pause1ms(vOnDuration)
        
          OUTA[noparse][[/noparse]vBuzzerPin] := 0
          Timing.pause1ms(vOffDuration)
          
        LONG[noparse][[/noparse]vBuzzerState] :=0                     
    
        COGSTOP(COGID)
    
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-01-20 00:59
    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[noparse][[/noparse]vBuzzerState] == 0 
           LONG[noparse][[/noparse]vBuzzerState] :=  COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps, x ) , @BuzzerStack )
    
    
    


    -Phil
  • DavidMDavidM Posts: 626
    edited 2008-01-20 01:11
    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[noparse][[/noparse]x] == 0 
           LONG[noparse][[/noparse]x] :=  COGNEW( BeepRun(vBuzzerPin, vOnDuration, vOffDuration, vNoOfBeeps, x ) , @BuzzerStack )
    
    



    regards

    Dave M
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-01-20 01:21
    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
  • DavidMDavidM Posts: 626
    edited 2008-01-20 01:36
    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
  • DavidMDavidM Posts: 626
    edited 2008-01-20 06:15
    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

    [noparse][[/noparse]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[noparse][[/noparse]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[noparse][[/noparse]BuzzerStatePtr] == 0
    LONG[noparse][[/noparse]BuzzerStatePtr] := COGNEW( BeepRun(BuzzerPin, OnDuration, OffDuration, NoOfBeeps , BuzzerStatePtr ) , @BuzzerStack )

    PUB BeepRun ( BuzzerPin, OnDuration, OffDuration, NoOfBeeps ,BuzzerStatePtr)

    DIRA[noparse][[/noparse]BuzzerPin] := 1

    REPEAT NoOfBeeps

    OUTA[noparse][[/noparse]BuzzerPin] := 1
    Timing.pause1ms(OnDuration)

    OUTA[noparse][[/noparse]vBuzzerPin] := 0
    Timing.pause1ms(OffDuration)

    LONG[noparse][[/noparse]BuzzerStatePtr] :=0 <-- This resets the "COG NUMBER variable back in the MAIN METHOD/MEMORY to 0


    regards


    Dave M
Sign In or Register to comment.