Shop OBEX P1 Docs P2 Docs Learn Events
stop a cog while it's busy? — Parallax Forums

stop a cog while it's busy?

xanaduxanadu Posts: 3,347
edited 2012-05-14 16:43 in Propeller 1
I'm using coginit and cogstop. Inside the new cog is a timer, and while the timer is running the cog won't shut off using cogstop. Is there a way to make the cog stop even though it is executing an instruction or can the new cog only stop between instructions?


Thanks!

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-05-14 14:54
    cogstop should work regardless of what the cog is doing. How do you know the cog isn't stopping? Show us some code, please.

    -Phil
  • xanaduxanadu Posts: 3,347
    edited 2012-05-14 15:02
    I know the cog isn't stopping because it's panning a camera. I wrote a remote control for a pan tilt servo base. Then I added a pre-programmed 'patrol' mode where it swings from side to side automatically. While panning to the next position and I stop the new cog the camera continues to pan until the preset is reached. Then I can take control.
        "z", "Z":
           coginit(4,patrol, @stack[0])           'camera patrol mode on
           xbee.str(string(" Cam Patrol On "))
    
         "c", "C":
           cogstop(4)                                  'camera patrol mode off
           xbee.str(string(" Cam Patrol Off "))    
    

    The above code listens for z or c character on XBee.
    pub patrol
    
     servo.set(2, P_POS1, 2) 'init pos
     servo.set(3, T_POS1, 2)
     pause (15000)
    
       repeat
        servo.set(2, P_POS2, 2)
        P_POS := P_POS2         'sync    
        pause (30000)
        
        servo.set(3, T_POS2, 2)
        T_POS := T_POS2          'sync
        pause (5000)
        
        servo.set(2, P_POS1, 2)
        P_POS := P_POS1        'sync           
        pause (30000)
        
        servo.set(3, T_POS1, 2)
        T_POS := T_POS1         'sync
        pause (5000)
    

    The above code moves the pan tilt servos to predefined positions.


    Thanks a lot!
  • xanaduxanadu Posts: 3,347
    edited 2012-05-14 15:10
    Maybe this;
    repeat until P_POS2 := P_LIMIT
        servo.set(2, P_POS2, 2)
        P_POS2 := P_POS2 + 1             
    

    That way it's not waiting until the end like below?
    repeat
        servo.set(2, P_POS2, 2)
        P_POS := P_POS2             
        pause (30000)
    
  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-05-14 15:49
    If you're panning a camera it's likely you have servo cog in use and that continues. What you might want to do is have this cog monitor a shutdown flag that is stored the hub. Your main program would set this flag and on reading, the cog could handle any required maintenance and then shutdown cleanly. I do this with my audio play object so that it can be stopped while the file is playing or looping.

    [Edit] Am I mistaken or is that my servo object (jm_servo8_adv) you're using? That would explain why the servo doesn't stop -- the movement to destination is still in progress. Maybe I should add a halt method that will stop the servo where it is.
  • xanaduxanadu Posts: 3,347
    edited 2012-05-14 15:51
    This cog cannot be stopped while in motion either:
    pub patrol
    
      repeat until P_POS == P_POS2     'P_POS pan current position, P_POS2 pan limit right
         servo.set(2, P_POS, 2)               'move the pan servo to the limit
         P_POS := P_POS + 1                'slowly 
    
    

    I thought that without the pause the cog has to stop instantly because it's going line to line fast.

    Here is how I'm stopping the cog:
    cogstop(4)                'camera patrol mode off
    
    
  • xanaduxanadu Posts: 3,347
    edited 2012-05-14 16:00
    JonnyMac wrote: »
    If you're panning a camera it's likely you have servo cog in use and that continues. What you might want to do is have this cog monitor a shutdown flag that is stored the hub. Your main program would set this flag and on reading, the cog could handle any required maintenance and then shutdown cleanly. I do this with my audio play object so that it can be stopped while the file is playing or looping.

    Hey JM thanks, I'm using your servo object. Working great again on yet another project. What you said makes sense I hadn't even thought about the servo object. I'm still really confused about why shutting down my cog that calls your object wouldn't stop the servo though. I'm trying to write a demo code not involving servos just LEDs and timers to work it out.
  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-05-14 16:11
    Keep in mind that you are running the servos very slowly by specify a speed differential of 2us/S -- the servo driver will keep moving a channel until the servo is at the desired target.

    Add these to methods to your copy of the object:
    pub halt(ch)
    
    '' Halts servo at current position
    '' -- allows iteruption of programmed move
    
      if ((ch => 0) and (ch =< CH_LAST))                            ' legal channel?
        target[ch] := pos[ch]                                       ' set target to current pos  
    
    
    pub halt_all
    
    '' Halt all servos at current position  
    
      bytemove(@target, @pos, 8)                                    ' update all targets
    


    Then you can update you patrol method to look like this -- it's more work, but it allows the method to stop the servos before committing on-demand hari-kari:
    pub patrol | t
    
      servo.set(2, P_POS1, 2) 'init pos
      servo.set(3, T_POS1, 2)
      pause (15000)
    
      repeat
        servo.set(2, P_POS2, 2)
        P_POS := P_POS2         'sync    
        t := cnt
        repeat 30000
          waitcnt(t += clkfreq / 1_000)
          if (killpatrol == true)
            servo.halt(2)
            servo.halt(3)
            cogstop(cogid) 
        
        servo.set(3, T_POS2, 2)
        T_POS := T_POS2          'sync
        t := cnt
        repeat 5000
          waitcnt(t += clkfreq / 1_000)
          if (killpatrol == true)
            servo.halt(2)
            servo.halt(3)
            cogstop(cogid) 
        
        servo.set(2, P_POS1, 2)
        P_POS := P_POS1        'sync           
        t := cnt
        repeat 30000
          waitcnt(t += clkfreq / 1_000)
          if (killpatrol == true)
            servo.halt(2)
            servo.halt(3)
            cogstop(cogid)
        
        servo.set(3, T_POS1, 2)
        T_POS := T_POS1         'sync
        t := cnt
        repeat 5000
          waitcnt(t += clkfreq / 1_000)
          if (killpatrol == true)
            servo.halt(2)
            servo.halt(3)
            cogstop(cogid)
    


    There may be a way to make this more elegant but without the full listing and understanding the intent, I'm taking the easy route. Of course, killpatrol is a global variable. You need to set this back to false before relaunching patrol.
  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-05-14 16:21
    Here's a slightly more elegant version of patrol():
    pub patrol | idx, delay, t
    
      idx := 0
    
      repeat
        case idx
          0:
            servo.set(2, P_POS1, 2) 
            servo.set(3, T_POS1, 2) 
            delay := 15_000
    
          1:
            servo.set(2, P_POS2, 2)    
            P_POS := P_POS2
            delay := 30_000
    
          2:
            servo.set(3, T_POS2, 2)     
            T_POS := T_POS2
            delay := 5_000
    
          3:
            servo.set(2, P_POS1, 2)  
            P_POS := P_POS1          
            delay := 30_000
    
          4:
            servo.set(3, T_POS1, 2)
            T_POS := T_POS1        
            delay := 5_000
    
        t := cnt                           
        repeat delay                      
          waitcnt(t += clkfreq / 1_000)    
          if (killpatrol == true)          
            servo.halt(2)                  
            servo.halt(3)                  
            cogstop(cogid) 
    
        idx += 1
        if (idx == 5)
          idx := 1
    
  • xanaduxanadu Posts: 3,347
    edited 2012-05-14 16:41
    I was not keeping in mind the speed I was running it at and now I'm starting to see why things are happening. Thanks a bunch, I added the halt to your object and tested it and it stops the servos. It is working great now just by calling;
           servo.halt(2)
           servo.halt(3)
           cogstop(4)                  
    

    I'm adding in the method, by your example so I can keep the vars in sync for coming out of patrol into manual, otherwise I'd probably just do the above only.

    Thanks!!
  • xanaduxanadu Posts: 3,347
    edited 2012-05-14 16:43
    JonnyMac wrote: »
    Here's a slightly more elegant version of patrol():
    pub patrol | idx, delay, t
    
      idx := 0
    
      repeat
        case idx
          0:
            servo.set(2, P_POS1, 2) 
            servo.set(3, T_POS1, 2) 
            delay := 15_000
    
          1:
            servo.set(2, P_POS2, 2)    
            P_POS := P_POS2
            delay := 30_000
    
          2:
            servo.set(3, T_POS2, 2)     
            T_POS := T_POS2
            delay := 5_000
    
          3:
            servo.set(2, P_POS1, 2)  
            P_POS := P_POS1          
            delay := 30_000
    
          4:
            servo.set(3, T_POS1, 2)
            T_POS := T_POS1        
            delay := 5_000
    
        t := cnt                           
        repeat delay                      
          waitcnt(t += clkfreq / 1_000)    
          if (killpatrol == true)          
            servo.halt(2)                  
            servo.halt(3)                  
            cogstop(cogid) 
    
        idx += 1
        if (idx == 5)
          idx := 1
    

    Or I'll just use this... hehe thanks!
Sign In or Register to comment.