Below is the Arduino Program Code for V1.1:
/*
Game_First_to_Respond - A program for a quiz game function
Copyright 2013 by V Boyd
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Change Log:
2013-04-28 V1.1 - Fixed float error in loop timing, set TEST_MODE to 3.5 seconds
2013-04-27 V1.0 - Added comments, cleaned up debug messages.
2013-04-26 V0.5 - Added debounce to reset line
2013-04-24 V0.4 - Reset hold for 10s does a "test lights" mode, Easter Egg put in
2013-04-24 V0.3 - Button Lights and Sounds added, auto reset after RESET_TIMEOUT_SECONDS
2013-04-23 V0.2 - Button detect with ordering & LED light blinking logic finished
2013-04-18 V0.1 - Initial Version
Notes:
2013-04-24 - All functions working; ready for cleanup
2013-04-22 - Started adapting for full 4 button support
2013-04-18 - To drive 4 additional LED lights on the control panel, will have to use Analog IN for _BUTTON
*/
// Buttons have two wires from the button into the controller and a GROUND wire.
// [Wire to control box][Plastic][Base Contact (ground)][Center Contact (BUTTON)][End Contact (ACTIVATE)]
// The _BUTTON wire is the phone plug center contact and goes HIGH when the button is pressed
// The _ACT wire is the phone plug end contact; on going HIGH the button lights (and sound) activate
// The phone plug base contact is GROUND
// GLOBAL Constants affecting behavior
const unsigned long RESET_TIMEOUT_SECONDS = 60; // Reset of buttons and LEDS even if Reset Button not pressed
const unsigned long DEBOUNCE_T = 50; // Debounce time in milliseconds
const unsigned long TEST_MODE = 3500; // 3.5 seconds
// PIN Assignments
const int RX = 0;
const int TX = 1;
const int BUTTON_START = 2;
const int RED_BUTTON = 2;
const int GRN_BUTTON = 3;
const int BLU_BUTTON = 4;
const int YLW_BUTTON = 5;
const int BTN_START = 6;
const int RED_ACT = 6;
const int GRN_ACT = 7;
const int BLU_ACT = 8;
const int YLW_ACT = 9;
const int LED_START = 10;
const int RED_LED = 10;
const int GRN_LED = 11;
const int BLU_LED = 12;
const int YLW_LED = 13;
const int BTN_RESET = 4;
// BUTTON State Seqence Varibles
// Define the button signals, each set of 3 values defined a "Step. (BS_STP_SZ defines the step size)
// A set of steps is called a "Profile." (BS_PROF_SZ defines the number of steps in a "profile."
// All profiles are the same size)
// The "Profiles" are used in this way:
// Profile 0 = Off, set the "button activate" line low and leave it low
// Profile 1 = "1st Place Profile" - 1 cycle of Lights and Sounds, then endless cycles of Lights Only
// Profile 2 = "2nd Place Profile" - Off
// Profile 3 = "3rd Place Profile" - OFF
// Profile 4 - "4th Place Profile" - OFF
// Profile 5 - "LIGHT TEST Profile" - Activate lights only, no sound.
// The 3 elecments of a "step" are: "[<HIGH | LOW | -1>, unsigned long delay_b4_next, int next_step]
// Where:
// <HIGH | LOW | -1> - Send the "button activiate" line a HIGH, or LOW signal.
// A -1 means do not change the value from the last setting.
// unsigned long delay_b4_next - Is the number of milliseconds that this signal should be output to the burton
// before proceeding to the next step (see following)
// int next_step - A "Profile's" steps are "numbered" 0 (zero) to (BS_PROF_SZ - 1).
// - A loop can be created by setting "next_step" to a previous step.
// - For example the "off" loop is simply a LOW's follow by a loop of "do nothing" to itself.
// (See Profile 1.)
// Out, ms, next
int BTN_SEQ[] = { LOW, 250, 1, /* Profile 0 (off) begin - off */
-1, 250, 1, /* - 1 the 01 for a value means just leave it at the last value, in this case LOW */
0, 0, 0, /* - 2 */
0, 0, 0, /* - 3 */
0, 0, 0, /* - 4 */
0, 0, 0, /* - 5 */
0, 0, 0, /* - 6 */
0, 0, 0, /* - 7 Profile 0 end */
HIGH, 2500, 1, /* -1 Profile 1 (winner) begin - 1 flashing with sound, then no sound */
/* going high turns on the lights and sound, staying high keeps the relay to speakers on */
LOW, 100, 2, /* recycle, 2.5 seconds is enough that the button stopped lights and sound */
HIGH, 20, 3, /* 20 ms pulse will turn on lights and sound */
LOW, 2500, 2, /* going low turns off the relay to the speaker, no sound */
0, 0, 0, /* step 4, no action */
0, 0, 0,
0, 0, 0,
0, 0, 0, /* step 7, Profile 1 end */
LOW, 250, 1, /* Profile 2 (2nd place) begin - off */
-1, 250, 1, /* - 1 */
0, 0, 0, /* - 2 */
0, 0, 0, /* - 3 */
0, 0, 0, /* - 4 */
0, 0, 0, /* - 5 */
0, 0, 0, /* - 6 */
0, 0, 0, /* Profile 2 end */
LOW, 250, 1, /* Profile 3 (3rd place) begin - off */
-1, 250, 2, /* - 1 */
0, 0, 0, /* - 2 */
0, 0, 0, /* - 3 */
0, 0, 0, /* - 4 */
0, 0, 0, /* - 5 */
0, 0, 0, /* - 6 */
0, 0, 0, /* Profile 3 end */
LOW, 250, 1, /* Profile 4 (4th place) begin - off */
-1, 250, 2, /* - 1 */
0, 0, 0, /* - 2 */
0, 0, 0, /* - 3 */
0, 0, 0, /* - 4 */
0, 0, 0, /* - 5 */
0, 0, 0, /* - 6 */
0, 0, 0, /* Profile 4 end */
LOW, 20, 1, /* Profile 5 (Light Test) Step 0 */
HIGH, 2500, 2, /* Step 1, activate L&S, leave Sound relay high, go to step 3 */
LOW, 100, 3, /* L&S have turned off by now, set activate signal to low, no effect, go to step 4 */
HIGH, 20, 4, /* Send activate to button for 20 ms (sound relay is turned on) go to step 5 */
LOW, 2500, 3, /* turn activate low, this turns off the speaker relay, but has no effect on ights, goto 3 */
0, 0, 0, /* step 5, unused */
0, 0, 0, /* step 6, unused */
0, 0, 0 /* step 7, unused */
};
const int BS_STP_SZ = 3; /* Step Size */
const int BS_PROF_SZ = 8; /* Profile Size */
const int BS_PROF_NUM = 5; /* 0=OFF, 1=1 Flash, 2=2 Flash, 3=3 Flash, 4=4 Flash */
// Button Sequence State
// For each color (0 to 4) a "pointer to where the button is in the BTN_SEQ[] state machine,
// The "pointer" is (1) what "profile is bring run, (2) what step is being run, and (3) when was the step started.
long lBSS[] = {0, 0, 0, /* RED, prof_index, step_index, step_start_t */
0, 0, 0, /* GRN, prof_index, step_index, step_start_t */
0, 0, 0, /* BLU, prof_index, step_index, step_start_t */
0, 0, 0}; /* YLW, prof_index, step_index, step_start_t */
const int BSS_SIZE = 3; /* number of elements in a row */
// LED State Seqence Varibles
// Think of this as a three dimensional array: a "step" (LOW, 250, 0) = (output, duration, next step)
// (LS_STP_SZ defines the step size.)
// Groups of "steps" are a "profile", i.e. 0=off, 1=1st place, 2=2nd place, etc.
// (LS_PROF_SZ defines the # of steps in a profile.)
// The groups of profiles is the LED State Sequence machine
// The "Profiles" are used in this way:
// Profile 0 = Off, set the "LED" line low and leave it low
// Profile 1 = "1st Place Profile" - LED is on solid
// Profile 2 = "2nd Place Profile" - LED is blinking "quickly"
// Profile 3 = "3rd Place Profile" - LED is blinking "slowly"
// Profile 4 - "4th Place Profile" - OFF
// Profile 5 - "LIGHT TEST Profile" - Activate LED on solid.
// The 3 elecments of a "step" are: "[<HIGH | LOW | -1>, unsigned long delay_b4_next, int next_step]
// Where:
// <HIGH | LOW | -1> - Send the "LED" line a HIGH, or LOW signal.
// A -1 means do not change the value from the last setting.
// unsigned long delay_b4_next - Is the number of milliseconds that this signal should be output to the LED
// before proceeding to the next step (see following)
// int next_step - A "Profile's" steps are "numbered" 0 (zero) to (BS_PROF_SZ - 1).
// - A loop can be created by setting "next_step" to a previous step.
// - For example the "off" loop is simply a LOW follow by a loop of "do nothing" to itself.
// (See Profile 1.)
// Out, ms, next
int LED_SEQ[] = { LOW, 250, 1, /* Step 0, Profile 0 begin - off */
-1, 250, 1, /* Step 1 */
0, 0, 0, /* Step 2 */
0, 0, 0, /* Step 3 */
0, 0, 0, /* Step 4 */
0, 0, 0, /* Step 5 */
0, 0, 0, /* Step 6 */
0, 0, 0, /* Step 7, Profile 0 end */
HIGH, 250, 1, /* Profile 1 begin step 0 - 1 LED ON, go to step 1 */
-1, 500, 1, /* step 1, don't change anything, leave LED ON, go to step 1 */
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0, /* Profile 1 end */
HIGH, 250, 1, /* Profile 2 (2nd place) begin - "Blink Quickly" */
LOW, 250, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0, /* Profile 2 end */
HIGH, 250, 1, /* Profile 3 (3rd place) begin - Flashing slowly */
LOW, 875, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0, /* Profile 3 end */
LOW, 250, 0, /* Profile 4 (4th place) begin - off */
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0, /* Profile 4 end */
LOW, 250, 1,
HIGH, 750, 2, LOW, 250, 3, HIGH, 250, 4, LOW, 250, 5, HIGH, 750, 6, LOW, 850, 7,
HIGH, 250, 8, LOW, 850, 9,
HIGH, 750, 10, LOW, 250, 11, HIGH, 250, 12, LOW, 1700, 0, /* S12 */
HIGH, 750, 14, LOW, 250, 15, HIGH, 250, 16, LOW, 250, 17, HIGH, 250, 18, LOW, 250, 19, HIGH, 250, 20, LOW, 850, 21,
HIGH, 250, 22, LOW, 250, 23, HIGH, 750, 24, LOW, 250, 25, HIGH, 250, 26, LOW, 850, 27,
HIGH, 750, 28, LOW, 250, 29, HIGH, 250, 30, LOW, 250, 31, HIGH, 750, 32, LOW, 250, 33, HIGH, 750, 34, LOW, 850, 35,
HIGH, 250, 36, LOW, 250, 37, HIGH, 750, 38, LOW, 850, 39,
HIGH, 750, 40, LOW, 250, 41, HIGH, 250, 42, LOW, 1700, 13, /* 42 */
HIGH, 250, 44, LOW, 250, 45, HIGH, 250, 46, LOW, 250, 47, HIGH, 250, 48, LOW, 850, 49,
HIGH, 250, 50, LOW, 250, 51, HIGH, 250, 52, LOW, 250, 53, HIGH, 250, 54, LOW, 250, 55, HIGH, 250, 56, LOW, 850, 57,
HIGH, 250, 58, LOW, 250, 59, HIGH, 750, 60, LOW, 850, 61,
HIGH, 750, 62, LOW, 250, 63, HIGH, 250, 64, LOW, 850, 65,
HIGH, 750, 66, LOW, 250, 67, HIGH, 250, 68, LOW, 850, 69,
HIGH, 750, 70, LOW, 250, 71, HIGH, 750, 72, LOW, 250, 73, HIGH, 750, 74, LOW, 850, 75,
HIGH, 750, 76, LOW, 250, 77, HIGH, 250, 78, LOW, 1700, 43, /* 78 */
HIGH, 250, 80, LOW, 250, 81, HIGH, 250, 82, LOW, 250, 83, HIGH, 250, 84, LOW, 250, 85, HIGH, 750, 86, LOW, 850, 87,
HIGH, 250, 88, LOW, 250, 89, HIGH, 250, 90, LOW, 850, 91,
HIGH, 750, 92, LOW, 250, 93, HIGH, 250, 94, LOW, 250, 95, HIGH, 750, 96, LOW, 250, 97, HIGH, 250, 98, LOW, 850, 99,
HIGH, 750, 100, LOW, 250, 101, HIGH, 250, 102, LOW, 250, 103, HIGH, 750, 104, LOW, 850, 105,
HIGH, 750, 106, LOW, 250, 107, HIGH, 250, 108, LOW, 250, 109, HIGH, 750, 110, LOW, 250, 111, HIGH, 750, 112, LOW, 1700, 79
};
const int LS_STP_SZ = 3; /* Step Size */
const int LS_PROF_SZ = 8; /* Profile Size */
const int LS_PROF_NUM = 5; /* 0=OFF, 1=1 Flash, 2=2 Flash, 3=3 Flash, 4=4 Flash */
// LED Sequence State
long lLSS[] = {0, 0, 0, /* RED, prof_index, step_index, step_start_t */
0, 0, 0, /* GRN, prof_index, step_index, step_start_t */
0, 0, 0, /* BLU, prof_index, step_index, step_start_t */
0, 0, 0}; /* YLW, prof_index, step_index, step_start_t */
const int LSS_SIZE = 3; /* number of elements in a row */
// Variables, General
long lLoopCount = 0;
unsigned long ulStartTime;
unsigned long ulCurrTime;
unsigned long ulLoopTime;
unsigned long ulActiveTimeStart; /* Time of first button pressed */
int iInputVal;
int iInputLastVal;
long lBounceCnt = 0;
int iRstBtnSt = 0;
int iTest = 0;
unsigned long ulRstBtnSt_t[2] = {0, 0};
unsigned long ulBtnSt_t = 0;
// the setup routine runs once when you press reset
// (the Arduino reste line, NOT the game reset button A4:
void setup() {
pinMode(RED_ACT, OUTPUT);
pinMode(GRN_ACT, OUTPUT);
pinMode(BLU_ACT, OUTPUT);
pinMode(YLW_ACT, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(GRN_LED, OUTPUT);
pinMode(BLU_LED, OUTPUT);
pinMode(YLW_LED, OUTPUT);
pinMode(RED_BUTTON, INPUT);
pinMode(GRN_BUTTON, INPUT);
pinMode(BLU_BUTTON, INPUT);
pinMode(YLW_BUTTON, INPUT);
pinMode(A4, INPUT);
// initialize serial communication at 9600 bits per second:
// only enable when debugging
// Serial.begin(9600);
}
// Reset the buttons and the LEDs
// This is accomplished by setting the lLSS and lBSS arrays to 0, 0, 0, i.e.
// profile = 0, step = 0, step_time = 0
void reset_all() {
for (int i = 0; i < sizeof(lLSS)/sizeof(long); i++) {
lLSS[i] = (long) 0;
}
for (int i = 0; i < sizeof(lBSS)/sizeof(long); i++) {
lBSS[i] = (long) 0;
}
ulActiveTimeStart = 0;
iTest = 0;
}
// the loop routine runs over and over again forever:
void loop() {
if (lLoopCount == 0)
ulStartTime = millis();
// READ Buttons (and debounce)
ulLoopTime = millis();
// BUTTON Press, check for button press, recorder order, 1,2,3,4; sum of order=0 means no button pressed
int dbgChange = false;
for (int color = 0; color < 4; color++) {
iInputVal = digitalRead(BUTTON_START + color);
if (lLSS[(color * LSS_SIZE)] == 0 && iInputVal == HIGH) {
int sum = (lLSS[0] != 0) + (lLSS[1*LSS_SIZE] != 0) + (lLSS[2*LSS_SIZE] != 0) + (lLSS[3*LSS_SIZE] != 0) + 1;
if (sum == 1) /* first button was pressed */
ulActiveTimeStart = ulLoopTime; /* for auto reset after RESET_TIMEOUT_SECONDS */
lLSS[color * LSS_SIZE] = sum; /* set LED profile */
lLSS[(color * LSS_SIZE) + 1] = 0; /* set to step 0 */
lLSS[(color * LSS_SIZE) + 2] = 0; /* reset start time */
lBSS[color * BSS_SIZE] = sum; /* set BTN profile */
lBSS[(color * BSS_SIZE) + 1] = 0; /* set to step 0 */
lBSS[(color * BSS_SIZE) + 2] = 0; /* reset start time */
dbgChange = true;
}
}
// if (dbgChange == true) { /* Debug Information */
// for (int color =0; color < 4; color++) {
// Serial.print(" btn "); Serial.print(color); Serial.print(" = ");
// if (color != 3) Serial.print(lLSS[color * LSS_SIZE]);
// else Serial.println(lLSS[color * LSS_SIZE]);
// }
// }
// BUTTON Lights and Sound
// for each color button, 1) see if the current step duration has expired,
// if the step duration expired, go to next step and perform action (i.e. HIGH, LOW
for (int color =0; color <4; color++) {
// read lBSS array for BTN-profile, BTN-step, and BTN-step-start-time
int prof_indx = lBSS[(color * BSS_SIZE) + 0];
int step_indx = lBSS[(color * BSS_SIZE) + 1];
unsigned long step_start_time = lBSS[(color * BSS_SIZE) + 2];
// index into BTN_SEQ array, BTN_SEQ[profile, step][Out-Value, Duration, Next-step]
int led_prof_index = (prof_indx * (BS_PROF_SZ * BS_STP_SZ)); /* the BTN profile */
int led_step_index = led_prof_index + (step_indx * BS_STP_SZ);
int step_out_value = BTN_SEQ[(led_step_index + 0)];
int step_duration = BTN_SEQ[led_step_index + 1];
int step_next = BTN_SEQ[led_step_index + 2];
if (step_start_time == 0) { /* First time on this step */
digitalWrite(BTN_START + color, step_out_value);
lBSS[(color * BSS_SIZE) + 2] = ulLoopTime;
step_start_time = ulLoopTime;
}
if (step_start_time + (unsigned long) step_duration < ulLoopTime) { // time to change steps
int led_next_step_index = (int) led_prof_index + (step_next * BS_STP_SZ);
int outValue = BTN_SEQ[led_next_step_index + 0];
if (outValue >= 0) {
digitalWrite(BTN_START + color, outValue);
}
lBSS[(color * BSS_SIZE) + 1] = step_next;
lBSS[(color * BSS_SIZE) + 2] = ulLoopTime;
}
}
// LED Lights
// for each color LED, 1) see if the current step duration has expired,
// if the step duration expired, go to next step and perform action (i.e. HIGH, LOW
for (int color =0; color <4; color++) {
// read lLSS array for LED-profile, LED-step, and LED-step-start-time
int prof_indx = lLSS[(color * LSS_SIZE) + 0];
int step_indx = lLSS[(color * LSS_SIZE) + 1];
unsigned long step_start_time = lLSS[(color * LSS_SIZE) + 2];
// index into LED_SEQ array, LED_SEQ[profile, step][Out-Value, Duration, Next-step]
int led_prof_index = (prof_indx * (LS_PROF_SZ * LS_STP_SZ)); /* the LED profile */
int led_step_index = led_prof_index + (step_indx * LS_STP_SZ);
int step_out_value = LED_SEQ[(led_step_index + 0)];
int step_duration = LED_SEQ[led_step_index + 1];
int step_next = LED_SEQ[led_step_index + 2];
if (step_start_time == 0) { /* First time on this step */
digitalWrite(LED_START + color, step_out_value);
lLSS[(color * LSS_SIZE) + 2] = ulLoopTime;
step_start_time = ulLoopTime;
}
if (step_start_time + (unsigned long) step_duration < ulLoopTime) { // time to change steps
int led_next_step_index = (int) led_prof_index + (step_next * LS_STP_SZ);
int outValue = LED_SEQ[led_next_step_index + 0];
if (outValue >= 0) {
digitalWrite(LED_START + color, outValue);
}
lLSS[(color * LSS_SIZE) + 1] = step_next;
lLSS[(color * LSS_SIZE) + 2] = ulLoopTime;
}
}
// RESET button
// Note: Debounce the reset button to avoid multiple resets and
// to enable timing of how long it has been pressed and held.
iInputVal = digitalRead(A4);
// Serial.println(iInputVal);
ulRstBtnSt_t[iInputVal] = millis();
ulBtnSt_t = ulRstBtnSt_t[iInputVal] - ulRstBtnSt_t[1-iInputVal];
if ((ulBtnSt_t > DEBOUNCE_T) && (iRstBtnSt != iInputVal)) {
iRstBtnSt = iInputVal;
// Serial.print("Reset Button = "); Serial.print(iRstBtnSt); Serial.print(", Bounce Count = "); Serial.println(lBounceCnt);
lBounceCnt = 0;
if (iRstBtnSt == HIGH)
reset_all();
}
if (iInputLastVal != iInputVal)
lBounceCnt += 1;
iInputLastVal = iInputVal;
if ((iRstBtnSt == HIGH) && (ulBtnSt_t > TEST_MODE)) {
if (ulActiveTimeStart == 0) {
for (int color = 0; color < 4; color++){
lLSS[color * LSS_SIZE] = 1; /* set LED profile */
lLSS[(color * LSS_SIZE) + 1] = 0; /* set to step 0 */
lLSS[(color * LSS_SIZE) + 2] = 0; /* reset start time */
lBSS[color * BSS_SIZE] = 1; /* set BTN profile */
lBSS[(color * BSS_SIZE) + 1] = 0; /* set to step 0 */
lBSS[(color * BSS_SIZE) + 2] = 0; /* reset start time */
}
ulActiveTimeStart = ulLoopTime; /* for auto reset after RESET_TIMEOUT_SECONDS */
}
}
if ((iRstBtnSt == HIGH) && (iTest == 0) && (ulBtnSt_t > (TEST_MODE * 2))) {
for (int color = 0; color < 4; color++){
lLSS[color * LSS_SIZE] = 5; /* set LED profile */
if (color == 0) lLSS[(color * LSS_SIZE) + 1] = 0; /* set to step 0 */
if (color == 1) lLSS[(color * LSS_SIZE) + 1] = 13;
if (color == 2) lLSS[(color * LSS_SIZE) + 1] = 43;
if (color == 3) lLSS[(color * LSS_SIZE) + 1] = 79;
lLSS[(color * LSS_SIZE) + 2] = 0; /* reset start time */
lBSS[color * BSS_SIZE] = 1; /* set BTN profile */
lBSS[(color * BSS_SIZE) + 1] = 0; /* set to step 0 */
lBSS[(color * BSS_SIZE) + 2] = 0; /* reset start time */
}
ulActiveTimeStart = ulLoopTime; /* for auto reset after RESET_TIMEOUT_SECONDS */
iTest = 1;
}
// IF game has been active (from the 1st button pressed) more than RESET_TIMEOUT SECONDS, reset
if ((ulActiveTimeStart !=0) && ((ulLoopTime - ulActiveTimeStart) > (RESET_TIMEOUT_SECONDS * 1000)))
reset_all();
// DEBUG - Loop timing
// Seems to take about 0.1 ms to run the entire loop (without print statements)
lLoopCount += 1;
// if (lLoopCount == 100000) {
// ulCurrTime = millis();
// Serial.print("ms for 100,000 loops (ulCurrTime-ulStartTime) ="); Serial.print((ulCurrTime-ulStartTime));
// Serial.print(", ms/loop = "); Serial.println((float) ((float) (ulCurrTime-ulStartTime) / (float) 100000.0),3);
// Serial.print(" ulLoopTime="); Serial.print(ulLoopTime);
// Serial.print(", ulStartTime="); Serial.print(ulStartTime);
// Serial.print(", ulCurrTime="); Serial.print(ulCurrTime);
// Serial.print(", millis()="); Serial.println(millis());
// lLoopCount = 0;
// }
}
© Copyright 2013, V. Boyd
A "Quiz Game" do-it-yourself controller based on an Arduino contoller that implements a "first response" monitor.
You might want to "cut and paste" the code into your Arduino development environment.
Note: The code may appear to be "cut off" on this page, however, if you "cut and paste" it, it will all be there with the full line length.
projectnotions.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com.Copyright 2016 projectnotions. All rights reserved.