Shop OBEX P1 Docs P2 Docs Learn Events
Stupid Newbie Question — Parallax Forums

Stupid Newbie Question

SteveWoodroughSteveWoodrough Posts: 190
edited 2009-05-01 02:55 in Propeller 1

I'm working my way slowly through my PE kit and thought I would try to do a little off road coding. One of the spin programs in the manual·lights a set of LED's in sequence. I decided to see if I could reverse the LED sequence to make the lights "bounce" from one end of the array to the other. I did it (see attached SPIN) but not in a very elegant fashion. I'd be interested in feedback on ways to write this better.

Thanks

Steve Woodrough

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Recent Project Videos:

http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

Comments

  • James LongJames Long Posts: 1,181
    edited 2009-04-27 02:44
    Steve,

    I do not believe there is a stupid newbie question. We all learn at a different pace, and we all start from knowing nothing (at some point).

    Your question is a double edge sword. There are really hundreds of ways to do what you did, "better" depends on who is critiquing, and how deep you want to get.

    Just to give you some ideas of different ways of doing the same thing (ok, almost the same thing):
    
    Var
    
    byte pin
    
    PUB ShiftLedsLeft
    
        dira[noparse][[/noparse]9..4] ~~
        pin := 4
        repeat
          repeat while pin =< 9     
           outa[noparse][[/noparse]pin]~~
           waitcnt(clkfreq/10 + cnt)
           outa[noparse][[/noparse]pin]~
           pin +=1
          repeat while pin => 4
           outa[noparse][[/noparse]pin]~~
           waitcnt(clkfreq/10 + cnt)
           outa[noparse][[/noparse]pin]~
           pin -=1
    
    
    



    Although I didn't try it, this should work.

    James L

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    James L
    Partner/Designer

    Lil Brother SMT Assembly Services
  • James LongJames Long Posts: 1,181
    edited 2009-04-27 02:50
    Just as a secondary note, I didn't use shift at all, although that could have been done as well. (shift left, and shift right).

    Maybe I should have read more carefully.

    But like I said, there are hundreds of ways to do the same thing.

    James L

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    James L
    Partner/Designer

    Lil Brother SMT Assembly Services
  • simonlsimonl Posts: 866
    edited 2009-04-27 12:07
    @Steve: Welcome aboard! Funny thing that - I started the same way smile.gif Here's the code I came-up with. Enjoy!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again wink.gif
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-27 13:20
    Well ... the coding also depends on what your goal is. Coding things in one way might be good for one case whereas coding it another way is better for other cases. For example you can do speed optimization or memory usage optimization.

    What you did can't be done much better when you want a general shifter which lives with any state the outa has when called.
    Maybe you could use some boolean algebra and use some operators to do the same thing without an explicit if statement:
    outa[noparse][[/noparse]9..4]:= ( (outa[noparse][[/noparse]9..4]<<1) & %111111) #> 1

    outa[noparse][[/noparse]9..4]<<1 first shifts
    an & on the result of the shift with %111111 simply allows the 1 to be within the range we use for LEDs. If it's outside the result will be 0.
    #> 1 limits the minimum, so the value we write back to outa[noparse][[/noparse]9..4] is not allowed to smaller than 1. 2 #> 1 returns 2 whereas 0 #> 1 returns 1

    This solution looks a bit more like 'you really know what you do' ;o) but I my guess is that the operation itself is slower than using the if-version.

    But to be honest, I don't know how your LED should bounce with that code? It's an endless loop, so light comes in from the right and leaves at the left.
  • James LongJames Long Posts: 1,181
    edited 2009-04-27 17:26
    MagIO2 said...
    Well ... the coding also depends on what your goal is. Coding things in one way might be good for one case whereas coding it another way is better for other cases. For example you can do speed optimization or memory usage optimization.

    What you did can't be done much better when you want a general shifter which lives with any state the outa has when called.
    Maybe you could use some boolean algebra and use some operators to do the same thing without an explicit if statement:
    outa[noparse][[/noparse]9..4]:= ( (outa[noparse][[/noparse]9..4]<<1) & %111111) #> 1

    outa[noparse][[/noparse]9..4]<<1 first shifts
    an & on the result of the shift with %111111 simply allows the 1 to be within the range we use for LEDs. If it's outside the result will be 0.
    #> 1 limits the minimum, so the value we write back to outa[noparse][[/noparse]9..4] is not allowed to smaller than 1. 2 #> 1 returns 2 whereas 0 #> 1 returns 1

    This solution looks a bit more like 'you really know what you do' ;o) but I my guess is that the operation itself is slower than using the if-version.

    But to be honest, I don't know how your LED should bounce with that code? It's an endless loop, so light comes in from the right and leaves at the left.

    You have to excuse Mag, he sometimes get way too deep and thorough.

    Mag, ease up on the guy, your gonna make his head pop.


    Truthfully, you did ask, and while some of this code is probably way over your experience level, they are all good examples of what can be done.

    I figure after all those examples, you are continuing to read and do other lessons.

    Also, just for information, not all of the code that was posted uses LED 4-9.

    James L

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    James L
    Partner/Designer

    Lil Brother SMT Assembly Services
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2009-04-29 03:36
    Thank you all for your input.· I appreciate all the feedback from you guys who are higher up on the mountain, I'm so far "back down the trail" I can still see my car!

    Posting questions on the forum is no substitute for RTFM'ng so I will continue with my studies. However, I have a few more questions.·
    What is the difference between:··· :=· and ==?

    Oop's!· I just realized that the sample code (Junk.spin)·I posted earlier was not anything like what I thought I posted.· Below is what I meant to post. ·My apologies in advance for not using the attachment manager.·

    The net effect of this routine is very simple.· The LED light bounces from 4-9 and back from 9 to 4.· What I do not like is the repeat 6 command.· It seemed to be a very brute force method.·

    I found that I could replace: if outa[noparse][[/noparse]9..4] == 0·with if outa[noparse][[/noparse]9..4] == %000000 in the first line of both repeat loops and the routine worked just fine.· (if outa[noparse][[/noparse]9..4] := %000000 DOES NOT work) Why?

    For the second repeat loop (LED sequnce 9,8,7,6,5,4) I wanted to replace the:
    if outa[noparse][[/noparse]9..4] == %000000 with if outa[noparse][[/noparse]9..4] == %100000 but the LED's only light in sequence 4,5,6,7,8,9 (first loop).· My obviously flawed logic was to try to identify the end of the first sequence (4-9) by waiting until only LED 9 is lit.· It does not work that way...Why?

    If someone could shed a little light on this I would appreciate it.

    Just for grins I tried an elseif outa[noparse][[/noparse]9..4] == %100000 and I get a compile error (expect variable)· Why? So clearly I'm in over my head and need to get back to Reading The Full Manual...

    Thanks for taking the time,
    Steve

    PUB ShiftLedsLeft
    ··· dira[noparse][[/noparse]9..4] ~~
    repeat················································· 'endless loop
    ··· repeat· 6·········································· 'Repeat loop 6 times
    ······
    ······ if outa[noparse][[/noparse]9..4] == 0······························ 'If LEDs off
    ········· outa[noparse][[/noparse]9..4] := %000001························ 'Set Output 4 high
    ·····
    ······ outa[noparse][[/noparse]9..4] <<= 1································ 'Shift output right 1 pin each loop
    ······ waitcnt(clkfreq/20 + cnt)······················· 'wait 1/20th second
    ··· repeat· 6·········································· 'Repeat loop 6 times
    ············································································
    ······ if outa[noparse][[/noparse]9..4] == 0······························ 'If LEDs off········
    ········· outa[noparse][[/noparse]9..4] := %100000························ 'Set Output 9 high··
    ······
    ······ outa[noparse][[/noparse]9..4] >>= 1································ 'Shift output left 1 pin each loop
    ······ waitcnt(clkfreq/20 + cnt)······················· 'wait 1/20th second




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • SRLMSRLM Posts: 5,045
    edited 2009-04-29 03:44
    := is an assignment operator (assign the value on the right to the variable on the left)
    == is a boolean operator. If both sides are equal, then it evaluates to true.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-29 05:54
    Hmmm ... what's the purpose of this code? Can you set the LED somewhere outside and ShiftLEDs has to take what it finds and shift it? Or is ShiftLEDs allowed to start from scratch? That would make things easier for a newbie that can even see the ants under the car ;o)

    PUB ShiftLedsLeft
        dira[noparse][[/noparse]9..4] ~~
        [color=red]outa[noparse][[/noparse]9..4] := %000001[/color]
    [color=#ff0000]    ' do the initialization here and you don't need any if in your loops if you use the right repeat count[/color]
    repeat                                                  'endless loop
        repeat  [color=orange]5[/color][s]6[/s]                                           'Repeat loop 6 times
           
    [s]       if outa[noparse][[/noparse]9..4] == 0                               'If LEDs off
              outa[noparse][[/noparse]9..4] := %000001                         'Set Output 4 high
    [/s]      
           outa[noparse][[/noparse]9..4] <<= 1                                 'Shift output right 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
        repeat  [color=red]5[/color][s]6[/s]                                           'Repeat loop 6 times 
                                                                                 
    [s]       if outa[noparse][[/noparse]9..4] == 0                               'If LEDs off         
              outa[noparse][[/noparse]9..4] := %100000                         'Set Output 9 high   
    [/s]       
           outa[noparse][[/noparse]9..4] >>= 1                                 'Shift output left 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
    
    

    In this code you simply don't shift the 1 out of the bits you use. You have 6 bits, so, if bit 4 is set you know that you can shift it 5 times to the left - if bit 9 is set, you can shift it 5 times to the right.

    If some other code is setting the bit and you want to shift it from exactly that position, then I'd do it like that:
    PUB ShiftLedsLeft
        [color=orange][s]dira[noparse][[/noparse]9..4] ~~[/s][/color]
    [color=#ffa500]    ' not needed, as the other code should have set the direction already[/color]
    repeat                                                  'endless loop
        repeat [color=red]until outa[noparse][[/noparse]9..4] & %000001[/color]
    [color=#ff0000]           ' this ends the loop as soon as the 1 reached bit 4[/color]       
    [s]       if outa[noparse][[/noparse]9..4] == 0                               'If LEDs off
              outa[noparse][[/noparse]9..4] := %000001                         'Set Output 4 high
    [/s]      
           outa[noparse][[/noparse]9..4] <<= 1                                 'Shift output right 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
    
        repeat  [color=orange]until outa[noparse][[/noparse]9..4] & %100000[/color]
    [color=orange]            ' this ends the loop as soon as the 1 reached bit 9[/color]                                                                             
    [s]       if outa[noparse][[/noparse]9..4] == 0                               'If LEDs off         
              outa[noparse][[/noparse]9..4] := %100000                         'Set Output 9 high   
    [/s]       
           outa[noparse][[/noparse]9..4] >>= 1                                 'Shift output left 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
    
    

    In this version you could even set 2 or 3 LEDs anywhere you want and it will bounce all the bits.

    EDIT:
    Ok ... now I see a little difference to what your code is doing. You really shift the bit out of sight, so for 1/20 of a second no LED is switched·on at all. Is this what you want? Is your version even doing what you want?
    The "if" lights LED 4 or LED 9, but just a few microseconds later it's already being shifted to the next position instead of staying for 1/20s.

    So, let's modify my first change a bit and it will shift the bit out of sight as well and behave very much like your version.
    PUB ShiftLedsLeft
        dira[noparse][[/noparse]9..4] ~~
    repeat                                                  'endless loop
        [color=blue]outa[noparse][[/noparse]9..4] := %000001[/color]
    [color=#0000ff]    ' waitcnt(clkfreq/20+cnt) if you want it to light for 1/20s as well[/color]
        repeat  6                                           'Repeat loop 6 times
           outa[noparse][[/noparse]9..4] <<= 1                                 'Shift output right 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
     
        [color=blue]outa[noparse][[/noparse]9..4] := %100000[/color]
    [color=#0000ff]    ' waitcnt(clkfreq/20+cnt) if you want it to light for 1/20s as well[/color]
        repeat  6                                           'Repeat loop 6 times 
           outa[noparse][[/noparse]9..4] >>= 1                                 'Shift output left 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
    
    



    Post Edited (MagIO2) : 4/29/2009 8:05:02 AM GMT
  • Toby SeckshundToby Seckshund Posts: 2,027
    edited 2009-04-29 06:58
    Steve,

    I am treading the same path, there are so many folk here that have vast experience that it is eay to tag on to the code that they pour out leaving you ignorant of the little things that are very, very important. I have started to read throungh the PE tutorial so I can cut down on the "stupid" mistakes. I still have problems with the parrallel processing, I have spent decades in linear-with-interupts land.
  • James LongJames Long Posts: 1,181
    edited 2009-04-29 07:35
    SRLM said...
    := is an assignment operator (assign the value on the right to the variable on the left)
    == is a boolean operator. If both sides are equal, then it evaluates to true.

    To break this down in a different way (not that SRLM's is incorrect)

    ":=" means - to make equal to.

    "==" means - if equal to.

    When I started those would confuse me, even after someone told me about assignment, and boolean.

    I'm not sure when the Constant assignment phase starts in the lessons, but it makes your life much easier when it does. That way you can name a constant something that makes sense, and stop using literals (the actual value).

    Just for basic information and getting help, the code tags are your friend. If you post code in the forum without the code tags, the forum software will reformat the code. Then we will not know if you indented correctly. Spin is indention sensitive, so always put any spin code between code tags. With short objects as yours it is usually easier to jut post the code. When the programs get bigger members do like you to attach the zip(archive) of your code. It saves having to scroll through 400 lines of code. Your code is not big enough to attach as of yet, so it is probably easier to just put it between the code tags.

    (code) (/code) <
    you must replace the "(" with "[noparse][[/noparse]".

    Code tags will give you this
    [noparse][[/noparse]code] <-----this will be invisible in most cases
    



    Don't get discouraged. If you hit a problem, just post the code. This is the best way to learn, trust me. Mag has been helping me with assembly for the propeller lately, and he is good with it. I've been using the propeller since it came out, and just now do I feel somewhat comfortable learning assembly. It's is a personal thing though.

    Keep asking questions. It is the best way to learn.

    Mag, I haven't had time to do the binary search, I just finished the assembly from hates.

    James L

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    James L
    Partner/Designer

    Lil Brother SMT Assembly Services

    Post Edited (James Long) : 4/29/2009 8:06:22 AM GMT
  • James LongJames Long Posts: 1,181
    edited 2009-04-29 07:47
    SteveWoodrough said...

    For the second repeat loop (LED sequnce 9,8,7,6,5,4) I wanted to replace the:

    if outa[noparse][[/noparse]9..4] == %000000 with if outa[noparse][[/noparse]9..4] == %100000 but the LED's only light in sequence 4,5,6,7,8,9 (first loop). My obviously flawed logic was to try to identify the end of the first sequence (4-9) by waiting until only LED 9 is lit. It does not work that way...Why?

    I'll explain this further, just in case Mag's explanation didn't drop the anchor.

    The reason it doesn't work....... when the first loop finishes (repeated 6 times), there was no %100000 left (only %000000). You had shifted so far, the one (1) had scrolled off and was lost. You have 6 places, but the first is already at one, that means if you shift 6 times, you have shifted one time too many.

    If you had used
    repeat 5 
    
    



    It would have worked. Mag says this, just in a different way.

    The elseif problem is unknown. We would need to see how you intended to use it (your code with it).

    James L

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    James L
    Partner/Designer

    Lil Brother SMT Assembly Services
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2009-04-30 04:10
    @MagIO2 Thank you. I liked the second version but I found I needed to reverse the end states to get it to work. You all don't give the new guy much of a break! smile.gif
    @James Long Thank you for your help as well. I now have a post it note on my project box that says:
    ":=" means - to make equal to. "==" means - if equal to. I take it then that := is more like a traditional Pbasic = so that x=3145 is expressed as x :=3145 and that == is used for logic type statements such as if x == 3145 then y := (?) 5.

    What is the & in:
    repeat until outa[noparse][[/noparse]9..4] & %000001

    Is there a table in the prop manual that lists all these operators?

    PUB ShiftLedsLeft
        dira[noparse][[/noparse]9..4] ~~     ' not needed, as the other code should have set the direction already
        outa[noparse][[/noparse]9..4] := %000100      'some initial condition
    repeat                                                  'endless loop
        repeat until outa[noparse][[/noparse]9..4] & %100000
               ' this ends the loop as soon as the 1 reached bit 4
          
           outa[noparse][[/noparse]9..4] <<= 1                                 'Shift output right 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
    
        repeat  until outa[noparse][[/noparse]9..4] & %000001
                ' this ends the loop as soon as the 1 reached bit 9
           
           outa[noparse][[/noparse]9..4] >>= 1                                 'Shift output left 1 pin each loop
           waitcnt(clkfreq/20 + cnt)                        'wait 1/20th second
    





    smile.gifshocked.gifshocked.gifsmile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
  • SRLMSRLM Posts: 5,045
    edited 2009-04-30 04:17
    Propeller Tool -> Help -> Quick reference

    So that's a bitwise AND: it's the output register with the mask, and will keep repeating going until the 4 bit is 1.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-30 07:15
    @Steve:

    Ah ... ehm ... this was only a hidden test, now I'm sure you understood ;o))

    How the·until works in this case is: until expects a boolean value. Only 0·has the meaning of·false any other value is·like a·true. Until loops ... well .. until the boolean expression is true. So, when the output bit is exactly at the position given in the bitmask, the value will be true and the until stopps.

    Post Edited (MagIO2) : 4/30/2009 7:22:10 AM GMT
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2009-05-01 02:55
    @SRLM Thanks, that is a good tip. I did not know the reference was so close..

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Recent Project Videos:

    http://www.youtube.com/watch?v=jI79Xsm_Kyk&feature=channel_page

    Cool Cars:
    http://www.youtube.com/watch?v=SLnPhYKZCqo&feature=channel_page
    http://www.youtube.com/watch?v=d2xGkYN4v7g&feature=channel_page
Sign In or Register to comment.