Timer/reflex game

Hello!

I am trying to write the code for a 2 player timer/reflex game. 2 buttons + LCD. I have the time formatted so that it is seconds.tenth of second. The goal of the game is to push the button every multiple of 5 seconds. I am starting to think this may not work on a microcontroller.

I tried just using:

millis()%5000==0;

But quickly realized that this would require the program to be at this if statement precisely at this point in time.
right now I am at:

  if(millis()%5000>4998 || millis()%5000<2)
  {
    lcd.setCursor(7,1);
    lcd.print(playerOneScore++);
  }

But getting 65 multiples of 5 at 340 seconds, should be 67, so close but not quite. Is there a way to do this "better", especially when I add the code for the buttons to check if they were pressed "close" to 5 seconds. even at a range of +- 5 milliseconds, I was getting 5 hits in that range.

Thanks!

-Josh

I am starting to think this may not work on a microcontroller.

Sure it will.

I tried just using millis()%5000==0, but quickly realized that this would require the program to be at this if statement precisely at this point in time.

Yep. So, don't do that. Instead, determine how long it has been since the last event (you DID record when that event occurred, didn't you?). If that equals or exceeds the desired interval, success! (whatever that means).

PS. You seem to have forgotten to read the "How to post on this forum" thread, or somehow assumed that didn't apply to you. It certainly does. POST YOUR CODE! (Correctly).

Hello,

Thanks for the input! Sorry about the code... I went and read through what you suggested and think I fixed my post! Very new to forums including posting code.

Ive been reading about Arduino timers and interrupts, is this what you were referring to when it came to recording events? If so, I should be trying to figure out how to create an interrupt at 5 second intervals and check to see whether one or two of the buttons is pressed?

Thanks!

Isn't that backwards? What if they press the button after 4 seconds? Your interrupt won't detect that. (In other words you will only detect correct presses, not incorrect ones. You could defeat that by jabbing the button madly).

What about: test if the button (switch) is pressed. If so, see how long elapsed since the last press. You don't need interrupts for that.

Thanks for pointing that out with the interrupts.

I think I have a semi functioning game (more to add in terms of winning) but it does work. I am not sure if this is really what you have suggested, and would be interested in how to improve. I dont think I really did what you suggested, though I gave it a go with the lastB1Push and lastB2Push variables to keep track of how long since last push. However, I am pretty sure I don't need this piece for it to work the way I have written it.

Thanks!

//include the library code:
#include <SPI.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
//You can go to http://playground.arduino.cc/Main/LiquidCrystal to learn more of what you can do with the LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //So, your LCD is called lcd in this file.

const int button1Pin = 8;//Change this number to whatever pin your first button is connected to
const int button2Pin = 9;//Change this number to whatever pin your second button is connected to

//keeps track of milliseconds since last time each button was pushed
int lastB1Push = 0; 
int lastB2Push = 0;

//keeps track of whether the button is down or up
int button1State, button2State;

//Players were getting scored multiple times for one button press, this is used to only score each press one time
boolean toggle1 = false;
boolean toggle2 = false;

//Track each players score
int player1Score = 0;
int player2Score = 0; 

void setup() {
 //Initialize buttons
 pinMode(button1Pin, INPUT);
 pinMode(button2Pin, INPUT);
  
 //set up the LCD with player names 
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.print("P1");
 lcd.setCursor(14,0);
 lcd.print("P2");
}

void loop() {
  //Runs the timer and LCD formatting
  gameClock();
  //Checks the state of the buttons and handles scoring
  checkPushed();
  //formats and updates scores
  lcd.setCursor(0,1);
  lcd.print(player1Score);
  lcd.setCursor(14,1);
  lcd.print(player2Score);
}

void gameClock()
{
  //These three if statements to keep the timer format consistant
  if(millis()/1000 < 10)
  {
    lcd.setCursor(7,0);
    lcd.print(millis()/1000);
  }
  if(millis()/1000 > 9 && millis()/1000 < 100)
  {
    lcd.setCursor(6,0);
    lcd.print(millis()/1000);
  }
  if(millis()/1000 > 99 && millis()/1000 < 1000)
  {
    lcd.setCursor(5,0);
    lcd.print(millis()/1000);
  }
  lcd.setCursor(8,0);
  lcd.print(".");
  lcd.setCursor(9,0);
  lcd.print((millis()/100)%10);
}

void checkPushed()
{
  //gets state of each button
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  //after the button is released, the toggle is reset
  if(button1State == HIGH)
  {
    toggle1 = false;
  }
  //the toggle will prevent the same button push from being scored multiple times
  //Checks player 1
  if(button1State == LOW && toggle1 == false)
  {
    toggle1 = true;
    //right now the scoring is +-100 milliseconds around 5 second multiples, could make these global variables to adjust difficulty.
    //right now its +1 win, -1 lose.  should change to variables to make changing scoring easier.
    if((millis() - lastB1Push) % 5000 > 4900 || (millis() - lastB1Push) % 5000 < 100)
    {
      player1Score = player1Score + 1;
    }
    else
    {
      player1Score =  player1Score - 1;
    }
    lastB1Push == millis();
  }
  //reset player 2 toggle
  if(button2State == HIGH)
  {
     toggle2 = false;
  }
  //checks player 2
  if(button2State == LOW && toggle2 == false)
  {
    toggle2 = true;
    if((millis() - lastB2Push) % 5000 > 4900 || (millis() - lastB2Push) % 5000 < 100)
    {
      player2Score = player2Score + 1;
    }
    else
    {
      player2Score = player2Score - 1;
    }
    lastB2Push == millis();
  }

}

//Your goal is to now make a timer reflex game.
//You will need to have a timer in the middle that counts by the tenth of a second: 0.0, 0.1...4.9, 5.0..etc
//In the left and right you will score in each corner for player 1 and 2.
//When a player wins, the game ends and a winning message appears.
//For now, you will just use the arduino reset button to start a new game.
//You need to add a way to win!  Make sure to display who wins!
//can you make different levels of dificulty?
//can you adjust the scoring?