Shop OBEX P1 Docs P2 Docs Learn Events
sharing value between methods — Parallax Forums

sharing value between methods

shmowshmow Posts: 109
edited 2008-03-17 13:12 in Propeller 1
Any advice on how to share a value between two methods (which are running on separate cogs)?
When I press the button the LED turns on but it won't flash - my code is below.

Thanks,
Shmow

'' File: Sharing Variable Content.spin
{{One method manipulates variable's value and another method
annunciates it to a LED on pin17 - only when a pushbutton (pin 23) is pressed}}
CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
DAT
  Value_Led byte 0
                       
VAR
  long stack[noparse][[/noparse]20]
  byte LED_One
    
PUB Main
'with pushbutton pressed, second cog and method are started
'when button is released, second cog is stopped and P17 goes low 
  dira[noparse][[/noparse]17] := %1 
  repeat
    if ina[noparse][[/noparse]23]
      coginit(7, Second_Flash, @stack[noparse][[/noparse]10]) 'method starts in separate cog
      Led_One := Value_Led
      outa[noparse][[/noparse]17] := Led_One
    else
      cogstop(7)
      outa[noparse][[/noparse]17] := 0
    
PUB Second_Flash 
'value repeatedly toggles between one and zero at one second intervals
'then assigned to memory location
  repeat
    byte[noparse][[/noparse]@Value_Led] := 1
    waitcnt(clkfreq + cnt)
    byte[noparse][[/noparse]@Value_Led] := 0
    waitcnt(clkfreq + cnt) 

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-03-16 20:51
    I don't really understand what you're trying to do. How about a simple description of what you want to happen, step by step?

    It takes a while for COGINIT or COGNEW to finish. They both set up the other cog, but finish and go on to the next statement a long time before the other cog actually finishes loading and starts (over 100us). Your program loops back and does a COGINIT again long before the 2nd cog would finish loading starting the process over again. Even when the button is released, the new cog is STOPped before it could ever start running.
  • shmowshmow Posts: 109
    edited 2008-03-17 02:47
    Here is the sequence of operation:

    when the input 23 (pushbutton) goes high...
    -the 8th cog is started
    -which runs Second_Flash method - toggling a value between 1 and 0 every two seconds
    -the Second_Flash method also assigns this changing value to a memory location (byte[noparse][[/noparse]@Value_Led])
    -the Main method (running in the default and separate cog) reads the contents of this memory location
    -and assigns this value to the output pin (17).
    when the input 23 (pushbutton) goes low...
    -the 8th cog stops
    -the output pin (17) also goes low

    How I've interpreted your reply: If I hold down the button then the 8th cog is re-initiated constantly,
    or this cog is stopped before anything can happen (if I release the button too soon.)·
    To test that idea, I edited out the code in the ELSE portion of that method but still no flashing output.

    Looks like I haven't grasped the timing·of cogs yet.·

    Perhaps you can steer me in the right direction.


    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    DAT
      Value_Led byte 0 'address of memory location that Second_Flash method writes to
                       'and Main method reads from
                           
    VAR
      long stack[noparse][[/noparse]20]
      byte LED_One
        
    PUB Main
    'with pushbutton pressed, second cog and method are started
    'when button is released, second cog is stopped and P17 goes low 
      dira[noparse][[/noparse]17] := %1 
      repeat
        if ina[noparse][[/noparse]23] 'pushbutton input true when pressed
          coginit(7, Second_Flash, @stack[noparse][[/noparse]10]) 'second flash method starts in separate cog
          Led_One := Value_Led 'value written in memory assigned to local variable
          outa[noparse][[/noparse]17] := Led_One 'output pin mirrors variable value
        else 'pushbutton input false when released
          cogstop(7) 'separate cog is stopped
          outa[noparse][[/noparse]17] := 0 'output pin goes low
        
    PUB Second_Flash 
    'value repeatedly toggles between one and zero at one second intervals
    'then assigned to memory location
      repeat
        byte[noparse][[/noparse]@Value_Led] := 1 'high value of 1 sent to memory
        waitcnt(clkfreq + cnt) ' pause for 1 sec
        byte[noparse][[/noparse]@Value_Led] := 0 'low value of 1 sent to memory
        waitcnt(clkfreq + cnt) ' pause for 1 sec  
    
  • hippyhippy Posts: 1,981
    edited 2008-03-17 03:03
    Why keep initialising the Cog ? Initialise it when INA[noparse][[/noparse] 23 ] goes high, then leave it to run while INA[noparse][[/noparse] 23 ] remains high, when it goes low stop the cog, initialising it again when INA[noparse][[/noparse] 23 ] next goes high again.

    Repeatedly re-initialising the cog doesn't give it time to do anything. A bit like dragging a runner back to the start line while the race is under way.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-03-17 03:11
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
                           
    VAR
      long stack[noparse][[/noparse]20]
      byte Value_Led
        
    PUB Main
    'with pushbutton pressed, second cog and method are started
    'when button is released, second cog is stopped and P17 goes low 
      dira[noparse][[/noparse]17] := %1
      Value_Led := 0
      repeat
        if ina[noparse][[/noparse]23] 'pushbutton input true when pressed
          coginit(7, Second_Flash, @stack[noparse][[/noparse]10]) 'second flash method starts in separate cog
          repeat until Value_Led 'wait until cog starts up
          outa[noparse][[/noparse]17] := Value_Led
        else 'pushbutton input false when released
          cogstop(7) 'separate cog is stopped
          outa[noparse][[/noparse]17] := 0 'output pin goes low
          Value_Led := 0 'reinitialize for next time
        
    PUB Second_Flash 
    'value repeatedly toggles between one and zero at one second intervals
    'then assigned to memory location
      repeat
        Value_Led := 1 'high value of 1 sent to memory
        waitcnt(clkfreq + cnt) ' pause for 1 sec
        Value_Led := 0 'low value of 1 sent to memory
        waitcnt(clkfreq + cnt) ' pause for 1 sec
    


    Note that the second cog doesn't need to use the byte notation to access the variable.
    Anything in a VAR or DAT section is global to the object.

    This still won't do what you say you want, but it will do what the original program
    was written to do. You need to only start the blinking cog once, when the pushbutton
    is initially depressed. If the button is still on and the cog is already started, you just
    want to copy Value_Led to the output pin.

    Normally with the Propeller, if you want a cog to do blinking like this, you give control
    of the I/O pin over to that cog. The direction register bit in the cog is set to output
    and the cog does the blinking. You could even dispense with the variable since the
    input registers of all the other cogs give the actual output state of the I/O pin. You
    wouldn't need to turn off the LED since, by stopping the blink cog, the direction
    register of the blink cog would be cleared to zero making the I/O pin an input.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-03-17 03:22
    Here's a simple blink object. You call the start method with the I/O pin number and the on and off time in milliseconds. You call the stop method to stop it. You could just combine this with your existing code or use it as a separate object:
    VAR byte cog
           long myStack[noparse][[/noparse]20]
    
    PUB start(pin,msOn,msOff)
       stop
       return cog := cognew(blink(pin,msOn,msOff),@myStack) + 1
    
    PUB stop
       if cog
          cogstop(cog~ - 1)
    
    PRI blink(pin,msOn,msOff)
       dira[noparse][[/noparse]pin] := 1
       repeat
          outa[noparse][[/noparse]pin] := 1
          waitcnt((clkfreq/1000)*msOn + cnt)
          outa[noparse][[/noparse]pin] := 0
          waitcnt((clkfreq/1000)*msOff) + cnt)
    
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-03-17 03:24
    I would also question why you use COGINIT instead of the more universally-recommended COGNEW. The assumption that cog 7 (or any particular cog) is even available is based on "privileged" information that good programming style dictates one should ignore. (So I don't have to repeat myself, please read an extended discussion on the subject in this thread.)

    -Phil
  • hippyhippy Posts: 1,981
    edited 2008-03-17 11:45
    My own rewrite of the original code ...

    VAR
      long stack[noparse][[/noparse]20]
      byte Value_Led
      byte Button_Pushed
    
    PUB Main
      dira[noparse][[/noparse]17] := 1
      Value_Led := 0
      Button_Pushed = 0
      repeat
        if ina[noparse][[/noparse]23] <> Button_Pushed
          Button_Pushed ^= 1
          if Button_Pushed
            Cog_Number := cognew(Second_Flash, @stack) + 1
          else
            if Cog_Number 
              cogstop( Cog_Number~ - 1 )
            Value_Led := 0
        outa[noparse][[/noparse]17] := Value_Led
    
    PUB Second_Flash
      repeat
        Value_Led := 1         ' high value of 1 sent to memory
        waitcnt(clkfreq + cnt) ' pause for 1 sec
        Value_Led := 0         ' low value of 1 sent to memory
        waitcnt(clkfreq + cnt) ' pause for 1 sec
    
    
    

    Post Edited (hippy) : 3/17/2008 11:51:55 AM GMT
  • shmowshmow Posts: 109
    edited 2008-03-17 13:12
    Thanks Guys, the suggestions helped.
Sign In or Register to comment.