Shop OBEX P1 Docs P2 Docs Learn Events
Passing a variable value between cogs — Parallax Forums

Passing a variable value between cogs

Ok, I have a couple of problems, but it all boils down to this: How can I pass a variable value between cogs?

My situation?  In one cog I am determining the state of my system, basically by measuring a voltage and comparing it to a test value.  Now, I need to pass this state value to my display cog, where i will change several ranges  on the display due to this state.

This should be pretty basic, but I can't figure it out.  I am doing maintenance on this code, and the original author had all kinds of complex data structures set up to pass values, but I need something simple.

What have I tried?  I tried establishing a VAR and setting it, but then couldn't reference it directly from another cog.  I then tried setting up a routine whose job is just to return this value.  This almost worked, but I realized while testing that it wasn't actually reading the value of the variable that was being set.  If I understand correctly, when I run the routine from a different cog, it still only sees what is on the new cog, not the one being run from its original file. 

Can someone give me a little simple help?

Comments

  • In C you should just use a global variable, declared outside of main().  All cogs have access to global vars.  If you are using Spin then I'm sure there is a similar way of doing it.
  • Unfortunately, I am using Spin.  Yes, in C it would be easy!
  • kwinnkwinn Posts: 8,697
    Measurement cog writes the value to a hub ram variable when it has data and that variable is set to some specific value. Display cog reads the value, sets the variable to the specific value to indicate that it has read the data and then updates the display.
    The variable would typically be part of the display program and it's address passed to the measurement cog on startup. The specific value to indicate the display cog has read the data would be some value that would never be seen as a measurement.
  • Ok, sounds like what I need.  What is the syntax to set up a hub ram variable?  And, then to read it?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-07-24 21:31
    Charles,
    A hub variable is just a VAR variable. If two Spin cogs are started from the same object, nothing special needs to be done, since both cogs automatically share the VAR variables declared in that object. But if the second cog is started from an external object, you need to pass that object's start routine the address of the VAR variable (e.g. @MyVariable) so it knows where to read/save data.
    -Phil
  • So, I have cogs started from two separate objects.  In cog A I have a variable, MyState.  What do I need to read that variable in another cog?  sounds like what I need, but I don't really comprehend what to do.  The manual really doesn't deal with what should be a very basic need in the software - how to pass values between cogs!
  • kwinnkwinn Posts: 8,697
    So, I have cogs started from two separate objects.  In cog A I have a variable, MyState.  What do I need to read that variable in another cog?  sounds like what I need, but I don't really comprehend what to do.  The manual really doesn't deal with what should be a very basic need in the software - how to pass values between cogs!


    What programming language are you using for the cogs?
  • Sorry, I am using Spin for everything.
  • As Phil mentioned, variables in the VAR section are shared between cogs. To share variables among objects requires a bit of effort (also explained by Phil).
    The only time sharing variables between cogs is an issue is if the cog is running PASM code rather than Spin. All Spin variables are stored in the hub.
  • Ok, so I am just really dense today.  Can you show me some sample code for passing values between cogs?  All my attempts are just failing.  No errors, just no results either!  This is driving me crazy!!!! ;-)
  • TymkrsTymkrs Posts: 539
    edited 2015-07-24 22:11
    tumblr_lvtb1vFSwe1qf00w4.png
    PUB PWM | ooga
    where "ooga" is the local variable's name.  Hope this helps!
    @atdiy
  • kwinnkwinn Posts: 8,697

    Sorry, I am using Spin for everything.


    Can you attach (as spin or zip files) the measurement and display code along with the cognew commands that start them?
  • Ok, then I need code for passing a variable value between cogs and objects!  I get an error of expecting an expression when I try to just use the variable name!
  • Hi Kwinn, sorry, but no.  It is a large project and NDA's prevent this.  This shouldn't be that hard, should it?
  • Ok, then I need code for passing a variable value between cogs and objects!  I get an error of expecting an expression when I try to just use the variable name!


    You mean stating them as longs? Or something else?
  • Longs would be fine.  I have a whole other issue about floats in spin...
  • kwinnkwinn Posts: 8,697
    When you start the cogs you can pass them the address of a variable as part of the parameter list like this.

    COGNEW (ReadMethod (@CommVar, @Stack )

    COGNEW (DisplayMethod (@CommVar, @Stack )

    Both the read and display methods now have the address of the variable.
  • Taking a look at my start file, I find the following data setups:

    CON
      sizeOfStack_ = 25

      #0 'enum for standard COG data block
      rho             'size of data block
      cogNum          'local copy of cog number
      cogStatus
      StackAddr
      stackSize
      sizeOfDataBlk_
      'The address of the cog datablock is returned by the cog.start function

    DAT {administrative storage for COG}
      podMgrStack long 0[sizeOfStack_]

    DAT {public data}
      podMgrDB LONG sizeOfDataBlk_, {number of elements in this datablock
                  }$deadbeef,       {cog number
                  }$deadbeef,       {status
                  }@podMgrStack,    {address of the cog stack
                  }sizeOfStack_    {number of elements in cog stack}


    And, this is followed by the following code in the start routine:


    'setup the standard datablock
      podMgrDB[stackAddr] := @podMgrStack 'This changes the compileTime offset into runTime address
      'return
      podMgrDB[cogNum]    := COGNEW(PodMgrCOG, @podMgrStack) + 1 'trick, failure = 0 ==> false



    So, he was passing some sort of values to the hub, I just don't know for sure what!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-07-25 01:43
    So, he was passing some sort of values to the hub, I just don't know for sure what!


    So this is the code in the child object's "Start" method right?
    As long as you're aware the value of the cog is one more than the one actually being used, it looks pretty straight forward.
    Why do you think the information isn't being passed back to the parent correctly?
    My guess is you're accessing the memory incorrectly. You may be adding an @ symbol when one isn't needed.
    I think we need to see part of the parent object's code to know what the problem is.
    Edit (edited): One possible problem with the program is the way an address is used as a variable in the data initialized in the DAT section. The address "@podMgrStack" used as a value in the DAT section will have a different value than @podMgrStack when evaluated at runtime. In order to store the correct address of "podMgrStack" the address needs to be evaluated at runtime (or corrected for the compile time offset). By storing the address at runtime, the correct address will be in the data structure. I believe the different ways memory addresses are evaluated is covered in the Propeller manual in the section about the "@" address symbol and/or the "@@" symbol section. I've seen the notation "@@@" used as a why to let compilers know what value to use but this notation isn't used by the Propeller Tool. After looking through your subsequent posts, I don't think this address offset issue is related to the problem you're having.
  • The parent object:

    PUB start | x ' COG 0
      data.init
      data.set(data#packSummaryDataset, data#officialCellCount, conf#maxCellsPerPack_) '<rea num="20121228">

      rtMgrDB  := rtMgr.Start
      podMgrDB := podMgr.Start
      canMgrDB := canMgr.Start(canMgr#xmitOnly)


      REPEAT UNTIL (long[podMgrDB][podMgr#cogStatus] )
      IF (conf#SpecifiedCellCount == 0)
        data.set(data#packSummaryDataset, data#officialCellCount, data.get(data#packSummaryDataset, data#observedCellCount))
      ELSE
        data.set(data#packSummaryDataset, data#officialCellCount, conf#SpecifiedCellCount)

      menu.main  'and never return



    I am trying to use the variable in the menu object!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-07-25 01:44
    Depending on how the parent object is using the code, the value stored for the stack address may be incorrect. I you add the following code to the start method of the child object, the correct address should be returned.
    [code]

    If the parent is already compensating for the address offset then my addition may cause problems.
    Using a memory address in a DAT variable as done in the code you posted will be incorrect.
    To post code in the forum follow the directions in the post linked below.
    http://forums.parallax.com/discussion/comment/1337853/#Comment_1337853



    Edit: I don't think the address offset issue is causing the problems you're experiencing.
  • Charles EdmondsonCharles Edmondson Posts: 46
    edited 2015-08-06 21:06
    Ok, here is what I am presently trying:
    
    PUB Packs | temp
    '  A routine to return the value of the NumPacks variable to other cogs
    
    temp :=1
      if (PV < (Cnt * 27 / 10))  '(NumPacks < 1)
         temp := conf#X
    
    return temp
    

    All the variables PV, Cnt and NumPacks are defined in THIS object. I then run this routine with other.Packs and I get a 1 every time. Those variables don't seem to have a value other than 0.

    Any ideas?
  • Any ideas?


    If you could post enough code to replicate the problem you're seeing we may be able to spot the issue. I'm personally having a hard time following along with little pieces of the program.
    I don't think the problem is related to passing values between cogs. I think the issue is passing values between objects.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-07-25 04:26
    Make a new DAT section containing this:

    mysharedvar   long  0

    In either COG, reference it with @mysharedvar

    This is a simple global. 

    If you want, you can put it at the top of your program too.  You can make multiple CON, DAT, VAR sections, and the DAT section is where assembly language and data typically go.  That's shared due to it being a simple HUB memory declaration. 

    If it's a PASM program, you start it with a COGSTART @myprogram and if it's just some data, you access it with the label associated with that data @mysharedvar style.


  • Thanks all!  It looks like moving my variable form the VAR section to the DAT section, it has the persistence I need to be read by other functions.  Now, I just have to do the other 1000 tasks necessary to finish my contract!  ;-)

  • Thanks all!  It looks like moving my variable form the VAR section to the DAT section, it has the persistence I need to be read by other functions.  Now, I just have to do the other 1000 tasks necessary to finish my contract!  ;-)



    Are there multiple instances of the object? Variables are persistent in both VAR and DAT but the DAT ones are shared among multiple instances of an object.
Sign In or Register to comment.