Hey guys,
SO im trying to code a stopwatch timer game where 4 players are given a target time, for example 10 seconds, and they have to hold a button down for how long they think 10 seconds lasts. Here is the code that allows this and compares the times to see who won, thank you to the member who helped me out with this
//define a limit for waiting for all players, 20-seconds in this case
#define GAME_TIME_LIMIT 20000L
//these are the player button pins
//these were used on a Mega2560
//make sure the pins you use have pin interrupts available
const int PLYR_1_BTN = 2;
const int PLYR_2_BTN = 3;
unsigned long
MasterTimer,
timePlayer[4];
byte
bPressFlags;
void setup()
{
//we need the serial window for interaction so wait for it
Serial.begin(9600);
while(!Serial);
//set up the buttons as input-pullups. Pushing a button should ground it
pinMode( PLYR_1_BTN, INPUT_PULLUP );
pinMode( PLYR_2_BTN, INPUT_PULLUP );
//each button will cause an interrupt on a falling edge (e.g. a press)
//map each button to its own handler
attachInterrupt(digitalPinToInterrupt(PLYR_1_BTN), ISR_PLYR_1, FALLING);
attachInterrupt(digitalPinToInterrupt(PLYR_2_BTN), ISR_PLYR_2, FALLING);
//reset the game and start
ResetGame();
}//setup
void ResetGame( void )
{
Serial.println( "\n\n*** Begin timing!!! ***" );
//we start the master timer here
MasterTimer = millis();
//this byte carries the user button press info
//in bits 0..3
//bit 0 = 1 means player 1 hit his button
//bit 1 = 1 means player 2 hit his button
//bit 2 = 1 means player 3 hit his button
//bit 3 = 1 means player 4 hit his button
//sero it at the start; each ISR will set its own bit
bPressFlags = 0x00;
}//ResetGame
void loop()
{
unsigned long
timeNow;
//let the game run until all four have pressed a button or some arbitrarily long timeout has elapsed
timeNow = millis();
if( ((timeNow - MasterTimer) > GAME_TIME_LIMIT) || (bPressFlags == 0x0F) )
{
ShowResults();
ResetGame();
}//if
}//loop
void ShowResults( void )
{
byte
plyr,
ClosestPlayer;
unsigned long
diff,
ClosestTime;
unsigned long
timeDelta[4];
float
dispTime;
//if no one pressed a button, say so
if( bPressFlags == 0x00 )
{
Serial.println( "No one played the game!" );
}//if
else
{
//ClosestTime will contain the smallest difference between user times and 10-seconds from the MasterTimer
//init with a huge value for comparison reasons
ClosestTime = 10000000L;
//check each player's results
for( plyr=0; plyr<4; plyr++ )
{
Serial.print( "Player " ); Serial.print(plyr+1); Serial.print( " time: " );
//if the player hit his button, a bit will be set in flags
if( bPressFlags & (1<<plyr) )
{
//plyr hit the button...
//find his time difference and make a value we can display to 3-digits (i.e. a float)
timeDelta[plyr] = timePlayer[plyr] - MasterTimer;
dispTime = (float)timeDelta[plyr] / 1000.0;
Serial.println( dispTime, 3 );
}
else
{
//bit wasn't set player hadn't hit his button
Serial.println( "No time recorded. " );
}//else
}//for
//go through and see who won
for( plyr=0; plyr<4; plyr++ )
{
//only players that pressed their buttons are checked
if( bPressFlags & (1<<plyr) )
{
//how close to 10-seconds?
//could be over or under; this is crude but makes it easy
if( timeDelta[plyr] >= 10000 )
diff = timeDelta[plyr] - 10000;
else
diff = 10000 - timeDelta[plyr];
//if the current players time is smaller than the current "closest" time, make that
//the new closest and record the player number
if( diff < ClosestTime )
{
ClosestPlayer = plyr;
ClosestTime = diff;
}//if
}//if
}//for
//print the results
Serial.print( "The winner is player " ); Serial.print( ClosestPlayer + 1 ); Serial.print( " with an error of " );
Serial.println( (float)(ClosestTime / 1000.0), 3 );
}//else
//use the serial console to re-start. Could also use any of the player buttons
Serial.println( "\n\nPress any key to play again." );
//wait for a character, then flush
while( Serial.available() <= 0 );
while( Serial.available() > 0 )
Serial.read();
}//ShowResults
void ISR_PLYR_1( void )
{
//if a button press has already been recorded, just leave (bounce etc)
if( bPressFlags & 0x01 )
return;
//record the player's button press time
timePlayer[0] = millis();
//and set his flag indicating he played
bPressFlags |= 0x01;
}//ISR_PLYR_1
void ISR_PLYR_2( void )
{
if( bPressFlags & 0x02 )
return;
timePlayer[1] = millis();
bPressFlags |= 0x02;
}//ISR_PLYR_2
void ISR_PLYR_3( void )
{
if( bPressFlags & 0x04 )
return;
timePlayer[2] = millis();
bPressFlags |= 0x04;
}//ISR_PLYR_3
void ISR_PLYR_4( void )
{
if( bPressFlags & 0x08 )
return;
timePlayer[3] = millis();
bPressFlags |= 0x08;
}//ISR_PLYR_4
however im not sure how i would display the numbers generated on the serial monitor onto a 7 segment LED display with 12 pins. I only want to display the final results once every player has released their buttons. Any help would be greatly appreciated