Shop OBEX P1 Docs P2 Docs Learn Events
Loop control — Parallax Forums

Loop control

JOSHTJOSHT Posts: 8
edited 2011-12-05 19:34 in Propeller 1
Hello, I am new to the forum and Also new to spin language. I am having some problems with loops I am trying to create. I have had some luck with them. But I still cannot get this one to works. I am trying to make an LED turn on and then I want to press a button 10 and after the tenth press have the button turn off. Here is some of the code I have written. It doesn't work. I have tried a few different ways and no such luck. Any help would be greatly appreciated.
Thanks,
-Josh

CON
_CLKMODE=XTAL1 + PLL2X
_XINFREQ = 5_000_000

INPUT_PIN =23
INV_HIGH =0
INV_LOW =1
WAITPERIOD =5_000_000
LED0 =2


VAR
LONG X

PUB GO0
DIRA [LED0]~~
OUTA [LED0]~~
DIRA [INPUT_PIN]~

REPEAT
TURNON_LED0
WAIT
WHILE X=>10
TURNOFF_LED0
WAIT
IF INA[INPUT_PIN]==0
X++

PRI TURNON_LED0
OUTA[LED0] :=INV_HIGH

PRI TURNOFF_LED0
OUTA[LED0] :=INV_LOW

PRI WAIT
WAITCNT(WAITPERIOD + CNT)

Comments

  • lardomlardom Posts: 1,659
    edited 2011-11-26 15:51
    VAR
         byte  index
    
           
            'button = 23
            'LED = 2
    
    PUB TenBtnPrses
    
        dira[2]~~
        outa[2]~
        dira[23]~~   
        
        outa[2] := 0
        repeat until ina[23]
        outa[2] := 1
        repeat index while ina [23] < 11
            index++
        outa[2] := 0
    

    I haven't tested it but it should work. I'm not sure if the button [23] should be declared input or output.
  • JOSHTJOSHT Posts: 8
    edited 2011-11-26 17:19
    Hey, thanks for the help. I'm getting an error. I will try and see if I can figure it out. Haven't been able to yet though.
    Thanks,
    -Josh
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-26 18:00
    Josh,

    Your going to want to keep track of the previous button state so you can count how many times the old state was unpressed and the new state is pressed.

    I think Larry's code will turn off the LED if the button if just held down.

    I've got some work to do right now. If you haven't got this figured out by the time I'm done with my work, I'll try to help some more. (I may be tomorrow.)

    BTW, welcome to the forum and the wonderful world of Propellers.

    It will help others help you if you learn how to post code in the forum. Follow this link.

    attachment.php?attachmentid=78421&d=1297987572
  • lardomlardom Posts: 1,659
    edited 2011-11-26 19:41
    Duane Degn, you are absolutely right. My 'index++' loop would turn the LED off faster than you could blink.

    [HTML]
    VAR byte index



    PUB TnBtnPrsses

    dira[2] := 1
    dira[23] := 1
    outa[2] := 0

    repeat 10
    repeat while ina[23]
    index++
    outa[2] := 1
    outa[2] := 0[/HTML]

    I modified the statement a bit. It compiles but it is still untested. I'm a student too.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-26 19:48
    Hey Larry, I tried your code but it didn't compile.
    EDIT: You posted while I was typing. I haven't tried your second code. My guess is it wouldn't work they why you're hoping. It would also turn off the LED too fast. (You also make the button an output instead of an input.)

    2nd EDIT: Josh, is your button normally high? The code I posted below assumes so. If not, change the "== 0" to "== 1" and change "oldState := 1" to "oldState := 0".

    I came up with some code but Josh, don't look at it yet.

    Try to come up with some working code with these clues.
    VAR
      LONG X, oldState, newState
    

    Keep track of the oldState of the button. Compare it with the new state to see if they are different (you've either pressed or released the button).

    If it's different check to see it the button has just been pressed (and not just released).

    If the button has just been pressed increment your counter (X).

    Start your loop with repeat. At the bottom of the loop use:
    WHILE X < 10
    

    Oh, you don't need the method "WAIT".

    Good luck.


    Not stop reading and start programming!


    .

    .

    .

    .

    .

    (Back of the book answer.)


    CON
      _CLKMODE=XTAL1 + PLL2X
      _XINFREQ = 5_000_000
       
      INPUT_PIN =23 
      INV_HIGH =0
      INV_LOW =1
      WAITPERIOD =5_000_000
      LED0 =2
    
    VAR
      LONG X, oldState, newState
    PUB GO0
      DIRA [LED0]~~
      OUTA [LED0]~~
      DIRA [INPUT_PIN]~
      oldState := 1 ' button not pressed
      
      TURNON_LED0 
      REPEAT
        newState := INA[INPUT_PIN]
        if newState <> oldState
          if newState == 0
            X++
          oldState := newState
         
      WHILE X < 10
      TURNOFF_LED0
      REPEAT ' keep program alive
    PRI TURNON_LED0
      OUTA[LED0] :=INV_HIGH
    PRI TURNOFF_LED0
      OUTA[LED0] :=INV_LOW
    PRI WAIT
      WAITCNT(WAITPERIOD + CNT) 
    
  • lardomlardom Posts: 1,659
    edited 2011-11-26 20:04
    I looked at my code again and realized the LED would not turn with the first button press. Well Josh, even when you get it wrong it's still fun working on it!
  • lardomlardom Posts: 1,659
    edited 2011-11-27 06:02
    Duane Degn, I did a test with 'Hyperterminal' and couldn't change "ina[23]" to zero. Otherwise "pin[2]" does what I want it to. I uploaded the file if you wouldn't mind taking a look.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-27 09:06
    Larry,

    I like this program. I only get 8 presses before the LED turns off. I think it's because:
    repeat while ina[23]              ' ina[23] is always 1! Why?
       outa[2] := 1
       repeat 9
          repeat while ina[23]
    
    The first time the button is pressed you start the loop. Since it is likely the button will still be pressed when the loop starts the second "repeat while" statement doesn't delay the program. If you add another half second delay prior to the "repeat 9" statement, you'll have time to lift your finger off the button.

    The button you're using is normally high? And a press grounds the button?

    I think if you add the delay and change the repeat from 9 to 10, then it will work they way you'd like it to.

    I personally don't like a Propeller program to completely end. I usually add a repeat at the end to keep the cog active. I think this is just because it's what I've seen other's on the forum do. Often a LED is supposed to be left on (I think I see more test programs that turn a LED on when a condition is met than programs that turn off a LED) and without a final repeat you wouldn't know the program had worked properly.

    I agree with you. This is fun stuff.
  • lardomlardom Posts: 1,659
    edited 2011-11-27 09:46
    I have to confess. I didn't wire the LED/button circuit since I have my breadboard set up for another project. I wanted to test my logic so I used Hyperterminal. Josht needs the practice so the best approach may be just to join the conversation and help where needed.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-27 10:29
    lardom wrote: »
    I have my breadboard set up for another project.

    Ah, yes. I used to have the problem. I finally ordered ten of these and made a little Propeller board with power supply that was easy to transfer from breadboard to breadboard.

    Your program needs a button to break out of the "repeat while" loops. Since you're using a terminal program you could change:
    repeat while ina[23]
    


    to:
    repeat while pst.rxcheck == -1
    

    Oh good, HyperTerminal's rxcheck is public. The rxcheck method in Parallax Serial Terminal is private. (Why in the world did Parallax make it private?)

    Just a second. I want to test this to make sure it works. Okay, it works. So now you should be able to try it without a button.



    My many breadboards came in handy this last Monday. I taught nine Cub Scouts how to wire up a ciruit on the boards with a wire, a resistor and a LED. I had enough breadboards so each Cub Scout could use one. It was fun to see how excited they got when their LED was finally lit.

    @Josh, Are you still with us? How goes the programming? Fun stuff, right? Keep the questions coming.
  • lardomlardom Posts: 1,659
    edited 2011-11-27 12:20
    Thanks. :smile: Are you teaching them to program in Spin?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-28 10:31
    lardom wrote: »
    Thanks. :smile: Are you teaching them to program in Spin?

    I'd like to, but there isn't enough time in the "Pack Activity" to do so. I'm not sure if all the boys are interested robots enough to want to learn to program.

    I might have a mini robot school at my house on a couple of Saturdays each month. This way, the kids who are interested, could learn more if they want.
  • JOSHTJOSHT Posts: 8
    edited 2011-12-05 19:34
    Thanks a lot guys. I didn't get to try it out until just now, its been a crazy month. Works great. Had to reverse the turn on LED and turn off LED protocols and the switch states because my inputs and outputs are buffered. But it is awesome. Thanks you all so much. Here is my final version in case anyone is interested.
    CON
      _CLKMODE=XTAL1 + PLL2X
      _XINFREQ = 5_000_000
       
      INPUT_PIN =23 
      INV_HIGH =0
      INV_LOW =1
      WAITPERIOD =5_000_000
      LED0 =2
    
    VAR
      LONG X, oldState, newState
    PUB GO0
      DIRA [LED0]~~
      OUTA [LED0]~~
      DIRA [INPUT_PIN]~
      oldState := 0 ' button not pressed
      
      TURNOFF_LED0 
      REPEAT
        newState := INA[INPUT_PIN]
        if newState <> oldState
          if newState == 1
            X++
          oldState := newState
         
      WHILE X < 10
      TURNON_LED0
      REPEAT ' keep program alive
    PRI TURNON_LED0
      OUTA[LED0] :=INV_HIGH
    PRI TURNOFF_LED0
      OUTA[LED0] :=INV_LOW
    PRI WAIT
      WAITCNT(WAITPERIOD + CNT)
    
    
Sign In or Register to comment.