Shop OBEX P1 Docs P2 Docs Learn Events
Fixing instruction overhead time? — Parallax Forums

Fixing instruction overhead time?

rwgast_logicdesignrwgast_logicdesign Posts: 1,464
edited 2012-09-18 20:44 in BASIC Stamp
So Im in chapeter 3 of the wam book and I went off and wrote the two player reaction game as an exercise at the end here it is
' {$STAMP BS2}
' {$PBASIC 2.5}
'2 player reaction


counter1 VAR Word
counter2 VAR Word
counter1 = 0
counter2 = 0


DEBUG "Both players press and hold there",CR,
      "button until the light turns red.",CR,
      "When the light turns green let go",CR,
      "of the button as fast as you can!",CR, CR


DO
  DO
  LOOP UNTIL (IN3=1) AND (IN4=1)




  HIGH 15
  LOW 14
  PAUSE 1000
  HIGH 14
  LOW 15


  DO
    IF IN3 = 1 THEN
      counter1 = counter1 + 1
    ENDIF
    IF IN4 = 1 THEN
     counter2 = counter2 + 1
   ENDIF
  LOOP WHILE (IN3=1) OR (IN4=1)


  DEBUG "Player 1's Score is: ", DEC counter1, " mS!", CR
  DEBUG "Player 2's Score is: ", DEC counter2, " mS!", CR
  IF (counter1 > counter2) THEN
    DEBUG "Player 1 is the winner!", CR,CR
  ELSEIF (counter2 > counter1) THEN
    DEBUG "Player 2 is the winner!", CR,CR
  ELSEIF (counter1=counter2) THEN
    DEBUG "Tour were equals this round!", CR,CR
  ELSE
    DEBUG "WTF HAPPEND!?", CR
  ENDIF
  DEBUG "Play again? Just hold down the buttons again!",CR,CR
   LOW 14
   LOW 15
LOOP



Anyways in the loop thats checking in3 and in4 is having time issues. Those two if commands back to back along with the counter1 and counter2 assignments are getting all messed up as far as time. If i hold the buttons for 3 seconds i only get about 1700ms stored in the counter variables. Is there a fix for this?

Comments

  • vaclav_salvaclav_sal Posts: 451
    edited 2012-09-18 08:23
    And how did you determine that each counter increment equals 1 ms ?
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-09-18 08:55
    To be fair, both states should be read at the same instant of time.
    DO
      state = inL & % 11000   ' reads the two inputs at once
      counter1 = counter1 + (state.nib0 >>3)
      counter2 = counter2 + (state >> 4)
    LOOP WHILE state
    

    The result will not be exactly in milliseconds, so if you want it to be, you have to multiply by a calibration factor. For example, you said, "1700 in 3 seconds". That is 567 per second, and the conversion factor then would be ms = counts * 1000 / 567. That is, if the counts come out at 567, that means the button was pressed for 1000 ms. The BASIC Stamp can do that multiplication by using the */ operator.
    ms = counts */ 451
    where on a hand calculator 451 = 256 * 1000 / 567. If you change the counting loop, you will have to recalibrate.

    Should the person who releases the button fastest be the winner?
  • rwgast_logicdesignrwgast_logicdesign Posts: 1,464
    edited 2012-09-18 14:10
    @Tracey
    Ahhh thank you, the WAM book has not gotten this detailed with syntax yet! Kind of weird the end of chapter project would be a game you couldnt possibly get right with what theyve taught you, my source looks alot similar to the solution except I used and while OR instead of an until AND. Lol i did mess up the signs on the code to determine a winner didnt catch that :)

    So is there a way to calculate just how many instructions/cycles code will take so problems like this are easily avoided? Would an even better way to do this is to use a 74 series counter to keep track of elapsed time? My first uController is the prop and it seems much more accurate not to mention fast :) so im wondering if the Bs2 has any built in counters or ways to keep accurate measurements of time?
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-09-18 20:44
    There are ways to estimate how much time the code will take based on the time for individual instructions. In the end it comes down to timing the code much as you did above. You hold down the button for a known amount of time and print out the raw result. From that you figure out the multiplier needed to put it into rational units like milliseconds instead of program unit like loop-time. Once a program is stable, that is, once you finish tinkering with it, the loop-time can be very consistent. The BASIC Stamp does not have interrupts or secret threads running in the background to throw off the timing.

    It can get thrown off if there are branches that can take a program down different paths within a loop. Your original with the IF statements is okay, given the situation, but after the fastest player releases the button, it takes a different time to go around the loop than it did before the first player timed out. That is because an IF statement that was true, is now false, and one of the counters no longer has to be incremented. The way I wrote the code is more neutral. Both counters are serviced each no matter what, adding either 1 or 0 to the count.

    The Stamp does not have an internal timer per se, so you are right to wonder about adding an external timer for that, if need be. The Propeller has multiple very capable internal timers and counters.
Sign In or Register to comment.