// https://wokwi.com/projects/405684473173069825
// for https://forum.arduino.cc/t/button-counter-stopwatch/1289236/6
// based on
// https://wokwi.com/projects/359393073615174657
#include <Wire.h>
#include <hd44780.h> // https://github.com/duinoWitchery/hd44780
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
//hd44780_I2Cexp lcd(0x27); // declare lcd object: auto locate & auto config expander chip
// or autoconfigure:
hd44780_I2Cexp lcd(0x27); // declare lcd object: auto locate & auto config expander chip
// Configure 2nd LDC in Wokwi with i2c-address per https://docs.wokwi.com/parts/wokwi-lcd1602
hd44780_I2Cexp lcdB; // declare lcd object: auto locate & auto config expander chip
hd44780_I2Cexp lcdC; // declare lcd object: auto locate & auto config expander chip
hd44780_I2Cexp lcdD; // declare lcd object: auto locate & auto config expander chip
const byte ButtonPin = A0;
uint32_t seconds = 0; // remember seconds since boot
uint32_t lastChangeMs, lastPressMs = 0; // button timings
uint32_t maxSecBetweenPresses = 0, lastPressSec = 0;
uint32_t count = 0;
bool dirty = false; // flag for whether the screens need updating
void setup()
{
Serial.begin(115200);
pinMode(ButtonPin, INPUT_PULLUP);
// initialize the LCD
lcd.begin(16, 2);
lcdB.begin(16, 2);
lcdC.begin(16, 2);
lcdD.begin(20, 4);
// Turn on the blacklight and print a message.
lcd.backlight();
lcd.print("MaxTime btwn Presses");
lcdB.backlight();
lcdB.print("Uptime");
lcdC.backlight();
lcdC.print("Elapsed Betwn");
lcdD.backlight();
lcdD.print("Count:");
}
void loop()
{
input();
process();
output();
}
void input() {
const uint32_t interval = 1000;
static uint32_t last = 0;
static int lastButtonState = digitalRead(ButtonPin);
int buttonState = digitalRead(ButtonPin);
uint32_t now = millis();
if (now - last >= interval) {
last += interval;
++seconds;
dirty = true;
}
if (buttonState != lastButtonState && now - lastChangeMs > 10) {
lastButtonState = buttonState;
lastChangeMs = now;
if (lastButtonState == LOW) {
lastPressMs = now;
dirty = true;
if (seconds - lastPressSec > maxSecBetweenPresses ) {
maxSecBetweenPresses = seconds - lastPressSec;
}
lastPressSec = seconds;
++count;
}
}
}
void process() {};
void output() {
if (dirty) {
char buff[80];
uint32_t secs = seconds;
int days = 0, hours = 0, minutes = 0;
//Serial.print(seconds); Serial.print("s ");
dirty = false;
// total elapsed
days = seconds / 86400UL;
hours = (seconds - days * 86400UL) / 3600;
minutes = (seconds - days * 86400UL - hours * 3600UL) / 60;
secs = (seconds - days * 86400UL - hours * 3600UL - minutes * 60UL);
snprintf(buff, 80, " %02d:%02d:%02d:%02d", days, hours, minutes, secs);
lcdB.setCursor(0, 1);
lcdB.print(buff);
secs = seconds - lastPressSec;
days = secs / 86400UL;
secs -= days * 86400UL;
hours = secs / 3600UL;
secs -= hours * 3600UL;
minutes = secs / 60UL;
secs -= minutes * 60UL;
snprintf(buff, 80, " %02d:%02d:%02d:%02d ", days, hours, minutes, secs);
lcdC.setCursor(0, 1);
lcdC.print(buff);
// count
snprintf(buff, 80, " %8ld", count);
lcdD.setCursor(0, 1);
lcdD.print(buff);
secs = maxSecBetweenPresses;
days = secs / 86400UL;
secs -= days * 86400UL;
hours = secs / 3600UL;
secs -= hours * 3600UL;
minutes = secs / 60UL;
secs -= minutes * 60UL;
snprintf(buff, 80, " %02d:%02d:%02d:%02d", days, hours, minutes, secs);
lcd.setCursor(0, 1);
lcd.print(buff);
}
};