Shop OBEX P1 Docs P2 Docs Learn Events
Variables across objects, again — Parallax Forums

Variables across objects, again

Michael PetryMichael Petry Posts: 11
edited 2010-04-18 19:45 in Propeller 1
Hello.· I have spent 3 days reading threads related to "global variables", "hub ram", and "passing data between objects".· I have about decided that it's impossible to do what I'm attempting, but I want to try one last time.

I have a collaborative project with my son:·· I want to build an object, which my son will use in his projects.· My object will run in it's own cog, and will constantly send data back to my son's cog/object.· His object will monitor the data stream for changes, and respond accordingly.··· In vain, I have built a test program.·
{{VarTest.spin}}
{{This is a test to determine if another cog, running an external object, can pass a
  continuous data stream back to the main cog/object. The shared memory location is $7f00}}
CON
  _CLKMODE = XTAL1 + PLL4X     'Set to ext low-speed crystal, 4x PLL
  _XINFREQ = 5_000_000         'Frequency on XIN pin is 5 MHz
VAR
  word pin
  long SqStack[noparse][[/noparse]100]
OBJ
  MyCog : "ChangePin"
PUB Main                       'This is my son's object.  it looks for a change at $7F00
  cognew(MyCog.ChangePin, @SqStack)  'Start my cog, running ChangePin (my object) 
  dira[noparse][[/noparse]16]~~
  dira[noparse][[/noparse]17]~~
  dira[noparse][[/noparse]18]~~
  dira[noparse][[/noparse]19]~~
  dira[noparse][[/noparse]20]~~
  dira[noparse][[/noparse]21]~~
  dira[noparse][[/noparse]22]~~
  dira[noparse][[/noparse]23]~~
  repeat
    pin := word[noparse][[/noparse]$7f00]         'Look for changes in memory address $7f00
    outa[noparse][[/noparse]pin]~~                'and turn on the corresponding pin
       

{{ChangePin.spin}}
PUB ChangePin                  'Modify the data in memory address $7F00, which my son's cog will watch
  word[noparse][[/noparse]$7f00] := 16
  waitcnt(20_000_000 + cnt)
  word[noparse][[/noparse]$7f00] := 20
  waitcnt(20_000_000 + cnt)
  word[noparse][[/noparse]$7f00] := 23


This almost works.·· The first cog·does see a change at memory address $7F00, but only only the last change made (:=23).· It does not see anything the 2nd cog does, until the 2nd cog stops.· Any suggestions?

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2009-05-22 00:40
    I think what you want to do is possible, you may need a different mechanism for communicating a memory location between cogs. For example, the attached demo uses a bi-color LED driver. The driver has the ability to do pwm brightness control of the LED. With the LED object there is a method that reveals the hub address of the objects brightness control variable. This address is passed to a third cog running a little Spin method to handle "background" fading of the LED.

    Cog 0 : Demo code
    Cog 1 : LED driver
    Cog 2 : fader method that uses address of the LED object's brightness variable

    Perhaps hard-wiring an hub address is not a good idea; let the program locat the variable and then reveal that location with @.
  • BradCBradC Posts: 2,601
    edited 2009-05-22 00:49
    Michael Petry said...

      cognew(MyCog.ChangePin, @SqStack)  'Start my cog, running ChangePin (my object) 
    
    
    


    There is your problem. You can't start a cog from a method in another object.

    Do something like this.

    PUB NewCog
      MyCog.ChangePin
    
    ... other code here
      cognew(NewCog, @SqStack)
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "VOOM"?!? Mate, this bird wouldn't "voom" if you put four million volts through it! 'E's bleedin' demised!
  • Michael PetryMichael Petry Posts: 11
    edited 2009-05-22 03:33
    BradC said...

    There is your problem. You can't start a cog from a method in another object.
    Thank you!·· Problem solved!·· Here is the code, incase someone else needs to copy the answer.

    {{VarTest.spin}}
    {{This is a test to determine if another cog, running an external object, can pass a
      continuous data stream back to the main cog/object. The shared memory location is $7f00}}
    CON
      _CLKMODE = XTAL1 + PLL4X     'Set to ext low-speed crystal, 4x PLL
      _XINFREQ = 5_000_000         'Frequency on XIN pin is 5 MHz
    VAR
      word pin     
    OBJ
      OtherCog : "ChangePin3"      'This is my son's object.  it looks for a change at $7F00
    PUB Main                       
      OtherCog.ChangePin           'Start my cog, running ChangePin (my object) 
      dira[noparse][[/noparse]16]~~
      dira[noparse][[/noparse]17]~~
      dira[noparse][[/noparse]18]~~
      dira[noparse][[/noparse]19]~~
      dira[noparse][[/noparse]20]~~
      dira[noparse][[/noparse]21]~~
      dira[noparse][[/noparse]22]~~
      dira[noparse][[/noparse]23]~~
      repeat
        pin := word[noparse][[/noparse]$7f00]          'Look for changes in memory address $7f00
        outa[noparse][[/noparse]pin]~~                 'and turn on the corresponding pin
           
    

    {{ChangePin.spin}}
    VAR
      long SqStack[noparse][[/noparse]100]  
    PUB ChangePin                  'Modify the data in memory address $7F00, which my son's cog will watch
      cognew(newcog, @SqStack)
    PUB newcog
      word[noparse][[/noparse]$7f00] := 16
      waitcnt(20_000_000 + cnt)
      word[noparse][[/noparse]$7f00] := 17
      waitcnt(20_000_000 + cnt)
      word[noparse][[/noparse]$7f00] := 18
      waitcnt(20_000_000 + cnt)
      word[noparse][[/noparse]$7f00] := 19
    

    Post Edited (Michael Petry) : 5/22/2009 3:39:44 AM GMT
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-05-22 03:53
    As long as you keep all methods within ONE *.SPIN-file you can use all variables even ACROSS cogs

    below is a demo how a variable is changed by different cogs

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      
    VAR
      long CogStack1[noparse][[/noparse] 20]
      long CogStack2[noparse][[/noparse] 20]
      
      long MyTestVar
    
    OBJ
      debug : "FullDuplexSerial"
    
    
    PUB Main
    'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run
      'heart.Start(27, 200)
      debug.start(31, 30, 0, 9600)
      
      MyTestVar := 100
      debug.str(string("Start MyTestVar="))
      debug.dec(MyTestVar)
      debug.Tx(13)
    
      cognew(M1,@CogStack1)
      cognew(M2,@CogStack2)
      
      repeat
        waitcnt(clkfreq + cnt)
        debug.str(string("MyTestVar="))
        debug.dec(MyTestVar)
        debug.Tx(13)
    
    
    PUB M1
      repeat
        waitcnt(ClkFreq * 3 + cnt)
        MyTestVar := 1
    
    
    PUB M2
      repeat
        waitcnt(ClkFreq * 5 + cnt)
        MyTestVar := 2      
    
    



    if you want to exchange data between different objects which means exchanging data between code that is saved in different *.SPIN-files

    simply define "get" and "set"-methods

    let's assume the code below is in a *.SPIN-file named MyObject.SPIN

    VAR
      long MyVar1
    
    PUB Get_MyVar1 : MyReturnValue
      MyReturnValue := MyVar1
    
    PUB Set_MyVar1 (MyValue)
    
      MyVar1  := MyValue
    
    



    inside your main.spin you have some code

      OBJ  
        MyObj "MyObject"
    
      'whenever you want to do a change to the value of MyVar
      'simply call
      MyObj.Set_MyVar1(16)
      MyObj.Set_MyVar1(20)
      MyObj.Set_MyVar1(23)
    
    
    



    you only wrote that the second objects monitors a datastream and respond on changes

    As soon as you describe what you want to do as the whole thing in your project I'm sure the forum-members will
    find several solutions

    the other way is to pass the RAM-adress of the variable to the other object

    content of file ObjectOfMicheals_Son.SPIN
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    OBJ
      MichaelObj : "ObjectOfMichael"
        
    VAR
      long MyPin
    
    
    PUB Main
      dira[noparse][[/noparse] 16..23]~~
      'the object should cotain a start-method which does the cognew INSIDE the object ITSELF
      '@MyPin passes the RAM-Adress of Variable MyPin to the other object
      
      MichaelObj.Start(@MyPin) 
       
      repeat
        !outa[noparse][[/noparse] MyPin] 'xor the status of the Pin to see it blinking   
    
    
    



    content of file ObjectOfMichael.spin
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    VAR
      long CogStack[noparse][[/noparse] 20]
      long AdressOfVarPin
      
    
    PUB Start(Pointer)
      AdressOfVarPin := Pointer 'Pointer contains the RAM-Adress of the Variable 
      cognew(ChangePin,@CogStack) 'do the cognew INSIDE the object ITSELF 
    
    
    PUB ChangePin
      repeat 'do it in a repeat loop for constantly watching the whole thing
        long[noparse][[/noparse]AdressOfVarPin] := 16 'store new value into RAM-Adress hold by AdressOfVarPin  
        waitcnt(ClkFreq / 4  + cnt)
        
        long[noparse][[/noparse]AdressOfVarPin] := 20
        waitcnt(ClkFreq / 4  + cnt)
        
        long[noparse][[/noparse]AdressOfVarPin] := 23
        waitcnt(ClkFreq / 4  + cnt)
    
    
    



    see also attached archive
  • Michael PetryMichael Petry Posts: 11
    edited 2009-05-22 04:13
    StefanL38 said...
    As long as you keep all methods within ONE *.SPIN-file you can use all variables even ACROSS cogs
    Yep, but.... I want to keep a seperate spin file, so I can modify and tweak my object without affecting what my son is doing.·· He should be able to use my object in several different projects, which to my understanding, is the purpose of creating seperate objects (spin files).
    the other way is to pass the RAM-adress of the variable to the other object said...
    Yes.· I started out by·sending the address using @, but it still was not working.· So I simplified things by using the address directly ($7f00), which still did not work, for the reason that bradC gave.· I appreciate your example and when I wake up, I'll study it some more and learn!· Thanks!

    Post Edited (Michael Petry) : 5/22/2009 3:34:03 PM GMT
  • HemPeterHemPeter Posts: 28
    edited 2010-04-18 15:22
    I found this info so helpful! cheers guys

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm either going mad or both...
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-04-18 19:45
    You could also define the address $7f00 as a constant in your object (e.g. named MY_ADR) . Your son then can access the same memory location by:

    word[noparse][[/noparse] OtherCog#MY_ADR ]

    But I think your first idea was better - or what stefan38 suggests in the last example - passing the address to use to your object. Because this way the main-program has control over all memory used by direct access. Say you have different objects that work this way or your main want's to use such an object twice. Then you have potentially conflicts in case both objects define the same address for such a communication variable.

    Post Edited (MagIO2) : 4/18/2010 7:51:32 PM GMT
Sign In or Register to comment.