#include <Wire.h>
#include <Adafruit_SSD1306.h>
// OLED display resolution
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// OLED display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
// Pin definitions for the buttons, external switch, and LEDs
const int bt_start1 = 2; // Start button 1
const int bt_start2 = 3; // Start button 2
const int bt_stop = 4; // Stop button
const int bt_reset = 5; // Reset button
const int external_switch = 6; // External switch
const int ledPin = 7; // External LED pin
const int onboardLED = 13; // Onboard LED pin
int hh = 0, mm = 0, ss = 0, ms = 0;
bool timerStart = false;
bool lastStart1State = HIGH; // to store the last state of start button 1
bool lastStart2State = HIGH; // to store the last state of start button 2
bool lastStopState = HIGH; // to store the last state of stop button
bool lastResetState = HIGH; // to store the last state of reset button
bool start2Active = false; // To track if Start Button 2 is active
bool externalSwitchState = HIGH; // To store the current state of the external switch
void setup() {
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize OLED display
display.clearDisplay(); // clear the display's memory
display.display(); // update the display
// Set the button pins as inputs
pinMode(bt_start1, INPUT_PULLUP);
pinMode(bt_start2, INPUT_PULLUP);
pinMode(bt_stop, INPUT_PULLUP);
pinMode(bt_reset, INPUT_PULLUP);
pinMode(external_switch, INPUT_PULLUP);
// Set the LED pins as outputs
pinMode(ledPin, OUTPUT);
pinMode(onboardLED, OUTPUT);
noInterrupts(); // disable all interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // set timer count for 1kHz increments
OCR1A = 1999; // = (16*10^6) / (1000*8) - 1
// turn on CTC mode
TCCR1B |= (1 << WGM12); // Set CS11 bit for 8 prescaler
TCCR1B |= (1 << CS11); // enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
interrupts(); // enable interrupts
// Initialize LED states
updateLEDState();
}
void loop() {
bool currentExternalSwitchState = digitalRead(external_switch);
// Check if the external switch state has changed
if (currentExternalSwitchState != externalSwitchState) {
externalSwitchState = currentExternalSwitchState;
updateLEDState();
}
// Handle button presses based on external switch state
if (externalSwitchState == LOW) {
handleExternalSwitchOn();
} else {
handleExternalSwitchOff();
}
// Update display
display.clearDisplay(); // clear the display's memory
display.setTextSize(2); // set text size to 2
display.setTextColor(WHITE); // set text color to white
display.setCursor(12, 5);
display.println("*Sverker*");
display.setCursor(12, 50);
display.println("MM:SS:Mls");
display.setCursor(12, 28);
display.print((mm / 10) % 10);
display.print(mm % 10);
display.print(":");
display.print((ss / 10) % 10);
display.print(ss % 10);
display.print(":");
display.print((ms / 100) % 10);
display.print((ms / 10) % 10);
display.print(ms % 10);
display.display(); // update the display
}
void handleExternalSwitchOn() {
// The LED should be OFF when the external switch is ON
digitalWrite(ledPin, LOW);
digitalWrite(onboardLED, LOW); // Turn off the onboard LED
// Check the state of Start Button 1
bool currentStart1State = digitalRead(bt_start1);
if (currentStart1State == LOW && lastStart1State == HIGH) {
Serial.println("Start button 1 pressed");
ms = 0; ss = 0; mm = 0; hh = 0; // Reset stopwatch
timerStart = true; // Start stopwatch
} else if (currentStart1State == HIGH && lastStart1State == LOW) {
Serial.println("Start button 1 released");
timerStart = false; // Stop stopwatch
}
lastStart1State = currentStart1State;
// Check the state of Stop Button
bool currentStopState = digitalRead(bt_stop);
if (currentStopState != lastStopState) {
Serial.println("Stop button state changed");
timerStart = false; // Stop stopwatch
}
// Check the state of Reset Button
if (digitalRead(bt_reset) == LOW && lastResetState == HIGH) {
Serial.println("Reset button pressed");
ms = 0; ss = 0; mm = 0; hh = 0; // Reset stopwatch
Serial.println("Stopwatch reset to 00:00:00:000");
}
lastResetState = digitalRead(bt_reset);
lastStopState = currentStopState;
}
void handleExternalSwitchOff() {
// Check the state of Start Button 2
bool currentStart2State = digitalRead(bt_start2);
if (currentStart2State == LOW && lastStart2State == HIGH) {
Serial.println("Start button 2 pressed");
start2Active = !start2Active; // Toggle the state of Start Button 2
if (start2Active) {
ms = 0; ss = 0; mm = 0; hh = 0; // Reset stopwatch
timerStart = true; // Start stopwatch
// Turn OFF LED
digitalWrite(ledPin, LOW);
digitalWrite(onboardLED, LOW); // Turn off the onboard LED
Serial.println("LED OFF");
} else {
timerStart = false; // Stop stopwatch
// Ensure LED is ON
digitalWrite(ledPin, HIGH);
digitalWrite(onboardLED, HIGH); // Turn on the onboard LED
Serial.println("LED ON");
}
}
lastStart2State = currentStart2State;
// Check the state of Stop Button
bool currentStopState = digitalRead(bt_stop);
if (currentStopState != lastStopState) {
Serial.println("Stop button state changed");
timerStart = false; // Stop stopwatch
// Ensure LED is ON
digitalWrite(ledPin, HIGH);
digitalWrite(onboardLED, HIGH); // Turn on the onboard LED
Serial.println("LED ON");
}
// Check the state of Reset Button
if (digitalRead(bt_reset) == LOW && lastResetState == HIGH) {
Serial.println("Reset button pressed");
ms = 0; ss = 0; mm = 0; hh = 0; // Reset stopwatch
Serial.println("Stopwatch reset to 00:00:00:000");
}
lastResetState = digitalRead(bt_reset);
lastStopState = currentStopState;
}
// Function to update the LED state based on the external switch
void updateLEDState() {
if (externalSwitchState == LOW) {
// If external switch is ON, LED should be OFF
digitalWrite(ledPin, LOW);
digitalWrite(onboardLED, LOW); // Turn off the onboard LED
Serial.println("External switch ON. LED OFF.");
// Reset timer and stop it
ms = 0; ss = 0; mm = 0; hh = 0; // Reset stopwatch
timerStart = false; // Stop stopwatch
} else {
// If external switch is OFF, LED should be ON
digitalWrite(ledPin, HIGH);
digitalWrite(onboardLED, HIGH); // Turn on the onboard LED
Serial.println("External switch OFF. LED ON.");
// Reset timer and stop it
ms = 0; ss = 0; mm = 0; hh = 0; // Reset stopwatch
timerStart = false; // Stop stopwatch
}
}
ISR(TIMER1_COMPA_vect) {
if (timerStart) {
ms++;
if (ms > 999) {
ms = 0; ss++;
if (ss > 59) {
ss = 0; mm++;
if (mm > 59) {
mm = 0; hh++;
}
}
}
}
}