/* HW03 Drag Race Xmas Tree using SevSeg library
Date: 9/6/2022
Author n.blizard
*
Purpose - Drag Race
Algorithm - use schematic and some code from Lab03 part 2
Use 3 yellow LEDs, 1 Red LED, 1 Green LED, + curr limit resistors
Use 4 digit 7 segment display
Use pushbutton to initiate the start sequence
use Analog pins since all digital pins are in use for 7 seg display
Steps
make a separate progam (w/o digital timer) for the LED sequencing
then merge the two programs and retests with timer
Setup
turn off all LEDs
blank 7 seg display
initialze -- see function initializeRun
Sequence the Xmas Tree -- see function xmasTreeSequence
Timing and display -- see function runTimingAndDisplay
Add functions
void initializeRun ()
turn on green LED (first step in loop)
wait for user to press button to start run
debounce the button while refreshing display
turn off red LED
Clear 7 segment display
initialize variables:
void xmasTreeSequence ()
turn off green LED
Blink three yellow LEDs in sequence (500 msec cascade, 20 msec delay)
continue to refresh display and checking for cheating (button push)
turn on green LED and ready to start timer
void runTimingAndDisplay ()
record start time
display running time in msec
void checkCheated ()
if button pressed before green light, driver cheated
display "----" (>9999)
light red LED
abort run (goto end of loop)
clear flag
debounce button while still refreshing display
endOfRun
===================== carryovers ======== FIX ME
add 3 functions
void displayTime() - combines minutes and seconds into one number
and display using setNumber()
void waitOneSecondWhileRefreshingTheTime() - continuously
refresh the display using refreshDisplay() lib call while
waiting for one second (1000 msec)
void updateTime() - increment secons and increments minutes if
seconds >= 60 (use mod 60)
(test the math first by using Serialprint func)
loop
3 function calls
*/
#include "SevSeg.h"
#define RED_LIGHT 0 // red light is on pin A1 (index 0 in array)
#define GREEN_LIGHT 4 // green light is on A5 (index 4 in array)
SevSeg sevseg; //Instantiate a seven segment controller object
// globals
//unsigned long msec = 0; // initialize to zero
const int TIME_TICK = 500; // delay between yellow lights (msec)
const int TIME_MAX = 10000; // max display ("----")
//xmas tree specific variables
byte buttonPin = A0;
bool PRESSED = LOW; // low if pressed
byte r3ygLED [] = {A1, A2, A3, A4, A5}; // R Y1 Y2 Y3 G
bool cheatedFlag = false; // set to true if cheated
bool greenFlag = false; // set to true if green light lit
bool abortFlag = false; // set to true if run must be aborted
byte debounceDelay = 100; // msec to prevent multiple messages
unsigned long runningTime = 0;
void setup() {
//sev segment specific variables
byte numDigits = 4;
byte digitPins[] = {2, 3, 4, 5};
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
bool resistorsOnSegments = true; // 'true' means resistors are on segment pins
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
bool updateWithDelays = false; // Default 'false' is Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
// initialize 7 segment display
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
sevseg.setBrightness(90);
sevseg.refreshDisplay(); // Must run repeatedly
// initialize serial print
Serial.begin(9600);
//set input pinMode for button
pinMode(A0, INPUT_PULLUP);
//analogWrite(A0, LOW); // to ensure its low
//set output pinModes for leds (1-5)
for (int j = 0; j < 5; j++) {
pinMode(r3ygLED[j], OUTPUT);
}
}
void loop() {
// this initial press starts the sequence
delay(2000); // between runs
initializeRun ();
//greenFlag = false; // set to true if green light lit, reinitize every run
xmasTreeSequence ();
if (greenFlag) {
runTimingAndDisplay ();
}
else {
Serial.println("..run aborted");
}
}
void initializeRun () {
// initialize variables:
abortFlag = false;
greenFlag = true;
cheatedFlag = false;
// turn on green LED (first step in loop)
Serial.println("-----------------------------------------------");
Serial.println("..ready, get in position, press button to start");
digitalWrite(r3ygLED[GREEN_LIGHT], HIGH);
buttonPressed(); // wait until pressed
// wait for user to press button while refreshing display
// check for cheating (defined as pushing button before green light)
// debounce the button while refreshing display
// turn off red LED
digitalWrite(r3ygLED[RED_LIGHT], LOW);
// Clear 7 segment display
// initialize variables:
}
void xmasTreeSequence () {
// turn off green LED
digitalWrite(r3ygLED[GREEN_LIGHT], LOW);
greenFlag = false; // reset greenFlag to check for cheating
// Blink three yellow LEDs in sequence (500 msec cascade)
// continue to refresh display and checking for cheating (button push)
// turn on green LED
// tests all LEDs in setup
unsigned long futureTime;
for (int j = 1; j < 4; j++) {
futureTime = millis() + TIME_TICK;
digitalWrite(r3ygLED[j], HIGH);
while (millis() < futureTime ) {
cheatingCheck();
}
digitalWrite(r3ygLED[j], LOW);
futureTime = millis() + TIME_TICK;
while (millis() < futureTime ) {
cheatingCheck();
}
}
// assuming made it this far, set greenFlagtrue
if (!cheatedFlag) {
greenFlag = true;
Serial.print("greenFlag = ");
Serial.println(greenFlag);
digitalWrite(r3ygLED[GREEN_LIGHT], HIGH);
}
}
void runTimingAndDisplay () {
long startTime;
if (greenFlag) { // ok to start timer and wait for driver to respond
startTime = millis();
Serial.println("..started Timer");
}
buttonPressed(); // wait for driver response (after seeing green light)
Serial.println("..driver started run");
Serial.println("..press button to stop run");
// call time to display in while loop
while ( analogRead(buttonPin) != PRESSED) { // FIXME FOR BUTTON PUSH TO END
runningTime = millis() - startTime;
displayTime( runningTime ) ;
Serial.println(runningTime);
tooSlow(); // special case if run exceeds max time
if (abortFlag) {
break;
}
}
delay(TIME_TICK);
// update display continously with elapsed time
//buttonPressed(); // wait for driver response at end of run (FIXME replace with a sensor)
long endTime = millis();
long elapsedTime = endTime - startTime;
// stop timer
// record start time
// display running time in msec
// check cheated flag and disqualify (display ----)
endRun ( elapsedTime ); // stop run if button pressed
}
void buttonPressed() {
// int buttonP = analogRead(buttonPin);
// Serial.println("buttonlow");
while (analogRead(buttonPin) != PRESSED) { //digitalRead(BP) goes high if pressed
// hang here until button is pressed
//Serial.println(analogRead(buttonPin));
}
// now execute the following code after button is pressed
//Serial.println("buttonhigh");
//debounce button
delay(TIME_TICK);
// refresh display
refreshDisplay();
}
void refreshDisplay() {
// this function refreshes display while waiting
displayTime( runningTime) ; // display running time
}
void cheatingCheck() {
// this function checks the state of the button and if pressed before the
// green light flag is true, sets the state of cheated to true as well.
// read the state of the button every time this function is called
// do not wait for button to be pressed, if not pressed, move on
if ( (!analogRead(buttonPin)) && !greenFlag) { // button pressed and greenFlag false
Serial.println("YOU CHEATED!");
cheatedFlag = true; // flag that cheating occurred
greenFlag = false; // do not permit to run
abortFlag = true;
cheatedStop(); // call the redlight function
}
delay (debounceDelay);
}
void cheatedStop () {
// display "----" (>9999)
displayTime(TIME_MAX);
// light red LED
// abort run (goto end of loop)
Serial.println ("Cheating Stop");
digitalWrite(r3ygLED[RED_LIGHT], HIGH);
}
void endRun( long elapsedTimer){
Serial.println("..Stopping Run");
Serial.print("..elapsed Time = ");
Serial.print(elapsedTimer);
Serial.println(" msec");
}
void displayTime( unsigned long timeToDisplay ) {
/* Purpose: display timetodisplay using setNumber() and refresh display
*/
sevseg.setNumber(timeToDisplay, 0); // select segment 2 for decimal pt
sevseg.refreshDisplay(); // must refresh after every update
}
void tooSlow( ) {
/*
Purpose: if runningTime >= TIME_MAX, abourt test
and display "----"
*/
if (runningTime >= TIME_MAX) {
Serial.println("..TOO SLOW, GO BACK TO START AND RETRY");
displayTime (runningTime);
abortFlag = true;
}
}
// END OF PROGRAM