Shop OBEX P1 Docs P2 Docs Learn Events
Stopping a cog that started in another object — Parallax Forums

Stopping a cog that started in another object

xanaduxanadu Posts: 3,347
edited 2012-10-29 09:09 in Propeller 1
"It is possible for any cog to start and stop any other cog, but in practice it is not done outside of the logical object except in extreme cases." -http://www.parallax.com/portals/0/help/P8X32A/QnaMobile/Advanced/Content/QnaTopics/QnaCogs.htm

Can anyone tell me how that is done, if I were to have an extreme case? If I had a bunch of objects and they're all launching cogs and I don't understand the objects enough to modify them to include stopping is there really a way to shut them all down from the top object?

This is in regard to Servo32v6 and its Servo32_Ramp_v1 object.

Below is my altitude hold, using an XBee to switch between regular TX controls and altitude hold mode. I can get either one to work, but toggling between the two is glitchy, and I know it is because I'm not stopping the right cogs.
'' Altitude Hold V0.8 Main 

OBJ
 
 RX         : "RX"
 servo      : "Servo32v6"
 alt        : "29124_altimeter"
 xbee       : "xbee_object_2"

var
        
 long start_alt
 long elevservo[20]
 long balt, getalti[20]
 long pulsewidth[60]
 long txstack[30]
 long servostack[30]
 long altstack[30] 

 
CON

 _clkmode = xtal1 + pll16x           
 _xinfreq = 5_000_000
 
 servoPin = 7                          ' Servo signal to this I/O pin-change if needed
  
 XBR      = 15                         ' XBee Dout
 XBT      = 14                         ' XBee Din
  

PUB Main | c 

  xbee.start(XBR, XBT, %0000, 9_600)                            ' start XBee coms 9600 baud
  waitcnt(clkfreq * 1 + cnt)
  xbee.at_init
  xbee.cr                                                       ' initialize xbee
  xbee.str(string("Roboglider Modem Online"))                   ' indicate sys reboot
  xbee.cr
  

 xbee.rxflush                                                   ' clear trash from xbee
  repeat
    c := xbee.rxtime(250)
    
    case c     
      "h", "H":
         xbee.str(string(" ALT HOLD MODE"))
         xbee.cr
         
         coginit(3,getalt,@altstack)
         coginit(6,servoc,@servostack)
          
      "n", "N":
         xbee.str(string(" TX MODE"))
         xbee.cr
         
         coginit(5,txmode, @txstack)
           
 
PUB getalt | a

  start_alt := 10                                        ' Setup up altitude to match servo center * gain
  alt.start(alt#QUICKSTART, alt#BACKGROUND)              ' Start altimeter for QuickStart with background processing.
  alt.set_resolution(alt#HIGHEST)                        ' Set to highest resolution.
  alt.set_altitude(alt.m_from_ft(START_ALT * 100))       ' Set the starting altitude, based on average local pressure.
  
         
  repeat
                                                         
    a := alt.altitude(alt.average_press)                 ' Get altitude data 
    balt := a * 5                                        ' Copy to VAR w/ gain
 
PUB Servoc | tInc, tc, tHa, t

 ctra[30..26] := %00100                                 ' Configure Counter A to NCO
 ctra[8..0]   := servoPin

 frqa := 1
 dira[servoPin]~~
 
  
 ' Set up cycle and high times
 tInc := clkfreq/1_000_000
 tC   := tInc * 21_500
 tHa  := tInc * 1500                         
 t    := cnt                                            ' Mark counter time

 repeat                                                 ' Repeat PWM signal
   tHa  := tInc * balt                                  ' Sync servo position/altimeter
   phsa := -tHa                                         ' Set up the pulse + Gain
   t += tC                                              ' Calculate next cycle repeat
   waitcnt(t)                                           ' Wait for next cycle
   
PUB txmode

  servo.start

  Rxinput

PUB RXinput  | i, pulse[6]

  RX.start(@pins,@pulseWidth)
  waitcnt(clkfreq/2 + cnt)

  repeat
    repeat i from 0 to 5
      pulse[i] := pulsewidth[i]                              ' capture pulse values from pins 1
      out(i + 7, pulse[i])                                   ' send servo pulses to pins 7
 
PUB out(_pin, _pulse)

    servo.set(_pin, _pulse)


DAT
  pins  LONG 1 


{{
+------------------------------------------------------------------------------------------------------------------------------+
¦                                                   TERMS OF USE: MIT License                                                  ¦                                                            
+------------------------------------------------------------------------------------------------------------------------------¦
¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    ¦ 
¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    ¦
¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦
¦is furnished to do so, subject to the following conditions:                                                                   ¦
¦                                                                                                                              ¦
¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦
¦                                                                                                                              ¦
¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          ¦
¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         ¦
¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   ¦
¦ARISING FROM,     OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         ¦
+------------------------------------------------------------------------------------------------------------------------------+
}}                             

Thanks.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-10-28 18:42
    If v7/v2 are anything like v6/v1 you're using then you have to make minor changes as the info (cog ID) is simply thrown away. For the ramp object let its method return the result from cognew. In Servo32 apply the same for the start and ramp methods. Your main object will then have to remember those ID numbers. Then again, people here will complain and demand that you do it properly and implement stop methods. Your call.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-10-28 18:44
    First of all, you're using coginit to start cogs, which is bad practice. Without tracking exactly which cogs are being used and when, you have no idea whether cogs 3, 5, and 6 are in use when you (re)start them. Always use cognew to start cogs. I'm not saying that this is the root of the problems that you're seeing, but fix this first before probing further.

    -Phil
  • xanaduxanadu Posts: 3,347
    edited 2012-10-28 19:10
    Thank you for the help. I had replaced cognew with coginit so I knew which cogs I was using, before I had realized that the ramp object was launching a cog. I just switched back to cognew so I can implement stopping the other cogs properly. I guess all I need to do is modify that servo object to include a stop method. The other objects (rx and alt) already have one, which is great.

    I guess I need to brush up on manipulating cog ID's. I went through this all I think around a year ago and seem to have completely forgot. The example in the PE book (page 79) is easy to understand when launching identical cogs from the same line of code.
  • xanaduxanadu Posts: 3,347
    edited 2012-10-29 08:02
    I dropped the servo object and now using the RX channel pulse to modify the same variable as the altimeter does. I ran into the same issue, I can only use altitude hold mode once. TX mode works great and I can switch in and out of it, but once I turn off altitude mode, there is no re-starting it.

    Another question I have is both RX and ALT objects have stop methods, if I call them from my top object that should shut them both down properly, and any cogs they launched as well correct?
  • Mike GreenMike Green Posts: 23,101
    edited 2012-10-29 08:12
    It is the responsibility of the stop method of an object to clean up after itself. That means that it's supposed to stop any cogs that were launched by the start method of the object. This is not done magically. The author of the object is supposed to follow this convention.
  • xanaduxanadu Posts: 3,347
    edited 2012-10-29 09:09
    Copy that Mike. I think the biggest problem here is I wasn't giving the altimeter enough time to launch its cogs, I put in some pauses and got much better results. Cannot wait until lunch time! I feel like another 20 minutes with this and I'll be up and running.

    I also decided to stop trying to stop the objects cogs, let them run and just switch between them by changing the repeat loop that copies the variable from either TX mode or ALT hold to the servo. Then all I need to do is reset the altitude VAR to select a new cruise altitude. I'm not sure why my initial approach was to turn everything on and off, but then again I hadn't realised at the time each object needs x amount of time to get up and running properly.
Sign In or Register to comment.