Shop OBEX P1 Docs P2 Docs Learn Events
cog will not start — Parallax Forums

cog will not start

xanaduxanadu Posts: 3,347
edited 2012-03-06 12:17 in Propeller 1
I'm using a Prop Protoboard and I'm on Chapter 5 and 6 (PE book) cogs, objects, ect. Let me start by saying all example code works great. I have a top object calling three new cogs, making light blink passing variables, loads of fun.

The PE Book is great!

The problem I have is that my own program is not so great, and doesn't work. It seems as though there is no new cog launching. I have not yet grasped one hopefully minor aspect.
OBJ

 LCDManager : "LCDmanager"
 LCDL2Manager : "LCDL2manager"
 WatchDog : "WatchDog"
 
VAR

 long stack[200]
 
CON
   
 _clkmode = xtal1 + pll16x            'clkfreq 80 mHz
 _xinfreq = 5_000_000

PUB Main
                     
 watchdog.beep

 cognew(lcdmanager.lcdbottom, @stack[0])  

 'waitcnt(clkfreq / 2 + cnt)

 watchdog.beep
   
 cognew(lcdl2manager.start, @stack[50])

 waitcnt(clkfreq / 2 + cnt)
   
 watchdog.beep

 cognew(WatchDog.WatchD, @stack[100])

 watchdog.beep

I only hear one beep, and only 'lcdmanager.lcdbottom' will run. I thought that cog0 keeps running and starting the other cogs, but it will not get past the first cog. The object the first cog loads runs great on its own, and also when loaded like this.

The other objects run great on their own as well when loaded into a single cog. However when I upload the code above it just stops and only runs the first cog.

The lcdmanager and lcdl2manager are separate cogs for separate lines of the LCD, could that be a problem even if they are not fighting over the pin?

Comments

  • TylerSkylerTylerSkyler Posts: 72
    edited 2012-03-06 10:16
    I had this problem a while back too. I found that for each new cog it needs it's own stack like:
    VAR
         
          long Stack[30], Stack1[30]
    
    PUB Main
    
          cognew(dosomthing,@stack)
          cognew(dosomthing,@stack1)
    
    

    Hope this helps,

    Tyler
  • Heater.Heater. Posts: 21,230
    edited 2012-03-06 10:19
    You cannot start a cog with a method in a different object.
    You have to call a method in that object that starts any cog it needs with its own methods.
  • xanaduxanadu Posts: 3,347
    edited 2012-03-06 10:22
    I had this problem a while back too. I found that for each new cog it needs it's own stack like:
    VAR
         
          long Stack[30], Stack1[30]
    
    PUB Main
    
          cognew(dosomthing,@stack)
          cognew(dosomthing,@stack1)
    
    

    Hope this helps,

    Tyler

    I will try this.
    Heater. wrote: »
    You cannot start a cog with a method in a different object.
    You have to call a method in that object that starts any cog it needs with its own methods.

    Ah, it HAS to be in the same object. I knew it was something simple like that, but I thought I tried it both ways, must be a combination of the two things listed here. Thank you.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-03-06 10:30
    I don't have your object, so I couldn't do much more than try and write this in a way that it should work, if you have the objects and you write the object assignment code under the OBJ section it should compile.
    
    CON
       
     _clkmode = xtal1 + pll16x            'clkfreq 80 mHz
     _xinfreq = 5_000_000
    
    
    VAR
    
     long stack1[100]
     long stack2[100]
     long stack3[100]
    
    
    OBJ
    
      ' is watchdog an object???
      ' is lcdmanager an object???
      ' is lcd12manager and object???
      pst : "Parallax Serial Terminal" 
    
    PUB Main | timeStamp, waitTime
                         
     'watchdog.beep
    
     cognew(lcd1, @stack1)                  ' call cog to start
     cognew(lcd2, @stack2)                    ' call cog to start
     cognew(lcd3, @stack3)                       ' call cog to start
    
      pst.Str(String("Starting "))  ' for sanitys sake when you are waiting for values to start appearing on the pst
      pst.Str(string(pst#NL))       ' a carriage return after printing something to the pst
    
      waitTime := (clkfreq/4)       ' initialize local variable
      timeStamp := cnt              ' sync variable to cnt
      
      repeat
        ' Do something here
        pst.Str(String("looping "))
        pst.Str(string(pst#NL))
        waitcnt(timeStamp += waitTime)
    
    
    PUB lcd1 | timeStamp, waitTime
    
      waitTime := (clkfreq/4)       ' initialize local variable  
      timeStamp := cnt              ' sync variable to cnt
      
      repeat
        watchdog.beep
        waitcnt(timeStamp += waitTime)
        
    
    
    PUB lcd2| timeStamp, waitTime
    
      waitTime := (clkfreq/3)       ' initialize local variable  
      timeStamp := cnt              ' sync variable to cnt
      
      repeat
        watchdog.beep
        waitcnt(timeStamp += waitTime)
    
    
    
    PUB lcd3| timeStamp, waitTime
    
      waitTime := (clkfreq/2)       ' initialize local variable  
      timeStamp := cnt              ' sync variable to cnt
      
      repeat
        watchdog.beep
        waitcnt(timeStamp += waitTime)
    
    
      
    
    

    xanadu wrote: »
    I'm using a Prop Protoboard and I'm on Chapter 5 and 6 (PE book) cogs, objects, ect. Let me start by saying all example code works great. I have a top object calling three new cogs, making light blink passing variables, loads of fun.

    The PE Book is great!

    The problem I have is that my own program is not so great, and doesn't work. It seems as though there is no new cog launching. I have not yet grasped one hopefully minor aspect.
    OBJ
    
     LCDManager : "LCDmanager"
     LCDL2Manager : "LCDL2manager"
     WatchDog : "WatchDog"
     
    VAR
    
     long stack[200]
     
    CON
       
     _clkmode = xtal1 + pll16x            'clkfreq 80 mHz
     _xinfreq = 5_000_000
    
    PUB Main
                         
     watchdog.beep
    
     cognew(lcdmanager.lcdbottom, @stack[0])  
    
     'waitcnt(clkfreq / 2 + cnt)
    
     watchdog.beep
       
     cognew(lcdl2manager.start, @stack[50])
    
     waitcnt(clkfreq / 2 + cnt)
       
     watchdog.beep
    
     cognew(WatchDog.WatchD, @stack[100])
    
     watchdog.beep
    

    I only hear one beep, and only 'lcdmanager.lcdbottom' will run. I thought that cog0 keeps running and starting the other cogs, but it will not get past the first cog. The object the first cog loads runs great on its own, and also when loaded like this.

    The other objects run great on their own as well when loaded into a single cog. However when I upload the code above it just stops and only runs the first cog.

    The lcdmanager and lcdl2manager are separate cogs for separate lines of the LCD, could that be a problem even if they are not fighting over the pin?
  • idbruceidbruce Posts: 6,197
    edited 2012-03-06 10:36
    You cannot start a cog with a method in a different object.
    You have to call a method in that object that starts any cog it needs with its own methods.

    Call cognew from within the LCDManager object and not within your primary object
  • xanaduxanadu Posts: 3,347
    edited 2012-03-06 10:37
    Turbo,

    Thanks I am using separate object files to keep it easy to look at. I did this with the separate files, and it works well. With the exception that I do not think it's possible to control the LCD using two independent cogs for each line, at least for me right now anyway.

    Thanks again everyone!!
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-03-06 11:42
    Just setting things straight ...

    @TylerSkyler:
    What you say is wrong! Both COGNEW can use the same variable as a base address - no problem with that!
    COGNEW( doSomething, @stack[0] ) is the same as COGNEW( doSomething, @stack + 0 )
    COGNEW( doSomething, @stack[30] ) is the same as COGNEW( doSomething, @stack + 120 ) because of 30*size of long = 30*4 = 120

    @turbosupra:
    Your code also contains the bug which is using lcdmanager.lcdbottom. In other parts this is a valid function call specifying function lcdbuttom in object lcdmanager. But in a cognew it is really calling the function and the result of the function is passed to the cognew. Of course that's not what you want! In cognew only functions which are defined in the same spin file are allowed.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-03-06 11:54
    @xanadu
    In general it is possible to control one piece of hardware from 2 COGs running the LCD driver, but some extra code is needed to hand over the PINs properly. So, usually it's a waste of resources! It's easier to call the LCD functions from 2 COGs syncing the functions for example via lock.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-03-06 12:17
    You are write, thank you. Without having the object attached so that I could load it into the IDE, I was limited on testing and I overlooked that. It should have looked like this:
     cognew(lcd1, @stack1)                  ' call cog to start
     cognew(lcd2, @stack2)                    ' call cog to start
     cognew(lcd3, @stack3)                       ' call cog to start
    

    and I have corrected that in my code example.


    MagIO2 wrote: »
    Just setting things straight ...

    @TylerSkyler:
    What you say is wrong! Both COGNEW can use the same variable as a base address - no problem with that!
    COGNEW( doSomething, @stack[0] ) is the same as COGNEW( doSomething, @stack + 0 )
    COGNEW( doSomething, @stack[30] ) is the same as COGNEW( doSomething, @stack + 120 ) because of 30*size of long = 30*4 = 120

    @turbosupra:
    Your code also contains the bug which is using lcdmanager.lcdbottom. In other parts this is a valid function call specifying function lcdbuttom in object lcdmanager. But in a cognew it is really calling the function and the result of the function is passed to the cognew. Of course that's not what you want! In cognew only functions which are defined in the same spin file are allowed.
Sign In or Register to comment.