Shop OBEX P1 Docs P2 Docs Learn Events
Spin code help — Parallax Forums

Spin code help

Laserist1984Laserist1984 Posts: 9
edited 2009-11-04 15:21 in Propeller 1
Hello Forum ,
I have little problem in how to start to make a delay to turn LED on .
I wrote this code
PUB start|n
  dira[noparse][[/noparse]LED_CONTROL]~~ 'set LED control port to output

  WaitCnt(OneSecond*5 + Cnt)
  repeat
    repeat while ina[noparse][[/noparse]Y_INDEXPULSE]>0  ' wait for pulse
    outa[noparse][[/noparse]LASER_CONTROL]~~             ' turn LED on
    WaitCnt(MicroSecond * 260 + Cnt)  ' LED on at first line of frame  
    outa[noparse][[/noparse]LED_CONTROL]~                ' turn LED off

i will write the pseudo code what i want from this program to do:
repeat:- while ina[noparse][[/noparse]Y_INDEXPULSE]>0,turn LED on,wait 260micro, LED off: i't·done by the code above
··········- while ina[noparse][[/noparse]Y_INDEXPULSE]>0,wait·8ms to turn LED on,wait 260micro, LED off.
········· - while ina[noparse][[/noparse]Y_INDEXPULSE]>0,wait·6ms to turn LED on,wait 260micro, LED off.
········· - while ina[noparse][[/noparse]Y_INDEXPULSE]>0,wait·5ms to turn LED on,wait 260micro, LED off.
········· -while ina[noparse][[/noparse]Y_INDEXPULSE]>0,wait·4ms to turn LED on,wait 260micro, LED off.
········· -while ina[noparse][[/noparse]Y_INDEXPULSE]>0,wait·7 ms to turn LED on,wait 260micro, LED off.

how i can make it in intelligent way and nice in Spin ?
I hope that i describe good :-)
Thank you in advance

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-03 18:21
    First of all you should replace the while ina - loop with the waitpne or waitpeq statement. Waitpeq and waitpne have better response times than you selfmade wait and reduce power consumption.

    Reason: The ina might be read just a short moment before the pulse arrives. Then the comparison and the next repeat statement will be executed before the next ina. Waitpeq and waitpne have an equivalent PASM instruction. So, an internal comparator constantly checks the ina-register. As long as the wait-condition is not true, the COG is in a halt state.

    Is it ensured that the pulse of that pin ends before your switch on - wait - switch off sequence is finished? Otherwise your wait until might react twice on the same pulse.

    For your variable wait-time:

    1. use a counter variable to count from 0 to 5 - for example in a repeat loop.

    2. define a DAT section "waittimes" for example, which contains 6 long values that you have to add to cnt in the waitcnt-statement

    DAT

    waittimes long 400, clkfreq*8/1000, clkfreq*6/1000, clkfreq*5/1000 ...

    3. Use these values in the waitcnt like

    waitcnt( long[noparse][[/noparse]@waittimes+counter] + cnt )



    Hope that helps. If you have further problems, ask again.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-03 20:02
    That should do the job:
    PUB start | count
      dira[noparse][[/noparse]LED_CONTROL]~~ 'set LED control port to output
      WaitCnt( clkfreq + Cnt)
    [color=green]
      ' This makes it an endless loop, you have to decide if you want that
    [/color][color=green]  repeat      
    [/color][color=purple]    ' here is the counter which simply loops through the timing list in the dat section.
    [/color][color=purple]    ' As we have 6 values in the list, we loop from 0 to 5
    [/color][color=purple]    repeat count from 0 to 5
    [/color][color=orange]      ' this replaces your repeat until, which checks the input-pin.
    [/color][color=orange]      ' As mentioned this only works fine if the pulse on Y_INDEXPULSE is shorter than the waittime and the
    [/color][color=orange]      ' 260 microseconds. If not simply add a waitpne with the same parameters. That makes sure that the input
    [/color][color=orange]      ' pin was low before waiting for high
          waitpeq( 1<<Y_INDEXPULSE, 1<<Y_INDEXPULSE, 0 )
    [/color][color=red]      ' here we wait for the time found in the table at position "count"
          waitcnt( long[noparse][[/noparse] @waittime+count ] + cnt )
    [/color]      outa[noparse][[/noparse]LED_CONTROL]~~             ' turn LED on
          WaitCnt(MicroSecond * 260 + Cnt)  ' LED on at first line of frame  
          outa[noparse][[/noparse]LED_CONTROL]~                ' turn LED off
         
    DAT
    MicroSecond long 80
    
    waittime long 400                    ' waittime + 0, this is close to the shortest time you can wait
             long 80_000_000 * 8 / 1000  ' waittime + 1
             long 80_000_000 * 6 / 1000  ' waittime + 2
             long 80_000_000 * 5 / 1000  ' waittime + 3 
             long 80_000_000 * 4 / 1000  ' ....
             long 80_000_000 * 7 / 1000
             ' 80_000_000/1000 is equal to 1 ms if you run the prop with 80MHz.
             ' If not you have to change 80_000_000. The multiplication is done 
             ' before because we don't want to loose digits due to integer-arithmetics
    
  • Laserist1984Laserist1984 Posts: 9
    edited 2009-11-03 20:07
    Thank you alooot MagIo2 , i will try it and i will tell you about results .
    Have a nice day
  • Laserist1984Laserist1984 Posts: 9
    edited 2009-11-04 00:13
    it's seems something wrong happen , i am trying to make change in this code if i want to do:··when the first time· ina[noparse][[/noparse]Y_INDEXPULSE]>0 , LED will be ON 260 microsecond , LED off , after 10 millisecond LED is·ON 260microsecond , LED off, after 10 millisecond LED is·ON 260microsecond , LED off .....
    PUB start
      dira[noparse][[/noparse]LED_CONTROL]~~ 'set LED control port to output
          
      WaitCnt( clkfreq + Cnt)
          if ina[noparse][[/noparse]Y_INDEXPULSE]>0
          Repeat  
          outa[noparse][[/noparse]LED_CONTROL]~~             ' turn LED on
          WaitCnt(MicroSecond * 260 + Cnt)  ' LED on 260 microsecond
          outa[noparse][[/noparse]LED_CONTROL]~                ' turn LED off
          waitcnt( long[noparse][[/noparse]@waittime] + cnt )     ' wait 10 millisecond
          
           
    DAT
    MicroSecond long 80
    waittime long 80_000_000 * 10 / 1_000         ' 80_000_000/1000 is equal to 1 ms           
             
    

    what can the problem from ?
    thanks in advance.
  • Laserist1984Laserist1984 Posts: 9
    edited 2009-11-04 10:23
    hello,
    please can someone tell me where the problem in the code mentioned above?
    thanks
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-04 11:02
    PUB start
      dira[noparse][[/noparse]LED_CONTROL]~~ 'set LED control port to output
          
      WaitCnt( clkfreq + Cnt)
      ' if does not wait until pin is high, it just checks. And if statement is true, it executes the correctly indented code 
      [s][color=red]if ina[noparse][[/noparse]Y_INDEXPULSE]>0[/color][/s]
      [color=green]waitpeq( 1<<Y_INDEXPULSE, 1<<Y_INDEXPULSE, 0 )[/color]
    [color=#008000]  ' indentation ... only code correctly indented is repeated[/color]
      repeat   
          outa[noparse][[/noparse]LED_CONTROL]~~             ' turn LED on
          WaitCnt(MicroSecond * 260 + Cnt)  ' LED on 260 microsecond
          outa[noparse][[/noparse]LED_CONTROL]~                ' turn LED off
          waitcnt( long[noparse][[/noparse]@waittime] + cnt )     ' wait 10 millisecond
          
           
    DAT
    MicroSecond long 80
    waittime long 80_000_000 * 10 / 1_000         ' 80_000_000/1000 is equal to 1 ms  
    
    

    Please note: Indentation is very important in SPIN. It replaces characters marking blocks as known in other programming languages. ( in C { 'do something } is a block·)

    This will only wait for a pulse on Y_INDEXPULSE and then repeat forever. If you want it only to run if the input is high you need to change it a bit:

    PUB start
      dira[noparse][[/noparse]LED_CONTROL]~~ 'set LED control port to output
          
      WaitCnt( clkfreq + Cnt)
     
      repeat
        [color=blue]waitpeq( 1<<Y_INDEXPULSE, 1<<Y_INDEXPULSE, 0 )[/color]
        repeat while ina[noparse][[/noparse]Y_INDEXPULSE]    ' the >0 only eats up runtime. Every number that is not 0 will keep the loop running
          outa[noparse][[/noparse]LED_CONTROL]~~             ' turn LED on
          WaitCnt(MicroSecond * 260 + Cnt)  ' LED on 260 microsecond
          outa[noparse][[/noparse]LED_CONTROL]~                ' turn LED off
          waitcnt( long[noparse][[/noparse]@waittime] + cnt )     ' wait 10 millisecond
          
           
    DAT
    MicroSecond long 80
    waittime long 80_000_000 * 10 / 1_000         ' 80_000_000/1000 is equal to 1 ms  
    
    
  • mparkmpark Posts: 1,305
    edited 2009-11-04 12:54
    MagIO2 said...
          waitcnt( long[noparse][[/noparse]@waittime] + cnt )     ' wait 10 millisecond 
    
    


    Hey MagIO2, why not just
          waitcnt( waittime + cnt )     ' wait 10 millisecond 
    
    


    ?

    Also, earlier you suggested
    waitcnt( long[noparse][[/noparse]@waittimes+counter] + cnt )
    but that won't work unless counter is a multiple of four. Just use
    waitcnt( waittimes[noparse][[/noparse]counter] + cnt )
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-04 15:21
    Hi mpark ...

    thanks for the comments.

    I simply did not recheck that waitcnt-line, so it missed the evolution.
    About the long: These things happen if you don't test the code before posting. I'm guilty for that.
Sign In or Register to comment.