#include <MD_MAX72xx.h>
#include <MD_Parola.h>
#include "Font_Data.h"
// constants won't change. They're used here to set pin numbers:
const int BUTTON = 2; // the number of the pushbutton pin
const int PRESS_TIME = 1000; // Time for long press (1000 ms = 1 second)
// change these pins to work with your board
#define MAX_DEVICES 3 // Number of LED Matrix
#define CLK_PIN 12 // Clock pin (SCK)
#define CS_PIN 11 // Chip Select pin (SS)
#define DATA_PIN 10 // Data pin (MOSI)
// Change this to work with your matrix
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
int mm = 0, ss = 0, ms = 0;
bool timerStart = false;
char Buffer[3] = " "; // create a buffer to hold the numbers
// Variables will change:
int lastState = LOW; // the previous state from the input pin
int currentState; // the current reading from the input pin
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
bool isPressing = false;
bool isLongDetected = false;
void setup() {
pinMode(BUTTON, INPUT_PULLUP);
P.begin();
P.setIntensity(1); // keep it 3 or below as we are powering off the chip/usb
P.setFont(F4x7straight); // Use a wider font to avoid jumping numbers
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
TCCR1B |= (1 << WGM12); // Set CTC mode
TCCR1B |= (1 << CS11); // enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
interrupts(); // enable interrupts
}
void loop() {
// Read the state of the button:
currentState = digitalRead(BUTTON);
if(lastState == HIGH && currentState == LOW) { // button is pressed
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
else if(lastState == LOW && currentState == HIGH) { // button is released
isPressing = false;
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
// Short press: toggle start/stop of the stopwatch
if( pressDuration < PRESS_TIME && (timerStart == false)) {
timerStart = true; // Start stopwatch
delay(100); // debounce delay
}
else if( pressDuration < PRESS_TIME && (timerStart == true)) {
timerStart = false; // Stop stopwatch
delay(100); // debounce delay
}
}
// Long press: reset the stopwatch
if(isPressing == true && isLongDetected == false) {
long pressDuration = millis() - pressedTime;
if(pressDuration > PRESS_TIME) {
timerStart = false; // Stop stopwatch
ms = 0; ss = 0; mm = 0; // Reset stopwatch
delay(100); // debounce delay
isLongDetected = true;
}
}
if (P.displayAnimate()) {
sprintf(Buffer, "%02d%c%02d", mm, (':'), ss); // Format MM:SS
P.displayText(Buffer, PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
}
// Save the last state
lastState = currentState;
}
ISR(TIMER1_COMPA_vect) {
if(timerStart == true) {
ms = ms + 1;
}
if(ms > 999) {
ms = 0;
ss = ss + 1;
}
if(ss > 59) {
ss = 0;
mm = mm + 1;
}
if(mm > 89) {
timerStart = false; // Stop stopwatch if time exceeds 89 minutes
}
}