/* Quiz Buzzer ----- ------ v.02 Behaviours: * Startup, flash lights, reds then greens. Detect plugged in buzzers? Start 'newgame' * When any red button pressed: All green lights come on then off twice and on third time, 'winner' LED comes on only. Any addtional presses counted for 3 seconds. Red buttons switch off either when pressed or after 5 seconds. * Short press selects 'next fastest' until all chosen. Then resets. (Not implimented) * 'reset' for held 2 seconds, switches off all green LEDs, flashes red buttons twice, then all red on. Game reset. Bonus: * 'Dice' mode, 'reset' held down for 5 seconds while in 'armed' mode. Starts after 5 seconds of hold-down, runs sequence: 1324 until button release. * 'Handicap', 'reset' held while power up = half second 'bias' towards buzzer 1 (Not implimented) * 'Drinking' game. Countdown timer then reaction. Fastest */ #define BUTOFFSET 14 #define REDOFFSET 10 #define GREOFFSET 6 #define RESBUT 2 #define RESLED 3 byte gamemode=1; // 1 = dice, 2 = quiz, 3 = drinking byte special=0; // Latches 'startup' modes. 1 for handicap. 2 for drinking. byte gamereset=1; // 1 = just reset (off if any red button pressed) byte resetting=0; // Break out of counter loop. byte playing=0; // 1 = timer started (Off after 5 seconds) byte winner=0; // If winner is chosen. And who. unsigned long buztime[4]; // Button timer data. 32 bits (4 bytes). byte buzcon[] = {false,false,false,false}; // Buzzers connected. void setup() { /* gamereset=1; // 1 = just reset (off if any red button pressed) resetting=0; // Break out of counter loop. playing=0; // 1 = timer started (Off after 5 seconds) winner=0; // If winner is chosen. And who. int time[4] = 0xffff; // All buttons start out with highest value */ // initialize serial: Serial.begin(9600); pinMode(10, OUTPUT); pinMode(11, OUTPUT); pinMode(12, OUTPUT); pinMode(13, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(14, INPUT); pinMode(15, INPUT); pinMode(16, INPUT); pinMode(17, INPUT); pinMode(RESLED, OUTPUT); pinMode(RESBUT, INPUT_PULLUP); // Detect startup conditons to set special modes. digitalWrite(RESLED, HIGH); delay(200); digitalWrite(RESLED, LOW); if(digitalRead(RESBUT)==LOW){ pinMode(GREOFFSET, INPUT_PULLUP); if (digitalRead(GREOFFSET)==LOW) { special=0; delay(200); digitalWrite(RESLED, HIGH); delay(200); digitalWrite(RESLED, LOW); } } else { special=2; } pinMode(GREOFFSET, INPUT); pinMode(GREOFFSET, OUTPUT); Serial.print("Special:"); Serial.println(special); randomSeed(analogRead(4)); resetgame(); } void loop() // start main loop { unsigned long checkMillis; unsigned long resetMillis; while(digitalRead(RESBUT)==LOW) {delay(10);} // Wait for reset button to be released. digitalWrite(RESLED, HIGH); if(special==2) { gamemode=3; } else { gamemode=2; } // Enables 'drinking' mode. while(gamereset){ if(millis()-checkMillis >= 500 ) { checkMillis = millis(); buttonDetect(); if(gamemode==2) { for(byte i=0; i<4; i++) { if(buzcon[i]) { redLED(i, HIGH); } else { redLED(i, LOW); } } } } if(gamemode==2) { //Quiz - start on red-button. for(byte i=0; i<4; i++) { if(buzcon[i]) { if(digitalRead(i+14)==HIGH){ buztime[i] = millis(); gamereset=0; playing=1; redLED(i, LOW); Serial.print("But:"); Serial.print(i); Serial.print("."); Serial.print(buztime[i]); Serial.print(" "); } } } } // Drinking - start on reset resetMillis = millis(); if(digitalRead(RESBUT)==LOW){ delay(10); while(gamereset==1) { if(digitalRead(RESBUT)==HIGH){ // Button let go quickly. (Needs to have no effect in triva mode) gamereset=0; playing=1; } if(millis()-resetMillis >= 2000 ) { // Button held down for 2 seconds gamemode=1; // Dice mode gamereset=0; } } } } // Game now running. Serial.print("Mode:"); Serial.print(gamemode); Serial.print("!"); digitalWrite(RESLED, LOW); if(gamemode==3) { // Drinking game logic // Flash random number of times. Serial.print("Count:"); for(byte i=random(3, 20); i>0; i--) { Serial.print(i); Serial.print("."); delay(1500); digitalWrite(RESLED, HIGH); delay(200); digitalWrite(RESLED, LOW); } Serial.print("!"); // Light up red buttons. for(byte i=0; i<4; i++) { if(buzcon[i]) { redLED(i, HIGH); } else { redLED(i, LOW); } } } if(gamemode>1) { // Do all the button timer stuff checkMillis = millis(); while(playing) { playing=0; for(byte i=0; i<4; i++) { if(buzcon[i]) { if(buztime[i]==0xffffffff){ playing=1; if(digitalRead(i+14)==HIGH){ buztime[i] = millis(); redLED(i, LOW); Serial.print(i); Serial.print("."); Serial.print(buztime[i]); Serial.print(" "); } } } } if(millis()-checkMillis >= 1000 ) { playing=0; Serial.print("Time "); } } // End playing // Red lights off! for(byte i=0; i<4; i++) { redLED(i, LOW); } // Choose winner. winner=0; // Have to start somewhere. for(byte i=0; i<4; i++) { greenLED(winner,LOW); if(buztime[i]= 10000 ) { gamereset=0; Serial.print("T"); } } resetgame(); Serial.println(" RESET"); } // End loop() /* ----- What did this do? What was it for? Why is it here? ---- Serial.print("Press: "); for(byte i=0; i<4; i++) { if(buzcon[i]) { redLED(i, HIGH); Serial.print(i); if(digitalRead(i+14)==HIGH){ Serial.print(".H "); greenLED(i, HIGH); } else { greenLED(i, LOW); Serial.print(".L "); } } else { redLED(i, LOW); } } Serial.println(""); */ // delay(50); // waits for a second // for(byte i=0; i<4; i++) { // redLED(i, LOW); // sets the LED off // greenLED(i,LOW); // } // delay(50); /* -------------------------- OLD PSUDOCODE EXAMPLE STUFF ------------------------- --- FOR LOGIC FLOW REFRENCE ONLY ------- if(playing & timer()=5sec) { playing = 0; timer(off); redledoff(all); } // Stops 'play' mode. Allows for resetting. All lights off. if buttondown() not restting=1 { // If any button is pressed down. Unless resetting. if red buttons() { // Any of the red buttons down if(reset) { // And game is ready to go. reset = 0 playing =1 // Start game starttimer() // And timer. } if(playing) { // If someone has pressed a button winner = 1; for each button{ If time(button) = 0xffff { // And button hasn't been 'counted' yet time(button)=timer; // Save counts for each timer. redledoff(button); // Switch off red button LED } } } if resetbutton() & playing = 0 { if(winner) { // Show next winner. time(winner) = 0xffff; // Give old winener max time. winner=0; // No more winner, so have to rerun the check! } if(resettimer = 2sec { resetting=1; } // trigger reset if(resettimer = 5sec & reset=1) { // Run 'dice'. else { // No button pressed. resetresettimer(); } if ( reset=0 AND winner=0 ) { // If there isn't one and at least one button has been pressed(reset=0);, find and show winner winner=1; // Have to start somewhere. for button 1 to 4 { // Go through all the buttons. if(time(winner) less time(button) ) { winner = button); // Find the lowest. } if(timer(winner)=0xffff) { // No 'real' winners left. newgame(); // Restat game again! else { displaywinner(winner); // Flash lights and show who won! } ------------------- END EXAMPLE PSUDOCODE ---------------- */ // -------------- FUCTIONS ----------- // Control red LEDS void redLED(byte ipin,byte istate){ digitalWrite(ipin+REDOFFSET, istate); } // Control green LEDs void greenLED(byte ipin,byte istate){ digitalWrite(ipin+GREOFFSET, istate); } // Detect what buttons are plugged in. void buttonDetect(){ Serial.print("Det:"); for(byte i=0; i<4; i++) { // digitalWrite(i+ioffset, LOW); pinMode(i+GREOFFSET, INPUT_PULLUP); //Serial.print(i); if (digitalRead(i+GREOFFSET)==LOW) { Serial.print("T"); buzcon[i]=true; } else { Serial.print("F"); buzcon[i]=false; } pinMode(i+GREOFFSET, INPUT); pinMode(i+GREOFFSET, OUTPUT); } Serial.println(". "); } // Put everything back where you left it. Including lights off. // And all timers reset void resetgame() { for(byte i=0; i<4; i++) { buztime[i] = 0xffffffff; // All buttons start out with highest value buzcon[0] = false; redLED(i,LOW); greenLED(i,HIGH); // What is with this? Needed? } resetting=0; // Break out of counter loop. playing=0; // 1 = timer started (Off after 5 seconds) winner=0; // No more winner gamereset=1; // Ready to go again. }