// Stopwatch dengan LCD 16x2 I2C
// Tombol Start/Stop di pin 2, Reset di pin 3, LED indikator di pin 13
// LCD I2C: SDA -> A4, SCL -> A5
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // alamat I2C biasanya 0x27, kalau tidak muncul coba 0x3F
const int pinStartStop = 2;
const int pinReset = 3;
const int pinLED = 13;
bool berjalan = false;
unsigned long waktuMulai = 0;
unsigned long totalWaktu = 0;
unsigned long tampilTerakhir = 0;
int statusTombolSebelumnya = LOW;
void setup() {
pinMode(pinStartStop, INPUT);
pinMode(pinReset, INPUT);
pinMode(pinLED, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("STOPWATCH");
lcd.setCursor(0, 1);
lcd.print("00:00.00");
}
void loop() {
int statusTombolStart = digitalRead(pinStartStop);
int statusTombolReset = digitalRead(pinReset);
// Deteksi tombol Start/Stop baru ditekan
if (statusTombolStart == HIGH && statusTombolSebelumnya == LOW) {
if (!berjalan) {
waktuMulai = millis() - totalWaktu;
berjalan = true;
} else {
totalWaktu = millis() - waktuMulai;
berjalan = false;
}
delay(50);
}
statusTombolSebelumnya = statusTombolStart;
// Tombol Reset
if (statusTombolReset == HIGH) {
berjalan = false;
totalWaktu = 0;
waktuMulai = 0;
delay(200);
}
// Hitung waktu berjalan
unsigned long waktuSekarang = berjalan ? (millis() - waktuMulai) : totalWaktu;
digitalWrite(pinLED, berjalan ? HIGH : LOW);
// Update LCD tiap 30ms (biar tidak flicker/kedip berlebihan)
if (millis() - tampilTerakhir >= 30) {
tampilTerakhir = millis();
unsigned long totalDetik = waktuSekarang / 1000;
int menit = totalDetik / 60;
int detik = totalDetik % 60;
int centidetik = (waktuSekarang % 1000) / 10; // 2 digit (centisecond)
lcd.setCursor(0, 1);
if (menit < 10) lcd.print("0");
lcd.print(menit);
lcd.print(":");
if (detik < 10) lcd.print("0");
lcd.print(detik);
lcd.print(".");
if (centidetik < 10) lcd.print("0");
lcd.print(centidetik);
lcd.print(" "); // spasi ekstra buat hapus sisa karakter lama
}
}