Shop OBEX P1 Docs P2 Docs Learn Events
Score counter from 0-3 — Parallax Forums

Score counter from 0-3

jmerrelljmerrell Posts: 25
edited 2013-11-19 10:45 in General Discussion
Hello everyone,

I am trying to write a subroutine for a game that will keep score (from 0-3) every time port 1 is switched to high, however I am missing something because only a zero is shown on my 7-segment display when port 1 goes high and does not change after subsequent highs to port 1. Can anyone help please. Thanks



' {$STAMP BS2}
' {$PBASIC 2.5}

'========DIR===========================================
OUTH = %00000000 ' Clear LED display
DIRH = %11111111 ' Set pins 8-15 to outputs

'=======VARIABLES======================================
index VAR Nib
score VAR Nib


DO
FOR index = 1 TO 3
IF IN1 = 1 THEN
PAUSE 10
score = 0
score = score + 1
LOOKDOWN score, [ 3, 2, 1], index
LOOKUP index, [ %10000100, %11010011, %11100111], OUTH
ENDIF
NEXT
LOOP

Comments

  • kwinnkwinn Posts: 8,697
    edited 2013-11-16 11:55
    You need to move the score=0 statement between the DO and FOR statements.
  • ercoerco Posts: 20,256
    edited 2013-11-16 12:26
    At a quick glance, I'm not sure that your for/next loop will work as you intend.
  • jmerrelljmerrell Posts: 25
    edited 2013-11-16 12:53
    Moving the score=0 statement worked. I still have some minor glitches with the score. Thanks Kwinn!!
  • jmerrelljmerrell Posts: 25
    edited 2013-11-16 13:25
    erco wrote: »
    At a quick glance, I'm not sure that your for/next loop will work as you intend.

    I removed the for/next as you suggested and it worked much better. This program is for a game I am making for my son. When I removed the for/next, the 7-segment display went blank, however the servos now rotate as they should. The intent of this program is that when port 1 is high, a servo rotates, a buzzer comes on, and there is a score shown on the display, which ends the game when the score equals 3. I'm not sure how to have the score display and increment every time port 1 goes high. The code for subroutine Target2 will be the same as Target1 subroutine, which I am working on now. Thanks!


    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    '========DIR===========================================
    OUTH = %00000000
    DIRH = %11111111

    '=======VARIABLES======================================
    SRVOcounter VAR Word
    SCORcounter VAR Bit
    index VAR Bit
    '=======MAIN===========================================
    MAIN:

    DO
    IF IN1 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET1
    ELSEIF IN2 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET2
    ENDIF
    LOOP

    '========SUBROUTINES====================================
    Target1:

    SCORcounter = 0
    IF IN1 = 1 THEN
    PAUSE 10
    SCORcounter = SCORcounter + 1
    LOOKDOWN SCORcounter, [ 3, 2, 1], index
    LOOKUP index, [ %10000100, %11010011, %11010110], OUTH
    ENDIF

    FOR SRVOcounter = 1 TO 25
    PULSOUT 14,1100 'Servo rotates DOWN"
    PAUSE 20
    NEXT
    FOR SRVOcounter = 1 TO 25
    PULSOUT 14, 660 'Servo rotates UP"
    PAUSE 20
    LOW 1
    NEXT
    PAUSE 20
    RETURN

    Target2:
    DEBUG "DEBUG Target 2", CR 'Target 1 hit"
    FOR SRVOcounter = 1 TO 25
    PULSOUT 15,1100 'Servo rotates DOWN"
    PAUSE 20
    NEXT
    FOR SRVOcounter = 1 TO 25
    PULSOUT 15, 660 'Servo rotates UP"
    PAUSE 20
    LOW 2
    NEXT
    PAUSE 20
    RETURN
  • kwinnkwinn Posts: 8,697
    edited 2013-11-16 15:44
    Move the SCORcounter = 0 line from Target1 and put it before the MAIN routine so the score is only set to 0 at the start of the game. Add an “if then else” at the end of the main routine to start the game over once the score reaches 3.

    I'm not a BS2 user so the syntax may not be correct but the logic is.


    '=======START===========================================
    START:
    SCORcounter = 0
    '=======MAIN===========================================
    MAIN:

    DO
    IF IN1 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET1
    ELSEIF IN2 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET2
    ENDIF
    IF SCORcounter < 3 THEN
    LOOP
    ELSE GOTO START
  • jmerrelljmerrell Posts: 25
    edited 2013-11-16 16:34
    kwinn wrote: »
    Move the SCORcounter = 0 line from Target1 and put it before the MAIN routine so the score is only set to 0 at the start of the game. Add an “if then else” at the end of the main routine to start the game over once the score reaches 3.

    I'm not a BS2 user so the syntax may not be correct but the logic is.

    Thanks kwinn. The display still shows a count of "1" every time port 1 goes high and never shows a 2 or 3. I know it has to be something minor with the code. I'll keep trying to debug the code.


    '=======START===========================================
    START:
    SCORcounter = 0
    '=======MAIN===========================================
    MAIN:

    DO
    IF IN1 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET1
    ELSEIF IN2 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET2
    ENDIF
    IF SCORcounter < 3 THEN
    LOOP
    ELSE GOTO START
  • kwinnkwinn Posts: 8,697
    edited 2013-11-17 12:36
    Did you delete the SCORcounter = 0 statement from the Target1 subroutine?
  • jmerrelljmerrell Posts: 25
    edited 2013-11-17 13:00
    kwinn wrote: »
    Did you delete the SCORcounter = 0 statement from the Target1 subroutine?

    Hi kwinn. Yes, the SCORcounter = 0 is located in the "Variables" before the MAIN. I only have a "1" showing up and it does not change each time there is a high on IN1. I just can't figure it out. Thanks


    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    '========DIR===========================================
    OUTH = %00000000
    DIRH = %11111111

    '=======VARIABLES======================================
    SRVOcounter VAR Word
    SCORcounter VAR Bit
    SCORcounter = 0
    index VAR Bit

    '=======MAIN===========================================
    MAIN:

    DO
    IF IN1 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET1
    ELSEIF IN2 = 1 THEN
    FREQOUT 6, 140, 4200
    GOSUB TARGET2
    ENDIF
    IF SCORcounter <3 THEN
    GOTO MAIN
    ENDIF
    LOOP

    '========SUBROUTINES====================================
    Target1:
    LOOKDOWN SCORcounter, [ 3, 2, 1], index
    LOOKUP index, [ %10000100, %11010011, %11010110], OUTH
    SCORcounter = SCORcounter + 1
    PAUSE 20

    FOR SRVOcounter = 1 TO 25
    PULSOUT 14,1100 'Servo rotates DOWN"
    PAUSE 20
    NEXT
    FOR SRVOcounter = 1 TO 25
    PULSOUT 14, 660 'Servo rotates UP"
    PAUSE 20
    NEXT
    PAUSE 20
    RETURN

    Target2:
    LOOKDOWN SCORcounter, [ 3, 2, 1], index
    LOOKUP index, [ %10000100, %11010011, %11010110], OUTH
    SCORcounter = SCORcounter + 1
    PAUSE 20

    FOR SRVOcounter = 1 TO 25
    PULSOUT 15,1100 'Servo rotates DOWN"
    PAUSE 20
    NEXT
    FOR SRVOcounter = 1 TO 25
    PULSOUT 15, 660 'Servo rotates UP"
    PAUSE 20
    NEXT
    PAUSE 20
    RETURN
    RETURN
  • skylightskylight Posts: 1,915
    edited 2013-11-17 13:50
    Hi jmerrell, you need to put the SCORcounter = 0 just above the DO statement so that it is in your MAIN part of the program it doesn't get executed in the variable section
  • kwinnkwinn Posts: 8,697
    edited 2013-11-17 16:05
    Try this. It should work but I do not have a BS to test it with, and I am not a BS user.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    '=======IR===========================================
    OUTH = %00000000
    DIRH = %11111111
    
    '=======VARIABLES======================================
    SRVOcounter VAR Word
    SCORcounter VAR Bit
    index VAR Bit
    '=======MAIN===========================================
    MAIN:
    DO
      SCORcounter = 0
      DO
        IF IN1 = 1 THEN
          FREQOUT 6, 140, 4200
          GOSUB TARGET1
        ELSEIF IN2 = 1 THEN
          FREQOUT 6, 140, 4200
          GOSUB TARGET2
        ENDIF
      LOOP
    LOOP
    
    '========SUBROUTINES====================================
    Target1:
    
    IF IN1 = 1 THEN
      PAUSE 10
      SCORcounter = SCORcounter + 1
      LOOKDOWN SCORcounter, [ 3, 2, 1], index
      LOOKUP index, [ %10000100, %11010011, %11010110], OUTH
    ENDIF
    
    FOR SRVOcounter = 1 TO 25
      PULSOUT 14,1100 'Servo rotates DOWN"
      PAUSE 20
    NEXT
    
    FOR SRVOcounter = 1 TO 25
      PULSOUT 14, 660 'Servo rotates UP"
      PAUSE 20
      LOW 1
    NEXT
    PAUSE 20
    RETURN
    
    Target2:
    DEBUG "DEBUG Target 2", CR 'Target 1 hit"
    FOR SRVOcounter = 1 TO 25
      PULSOUT 15,1100 'Servo rotates DOWN"
      PAUSE 20
    NEXT
    
    FOR SRVOcounter = 1 TO 25
      PULSOUT 15, 660 'Servo rotates UP"
      PAUSE 20
      LOW 2
    NEXT
    PAUSE 20
    RETURN
    

    PS - If it still does not work try posting your question in the Basic Stamp forum.
  • jmerrelljmerrell Posts: 25
    edited 2013-11-17 19:08
    skylight wrote: »
    Hi jmerrell, you need to put the SCORcounter = 0 just above the DO statement so that it is in your MAIN part of the program it doesn't get executed in the variable section

    skylight, sounded like a good suggestion but did not work. I will keep trying to figure this one out. Thanks again :smile:
  • jmerrelljmerrell Posts: 25
    edited 2013-11-17 19:23
    Kwinn, another good suggestion but yours did not work either. When IN1 goes high, the servo rotates and the score (7 segment LED) should increases in count (my intent). IN1 is high for about 50-100ms then returns to low. Sort of like pushing a momentary switch. This is the first time I have ever written code for lookup/lookdown. My ideal situation would be to have the zero appear on the display when the program starts (which it does not) and increment after IN1 goes high. I will keep trying to figure this program out. Seems like it should be so easy.
  • garyggaryg Posts: 420
    edited 2013-11-18 05:56
    Hi
    When I'm having trouble such as you are having,
    I write a very super simple program to test only the function that I feel is giving trouble.
    I would try something like this:


    Keep the IR, and VARIABLES as is.
    Then only write the simple program something like what I've written below.

    MAIN:

    SCORcounter = 0

    GOTO Test

    Test:

    LOOKDOWN SCORcounter, [3,2,1], index
    LOOKUP index, [%10000100,%11010011,%11010110], OUTH
    SCORcounter = SCORcounter +1
    PAUSE 1000
    If SCORcounter <4 GOTO Test
    Debug " I'm Done", cr
    END


    If this simple code is correct your display should start in the off condition
    Then cycle through the numbers 1 to 3

    When you get a very super simple program section working correctly, you will understand
    what is and is not working.

    I could not actually try this code as my BS2 is tied up at the moment.

    This is the strategy I always use when I'm not understand something.
    I hope this helps you out in some manner.
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-11-18 06:37
    Change .... SCORcounter VAR Bit ... so that it reads ... SCORcounter VAR Byte
  • jmerrelljmerrell Posts: 25
    edited 2013-11-19 10:45
    I changed "index var bit" to "index var word" and now everything works great. Thank you to everyone who had an input to this difficult problem..Thanks!!
Sign In or Register to comment.