/*
Project: Four digit 7 segment stopwatch
Description: Basic stopwatch sketch
Creation date: 10/12/22
Author: AnonEngineering
https://wokwi.com/projects/343741010016207442
https://wokwi.com/projects/345369455239365203
License: Beerware
*/
const int NUM_DIGITS = 4;
const int DP_POS = 1; // where to place decimal point, -1 for none
//const bool COM_ANODE = true; // common anode = true, common cathode = false
const byte DIGIT_PINS[] = {8, 6, 5, 2}; // digit pins, digits 4 - 1 ( Left to right)
const byte SEG_PINS[] = {3, 7, 10, 12, 13, 4, 9}; // segment pins A - G
const byte digitSegVals[10][7] { // [digits 0 - 9], [segments A - G]
{0, 0, 0, 0, 0, 0, 1}, //0
{1, 0, 0, 1, 1, 1, 1}, //1
{0, 0, 1, 0, 0, 1, 0}, //2
{0, 0, 0, 0, 1, 1, 0}, //3
{1, 0, 0, 1, 1, 0, 0}, //4
{0, 1, 0, 0, 1, 0, 0}, //5
{0, 1, 0, 0, 0, 0, 0}, //6
{0, 0, 0, 1, 1, 1, 1}, //7
{0, 0, 0, 0, 0, 0, 0}, //8
{0, 0, 0, 1, 1, 0, 0}, //9
};
const int DP_PIN = 11;
const int RUN_PIN = A5;
const int RST_PIN = A4;
const long DELAY_VAL = 100;
unsigned long prevTime = 0;
unsigned long lastBtn1Time = 0;
unsigned long lastBtn2Time = 0;
bool lastBtn1State = false;
bool lastBtn2State = false;
bool stateOne = false;
bool stateTwo = false;
void setup() {
Serial.begin(9600);
pinMode(RUN_PIN, INPUT_PULLUP);
pinMode(RST_PIN, INPUT_PULLUP);
for(int segVal = 0; segVal < (sizeof(SEG_PINS) / sizeof(SEG_PINS[0])); segVal++) {
pinMode(SEG_PINS[segVal], OUTPUT);
}
for(int digitVal = 0; digitVal < NUM_DIGITS; digitVal++) {
pinMode(SEG_PINS[digitVal], OUTPUT);
}
pinMode(DP_PIN, OUTPUT);
//digitalWrite(DP_PIN, HIGH); // turns DP off
}
void loop() {
static int countVal = 0;
checkButtons();
if(stateOne == true) {
if(millis() - prevTime >= DELAY_VAL) {
prevTime = millis();
showDigits(countVal);
countVal++;
if(countVal >= pow(10, NUM_DIGITS)) countVal = 0; // reset count
}
} else{
showDigits(countVal);
}
if(stateTwo == true) {
countVal = 0;
}
}
void showDigits(int value) {
int digitsToDisplay = 0;
// Leading zero suppression, not great..
//if(value < 10) {
//digitsToDisplay = 0;
//} else if(value < 100) {
if(value < 100) {
digitsToDisplay = 1;
} else if(value < 1000) {
digitsToDisplay = 2;
} else {
digitsToDisplay = 3;
}
for(int digit = digitsToDisplay; digit >= 0; digit--) { // High digits first, higher power first
driveSegments(int(value/pow(10, digit)) % 10); // setup segment pins
if (digit == DP_POS) digitalWrite(DP_PIN, LOW); // turn on DP?
digitalWrite(DIGIT_PINS[digit], HIGH); // turn digit on
digitalWrite(DIGIT_PINS[digit], LOW); // turn digit & DP off
digitalWrite(DP_PIN, HIGH);
}
}
void driveSegments(int digitVal) {
for (int segVal = 0; segVal < (sizeof(SEG_PINS) / sizeof(SEG_PINS[0])); segVal++) {
digitalWrite(SEG_PINS[segVal], digitSegVals[digitVal][segVal]);
}
}
void checkButtons() {
// Read the pushbutton one input pin:
int btn1State = digitalRead(RUN_PIN);
// Compare the button reading to its previous reading
if (btn1State != lastBtn1State) {
// If the reading has changed, update the state based on the reading
if (btn1State == LOW) {
// If the current reading is LOW then the button went from off to on:
stateOne = ! stateOne; //true; // set state one
if(stateOne == true) {
Serial.println(F("Start"));
} else{
Serial.println(F("Stop"));
}
} else {
// If the current state is HIGH then the button went from on to off:
//Serial.println(F("Start released"));
}
// Save the current reading as the last reading, for next time through the loop
lastBtn1State = btn1State;
// Delay a little bit to avoid bouncing
delay(20);
}
// Read the pushbutton two input pin:
int btn2State = digitalRead(RST_PIN);
// Compare the button reading to its previous reading
if (btn2State != lastBtn2State) {
// If the reading has changed, update the state based on the reading
if (btn2State == LOW) {
// If the current reading is LOW then the button went from off to on:
stateTwo = true; // set state two
Serial.println(F("Reset"));
} else {
// If the current state is HIGH then the button went from on to off:
stateTwo = false; // set state two
//Serial.println(F("Reset released"));
}
// Save the current reading as the last reading, for next time through the loop
lastBtn2State = btn2State;
// Delay a little bit to avoid bouncing
delay(20);
}
}