Shop OBEX P1 Docs P2 Docs Learn Events
LED PBASIC problem — Parallax Forums

LED PBASIC problem

hp16hp16 Posts: 11
edited 2013-10-19 21:47 in General Discussion
Hello, I'm new to this, I'm trying to learn PBASIC right now to do basic commands like: turn on LED, turn it off, etc.

I was working on a command on which, with the push of a button, will turn an LED on for 10 seconds, if I push the button again, while the LED is still on, it will blink for 10 seconds at a rate of one per second (on for .5 seconds, off for .5 seconds). But if the button is pressed again before the LED blinks 10 times it will stay on for 10 seconds. This is what I had so far but according to my professor, I'm wrong:

counter VAR Byte

For counter = 1 to 10

DEBUG ? counter

IF (IN3=1) THEN
HIGH 14
PAUSE 500
LOW 14
PAUSE 500

NEXT


ELSE

HIGH 14
PAUSE 1000


NEXT


DEBUG "All Done"


END

Comments

  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-11 11:28
    Your Professor is correct. I do not think since this is a school assignment anyone will give you the out right answer. I am assuming your LED stays on and when button is pressed it blinks, correct?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-11 11:39
    There are several different ways to accomplish the task assigned by your professor.

    It's hard to know how much help would be appropriate to offer on a school assignment.

    I will suggest you should make sure the button has been released before you start looking to see if it has been pressed again. Otherwise you wont know if you are detecting a new button press or if the first press was just held down for awhile.

    There's a link in post #3 of my index (see my signature) to a tutorial on how to post code to the forum. It will be easier to help you if you use the code tags mentioned in the tutorial.

    Give the code another go and post what you have and what it does and I bet someone around here will offer another hint (if you still need one).

    BTW, Welcome to the forums.
  • ercoerco Posts: 20,256
    edited 2013-10-11 12:26
    +1, Welcome to the forums.

    In a nutshell, you can't use pause statements. Instead, you must make some timed loops (either a half second or ten seconds) to continuously look at your pushbutton to decide what to do while the LED is doing its thing. In essence, you'll have three seperate loops within your program. First is LED off, looking for a button press. Second is blinking the LED for 10 secs while looking for a button press, and the third is LED on for ten seconds while looking for a button press.

    Hopefully you have a Stamp you can experiment with "live", because until you achieve a certain amount of proficiency, writing code "blind" (without constant testing) is quite difficult.
  • GenetixGenetix Posts: 1,754
    edited 2013-10-11 13:38
    One way to do this is by using what is called a State Machine. The state will change each time the button is pressed or an action completes. The actions will depend on the current state.
  • hp16hp16 Posts: 11
    edited 2013-10-12 18:05
    Hello and thanks for the welcome. I'm not here to get the answer, I'm here to learn. My professor basically said we have to code this but hasn't taught much on the subject and I'm stuck. He just gave us part of the pseudo code in class but I don't know how to finish it, it doesn't make sense to me. Remember that the problem asks me to construct a code that will make an LED turn on for 10 seconds, IF the button is pressed the LED will flash 10 times at a rate of 1 per second (.5 sec on, .5 sec off). IF the button is pressed again before the LED blinks 10 times the LED will be on for 10 seconds without blinking again. My professor's pseudo code (see below) for this doesn't make sense for me, though. On the "For counter" part it says from 1 to 200 milliseconds. Shouldn't it be from 1 to 10 seconds? I don't get it.

    Then how am I going to press the button again if there's only two choices for the button: button on, button off.

    If anyone can guide me to a tutorial or something about LEDs and buttons I'll be very grateful. I have to turn this in on Tuesday and I have no idea what I'm doing.



    DO

    IF button pressed THEN
    turn on LED
    For counter 1 to 200 ms
    wait 50 ms

    IF button pressed
    (blink)

    ELSE button not pressed
    wait 50 ms

    END LOOP
  • NWCCTVNWCCTV Posts: 3,629
    edited 2013-10-12 18:51
    OK. If you have a Basic Stamp related MCU the What's A Microcontroller Text is available here to download. There is a lot of info pertaining to LED's and all the various commands. It is quite a bit of reading but you should be able to figure out what you need with it. If you get stuck post your code using the code brackets as it is easier for all to view and try to help out. In some browsers you have to click the Go Advanced tab to see the code bracket selection. Also, re read the posts in this thread and you should be able to get it. If not, as long as you are trying we will all try to help you out.
    Code goes in here.
    
  • Mike GreenMike Green Posts: 23,101
    edited 2013-10-12 18:51
    The general problem is that you need to keep time using a microcontroller with limited timekeeping ability. The main time reference is the PAUSE statement. How can you use that to do things at specific times or time intervals? Let's say you want to keep track of the time in 1/10th second units and in minutes, then you want to test an I/O pin and do something if it's low for up to one second.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    timeSec10 var word  ' time in 1/10ths of a second
    timeMin var word  ' time in minutes
    timeCntr var byte  ' temporary time counter
    testPin pin 1  ' I/O pin to be checked
    
    timeMin = 0
    timeCntr = 0
    
    do  ' main loop
       timeSec10 = 0   ' start over counting 1/10s of a second
       do  ' each loop takes around a 1/10th of a second
          if testPin = 0 then   ' I/O pin is low?
             if timeCntr = 0 then   ' I/O pin just turned low
                ' here you might turn something on
             endif
             if timeCntr = 10 then   ' I/O pin has been low for a second
                ' here you would turn something off
             endif
             timeCntr = timeCntr + 1   ' increment counter
          else
             timeCntr = 0   ' I/O pin not low, reset counter
             ' you also need to turn off the something here
          endif
          pause 100   ' this is what sets most of the time "tick"
          timeSec10 = timeSec10 + 1
       loop while timeSec10 < 600
       timeMin = timeMin + 1
    loop
    
    The amount of time it takes to execute the code other than the pause can take several milliseconds, so you will have to calibrate the program. You'll have to use an accurate clock to measure the actual time it takes to count timeMin up to, say, 30 minutes and decrease the pause time enough to make the 30 minute time work out properly.

    Something to think about ... What happens when testPin is low for more than about 25 seconds? If that's not the behavior you want, how would you fix it?
  • hp16hp16 Posts: 11
    edited 2013-10-12 21:49
    ok, I'm gonna try to solve this without using pseudo code, please correct me if I'm wrong on something. I know that most likely I am wrong.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    counter VAR byte
    
    DO
    
    IF (IN3 = 1) THEN
    
    HIGH 14
    FOR counter 1 to 200
    PAUSE 50
    
    {IF (IN3 = 1) THEN
    
    FOR 1 to 10
    
    PAUSE 50
    
    DEBUG ? counter
    
    
    HIGH 14
    PAUSE 500
    LOW 14
    PAUSE 500
    
    NEXT }
    
    ELSE (IN3=0)
    
    PAUSE 50
    
    LOOP
    
    END LOOP
    
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-12 22:08
    Do you have a Basic Stamp to test your code on? If not, this is going to be extra difficult.
  • hp16hp16 Posts: 11
    edited 2013-10-12 22:13
    I have Basic Stamp Editor but I don't have a way to test it. The Basic Stamp 2 that I connect it to is at school
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-12 22:25
    hp16 wrote: »
    I have Basic Stamp Editor but I don't have a way to test it. The Basic Stamp 2 that I connect it to is at school

    Well, that kind of takes the fun out of it. Darn.

    Learning this stuff is fun if you can see the effect on the output caused by small changes to the code. Trying to come up with code without being able to test small sections just isn't nearly as much fun.
  • ercoerco Posts: 20,256
    edited 2013-10-13 12:43
    hp16 wrote: »
    I have Basic Stamp Editor but I don't have a way to test it. The Basic Stamp 2 that I connect it to is at school

    Scour the Radio shacks near you to see if they have any of their clearance "Stamp Activity kits" . Just $10 or $15 for a NICE kit. Ridiculously cheap, includes a BS2 Homework Board.

    http://parallax.com/product/90005
  • GenetixGenetix Posts: 1,754
    edited 2013-10-13 17:36
    Are you sure that understand what you need to do because they way the present it and the pseudo code you provided don't agree? Chapter 2 of What's a Microcontroller (WAM) should how to blink LEDs and Chapter 3 shows how to use Pushbuttons. Look at the program from Mike Green as an example. Before you start writing code you need to work out the flow of your program. What turns the LED on? What happens when the LED is on? What happens when the LED is blinking? What happens at the end of any of these cycles? First, understand what needs to be done when and then you can create pseudo code and from there BS2 code. Several things I see already. In IF-THEN statements if you do more than one thing after the If-Then then you need to add ENDIF at the end. The same goes for an ELSE. If you press F7 while in the Stamp Editor it will point out some problems for you. FOR-NEXT doesn't use brackets, { }, so you don't need them. The DO-LOOP will continue forever and END and LOOP are 2 separate commands, so you don't need that either. It's good practice to indent the next lines after commands such as DO, FOR, and IF as in Mike's program. It makes the program easier to understand and read. You also see that Mike declared a PIN variable for the I/O pin that ha used. You can declare a variable, such as LED, for Pin 14 and another variable for your Button at Pin 3. Then you can use those Pin variables instead of numbers. It makes your program easier to read and modify. And finally you can add comments to your program by placing them after an apostrophe, ', as Mike has done. That should get you started and feel free to ask any questions about BS2 programming.
  • hp16hp16 Posts: 11
    edited 2013-10-14 00:13
    ok, so I finally went and bought a BS2 homework board, it cost me 50 dollars :blank: but it has helped me a little bit

    I've got this code but when I press the button it starts blinking first for 10 seconds and after blinking 10 seconds it stays on for 10 seconds. What am I doing wrong?
    DO
    
    
      IF(IN3 = 1) THEN
    
    
        FOR counter = 1 TO 200
        DEBUG ? counter
        HIGH 14
        PAUSE 50
    
    
    
    
        IF(IN3 = 1) THEN
          FOR counter = 1 TO 10
          DEBUG ? counter
          HIGH 14
          PAUSE 500
          LOW 14
          PAUSE 500
          NEXT
    
    
        ENDIF
        NEXT
    
    
    
    
    
    
      ELSE
    
    
        PAUSE 50
      ENDIF
    
    
    LOOP
    
  • GenetixGenetix Posts: 1,754
    edited 2013-10-14 01:38
    Your code looks a lot neater now but you should indent all those statements under that FOR including that IF statement.

    IF and ENDIF should align, FOR and NEXT should align, and your DO and LOOP are already aligned.
    DO
      IF(IN3 = 1) THEN
        FOR counter = 1 TO 200
          DEBUG ? counter
          HIGH 14
          PAUSE 50
          IF(IN3 = 1) THEN
            FOR counter = 1 TO 10
              DEBUG ? counter
              HIGH 14
              PAUSE 500
              LOW 14
              PAUSE 500
            NEXT
          ENDIF
        NEXT
      ELSE
        PAUSE 50
      ENDIF
    LOOP
    

    You now see everything that will run in the DO LOOP and first you have an IF that will turn on the light.

    This first IF needs and ENDIF to stop it since you have more than one statement under it.

    Then you have a FOR NEXT.
    You need to understand that the FOR NEXT will complete before anything else can happen.
    Is this what you want to happen?
    Look at how Mike did it.

    Also if you place a FOR NEXT inside of a FOR NEXT the inner FOR NEXT runs the number of times the outer FOR NEXT runs.
    Is this what you want to happen?

    You are getting there.
    Do you notice something about the time the LED should stay on or blink?
    Look again at Mike's program and what he does.
  • hp16hp16 Posts: 11
    edited 2013-10-16 01:58
    ok guys, so apparently I made a mistake. I had to use subroutines in my code and I didn't. I'll be posting my pseudo code later.
  • GenetixGenetix Posts: 1,754
    edited 2013-10-16 09:50
    Small programs don't require subroutines though it's good practice. It's good though that you see their value.
    More importantly though is do you understand what your program needs to do?

    Also, don't be afraid to ask questions if there is something that you don't understand.
  • hp16hp16 Posts: 11
    edited 2013-10-16 10:41
    I got the program working without subroutines but my professor wants to see subroutines in my code so I have no choice. Remember my program is supposed to stay on for 10 seconds when I click a button. If I click the button again while the LED is on it's supposed to blink 10 times at a rate of 1 per second. If I press the button again while its blinking it has to go back to staying on for 10 seconds. This has to go on on a loop. That way, if I keep pressing the button it's gonna do the same thing over and over again. I thought this was supposed to work already but it doesn't. I tried it and the LED just stays on for more than seconds or sometimes it just gives a quick half a second flash and the program stops. This is my code:

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    
    
    
    counter VAR Byte  'declaring my variable
    
    
    DEBUG ? IN3        'check if button has been pressed
    
    
    DO
    
    
    IF(IN3 = 1) THEN         'if I press the button here it's supposed to stay on for 10 seconds
    stayon:
    HIGH 14
    FOR counter = 1 TO 200
    DEBUG ? counter
    PAUSE 50                 'the reason I have pause 50 ms is because if I wait for a longer time and if I press the button while it's waiting my program is not going to work efficiently
    
    
      IF(IN3 = 1) THEN
      GOSUB blink           'this is my subroutine. it jumps to the code that is at the bottom
    
    
      ELSE
        END
      ENDIF
    NEXT
    
    
    ELSE
    LOW 14
    PAUSE 50
    ENDIF
    
    
    LOOP
    
    
    
    
    blink:             'this is the command where it's going to blink 10 times
    
    
    FOR counter = 1 TO 10
    DEBUG ? counter
      LOW 14
      FOR counter = 1 TO 10
      DEBUG ? counter
      PAUSE 50
      IF(IN3 = 1) THEN
        GOSUB stayon           'sends it back to stayon: if the button is pressed
    
    
      ELSE
        END
      ENDIF
      NEXT
      HIGH 14
      FOR counter = 1 TO 10
      DEBUG ? counter
      PAUSE 50
      IF(IN3 = 1) THEN
        GOSUB stayon           'sends it back to stayon: if the button is pressed
      ELSE
        END
      ENDIF
      NEXT
    NEXT
    
    
  • GenetixGenetix Posts: 1,754
    edited 2013-10-16 16:49
    The END command makes the BS2 stop running the program. Are you sure you want to stop your program?
    Also the logic of your program is still not correct. Did you notice that LED will be on or blink for the same amount of time? Perhaps you should be using the same timing loop for both conditions.
    And how does your program know whether the LED is blinking or steady? What if someone kept pressing the button over and over again?
    Same as before, you don't want to use a FOR-NEXT unless you have a way to EXIT from it if conditions should change. Look at Mike's program and see how he makes does the same thing without a FOR-NEXT.

    Have you tried making a Flow Chart or a diagram of how your program should function?
  • hp16hp16 Posts: 11
    edited 2013-10-19 21:47
    I solved it! Thanks for the help everyone
Sign In or Register to comment.