Shop OBEX P1 Docs P2 Docs Learn Events
Can't escape repeat loop — Parallax Forums

Can't escape repeat loop

Ozzie NeilOzzie Neil Posts: 16
edited 2010-01-04 05:11 in Propeller 1
I am new to propeller having been a Stamp user for a few years.· I am finding SPIN a bit clunky and i am having a problem i can't seem to overcome.


I have a prototype board wired up with 5 inputs to pins 15 to 19.· When anyone of them goes high the value is summed, if the sum is greater than zero then the 3 coginit commands are supposed to execute.· The summing part works well, no problem there.

It all works but the repeat command won't release, i can't stop it and it then appears to hang.· I added a debug string to the end and it won't execute.· The cogint and fire() command does work, it lights up a LED (it will do more than that eventually) but won't escape the repeat command.· I added a second cogint to see if it would release - my thinking was if it·executed the second coginit then the fault was not coginit related.· It executes all 3 coginits, i have tried some repeat whiles etc but to no avail.·

Below is the code i am using, this is my first time on this forum and certainly would appreciate some help.· I am sure it i something simple that i am overlooking.· [noparse]:)[/noparse]· I included the fire() method in case that helps.



· Debug.str(String("Enter delay in seconds: ",9))
· pause := Debug.getdec
···
· repeat
··· value := (ina[noparse][[/noparse]15..19])
··· if value > 0
····· coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0])
····· coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
····· coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])




Pub fire (output,cog,delay)
{{
Fires output.· Parameters are output pin, cpu, delay in seconds
}}
· dira[noparse][[/noparse]0..4]· := %11111································ 'set pins to outputs
·
· waitcnt(clkfreq*delay + cnt)························· 'start delay
· outa[noparse][[/noparse]output] := 1···································· 'turn on
· waitcnt(clkfreq/2 + cnt)····························· 'stay on for...
· outa[noparse][[/noparse]output] := 0···································· 'turn off
· cogstop(cog)········································· 'stop cpu
······

Comments

  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-01-01 10:42
    Repeat is doing exactly what it should do, it is repeating, there is no reason for it to escape. You could try something like this:

    value := 0
    repeat until value  > 0
       value := ina[noparse][[/noparse]15..19]
    coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0])           
    coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
    coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])
    
    



    So it will repeatidly check ina and when it is greater then 0 it will leave the loop and run your coginit commands.

    You can also repeat while which is handy. Page 188 of the manual onwards has quite a few examples.

    Graham

    Post Edited (Graham Stabler) : 1/1/2010 3:16:11 PM GMT
  • Ozzie NeilOzzie Neil Posts: 16
    edited 2010-01-03 05:03
    Thanks for your reply Graham. I left off some commands because i didn't want to confuse any responses, i had already tried your version and it didn't work. I indented the cogints since repeats require indenting.

    I have added the print test string in the code since once it finishes the last cogint it should run the next command (print test string) and it doesn't, it prints the first string (enter delay) so setup of debug is correct.

    If i use either the until or the while it works up to the last cogint and won't print the test string - ( this is only for debugging purposes). Since it still isn't leaving the loop it won't print the the "Program finished" string which is the last program instruction.

    ( i have also used repeat while value == 0 )



    Debug.str(String("Enter delay in seconds: ",9))
    pause := Debug.getdec

    repeat 'until value > 0
    value := (ina[noparse][[/noparse]15..19])
    if value > 0
    coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0]) 'allow 20 for each stack
    coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
    coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])
    Debug.str(String("Test string"))
    'while value == 0

    Debug.str(String("Program finished"))
  • ElectricAyeElectricAye Posts: 4,561
    edited 2010-01-03 05:18
    Oz,

    for people to help you with code, you really need to use the CODE buttons (located below the smilies) to contain your code, otherwise the indentations are lost and nobody knows what you're really doing.


    That way
      your code
        will make sense to people
    
    



    smile.gif
  • Ozzie NeilOzzie Neil Posts: 16
    edited 2010-01-03 06:05
    Hmmm,· my code posted properly the first time using normal spaces, maybe it didn't like the quick reply ..· I'll ty again..

    Debug.str(String("Enter delay in seconds: ",9))
    pause := Debug.getdec

    repeat···· 'until value > 0
    value := (ina[noparse][[/noparse]15..19])
    ·· if value > 0
    ····· coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0])········ 'allow 20 for each stack
    ····· coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
    ····· coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])
    ····· Debug.str(String("Test string"))
    'while value == 0

    Debug.str(String("Program finished"))
  • ElectricAyeElectricAye Posts: 4,561
    edited 2010-01-03 06:46
    Ozzie Neil said...
    Hmmm, my code posted properly the first time using normal spaces, maybe it didn't like the quick reply .. I'll ty again..

    Debug.str(String("Enter delay in seconds: ",9))
    pause := Debug.getdec

    repeat 'until value > 0
    value := (ina[noparse][[/noparse]15..19])
    if value > 0
    coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0]) 'allow 20 for each stack
    coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
    coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])
    Debug.str(String("Test string"))
    'while value == 0

    Debug.str(String("Program finished"))

    On my computer, I'm seeing this:

    repeat     'until value > 0
    value := (ina[noparse][[/noparse]15..19])
    
    



    which has nothing indented under the repeat. Maybe it's showing up on my computer improperly because you aren't using the CODE keys under the smilies to enclose your code, but I think that repeat, by itself, will just hang there forever.
  • SamMishalSamMishal Posts: 468
    edited 2010-01-03 15:21
    Ozzie Neil said...
    Hmmm,· my code posted properly the first time using normal spaces, maybe it didn't like the quick reply ..· I'll ty again..
    Debug.str(String("Enter delay in seconds: ",9))
    pause := Debug.getdec
    repeat···· 'until value > 0
    value := (ina[noparse][[/noparse]15..19])
    ·· if value > 0
    ····· coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0])········ 'allow 20 for each stack
    ····· coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
    ····· coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])
    ····· Debug.str(String("Test string"))
    'while value == 0
    Debug.str(String("Program finished"))
    Ozzie,

    Try this.... I am not sure what logic you are trying to achieve but the Repeat by itself with no indented anything
    under it will just sit there for ever and the program will never do anything.

    This code might be what you want....... but PLEASE when you post code use the FULL posting Editor not the
    Quick Reply one and ALSO use the # key which is one of the editing tools at the top of the Editor IDE.

    This # key will create a box that you can put code in and will maintain Indentations.

    In SPIN....Indentation is of PARAMOUNT importance and wrongly indented code WILL produce all sorts of
    SIDE EFFECTS that you may not want at all.

    Anyway...here is my attempt at correcting your code.....pay particular attention to how things are indented.

    Debug.str(String("Enter delay in seconds: ",9))
    pause := Debug.getdec
     
    repeat until ina[noparse][[/noparse]15..19]   ''since I do not see anywhere you are using the variable value
                               ''then you do not really need to store the result of ina[noparse][[/noparse]]
                               ''also the format of saying until ina[noparse][[/noparse]15..19] is the same as
                               ''saying until ina[noparse][[/noparse]15..19] > 0
     
    ''note  ina[noparse][[/noparse]15..19] will produce a different number than ina[noparse][[/noparse]19..15]
    ''IF you ARE using the number then maybe you probably need ina[noparse][[/noparse]19..15]  not ina[noparse][[/noparse]15..19]
    ''but ina[noparse][[/noparse]15..19] is a good trick to use in certain situations too.
     
    
     
     
    '--------this is also will work 
    'value := 0                   'notice you need to PRESET value to 0 since you are not assured that 
    '                             'value would be 0 before you enter the loop unless it is the FIRST time
    '                             'you run the program.
    'repeat until value > 0
    '   value := (ina[noparse][[/noparse]15..19])    'notice this line is indented under the repeat which makes it part of the
                                  'repeat statement. This line gets executed over and over.
                                  'also you could have said repeat until value  .... no need for value> 0
                            
     
    '--------this is also equivalent....notice no PRESETTING of value is required
    'repeat
    '   value := (ina[noparse][[/noparse]15..19])    'notice this line is indented under the repeat which makes it part of the
    '                             'repeat statement. This line gets executed over and over.
    'until value > 0              'you can also say here until value .... no need for > 0
     
     
    '--------this is also equivalent....notice no PRESETTING of value is required
    'repeat
    '   value := (ina[noparse][[/noparse]15..19])    'notice this line is indented under the repeat which makes it part of the
    '                             'repeat statement. This line gets executed over and over.
    'while not value              'or you can say While Value == 0
     
     
     
     
    ''these line will only get executed once you exit the repeat loop.....and thus there is no
    ''need to put them inside a conditional [b]as you had before[/b] since the condition is assured to be
    ''true since it the same condition as the one for exiting the loop above.
    ''Also this eliminates the need to store ina[noparse][[/noparse]19..15] in the variable value since now we do not use it.
     
    coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0])         'allow 20 for each stack
    coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
    coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]30])
     
    Debug.str(String("Test string"))
    Debug.str(String("Program finished"))
    
    

    ·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Samuel

    www.RobotBASIC.com


    Post Edited (SamMishal) : 1/3/2010 3:29:58 PM GMT
  • Ozzie NeilOzzie Neil Posts: 16
    edited 2010-01-04 04:22
    Thanks to all those who responded to my query and to those who pointed out that indentation is important.· I know that but it seems to vary a bit, i read the code from multiple computers and see the indentation apart from the quick reply while others don't.· Anyway lesson learned so again here is the code.

    On a brighter note i replaced coginit with cognew and it works so my query is now more academic rather than a real problem but why would cognew work and not coginit?· Nothing else was changed so the repeat loops i had were fine, troubleshooting 101 tells me the problem must have been coginit since it was the only thing that was changed..
    I followed samples in Parallax documentation so i am slightly confised as to why it wouldn't work.· I should have used cognew to begin with, oh well.·smile.gif

    Thanks again for all those who responded, i look forward to an answer on my now academic question.

    Debug.str(String("Enter delay in seconds: ",9))
    pause := Debug.getdec
    repeat     'until value > 0
    value := (ina[noparse][[/noparse]15..19])
       if value > 0
          coginit (1,fire(camera,1,pause), @stack[noparse][[/noparse]0])         'allow 20 for each stack
          coginit (2,fire(misc1,2,pause*2), @stack[noparse][[/noparse]20])
          coginit (3,fire(camera,3,pause*4), @stack[noparse][[/noparse]40])
          Debug.str(String("Test string"))
    'while value == 0
    Debug.str(String("Program finished"))
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-01-04 04:36
    Perhaps your "debug" object uses a cog? If so, coginit(1, ....) clobbers the debug cog. There are very few reasons to use coginit instead of cognew.
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-01-04 04:39
    Without seeing the COMPLETE code it is hard to say what it is exactly.

    In coginit YOU have to specify the cog-number.
    If the cog with this number is already in use (from some other part of the software that has used cognew)

    The coginit command will force this cog to stop its running code and start running the new code specified in the second parameter of coginit.

    This means TOTALLY regardless of a cog beeing already in use coginit forces this cog in EVERY CASE to stop working and start the new code.

    ALWAYS use cognew. Then you NEVER have to worry about cognumbers. It is all done automatically in the backround for you.
    There are only a few special cases where it is an advantage to use coginit. 99.9% it is a disadvantage so always use cognew

    best regards

    Stefan
  • ElectricAyeElectricAye Posts: 4,561
    edited 2010-01-04 04:50
    Oz,

    I totally agree with Stefan and jazzed on this. Using cognew allows the Propeller to keep track of which cogs it is using and thus the Propeller will prevent conflicts from occurring (so long as you don't try to call up too many cogs). In other words, if you use cognew, you don't have to think so much about what you and your chip are doing. In the past, I thought using coginit would put me more in control of what's happening with my software, but no matter what I tried, I always got burned by it in the end. Stick with cognew and you'll be happy.


    have fun,
    Mark
    smile.gif
  • Ozzie NeilOzzie Neil Posts: 16
    edited 2010-01-04 05:11
    The only time i specified a cog was where i had it listed, however the theory that specifying a cog is over riding another process seems sound. The program itself isn't that complicated but then it doesn't need to be complicated to get itself into a knot does it?

    I also thought it would give me a greater degree of control but maybe the processor is better at doing that than I am. I think the lesson here is that using coginit is so rarely justified you just don't use it.



    Neil
Sign In or Register to comment.