#include <Arduino.h>
#include <Wire.h> // Library untuk komunikasi I2C
#include <LiquidCrystal_I2C.h> // Library untuk LCD I2C
// Definisikan pin untuk tombol
const int setTimeButtonPin = PA0; // Tombol untuk mengatur waktu
const int startPauseButtonPin = PA1; // Tombol untuk memulai/menjeda
const int resetButtonPin = PA2; // Tombol untuk reset
// Variabel untuk menyimpan status tombol sebelumnya (untuk debounce)
bool lastSetTimeButtonState = LOW;
bool lastStartPauseButtonState = LOW;
bool lastResetButtonState = LOW;
// Variabel untuk timer
volatile int countdownTime = 0; // Waktu hitungan mundur dalam detik
volatile bool timerRunning = false; // Status timer (berjalan/jeda)
unsigned long previousMillis = 0; // Untuk tracking waktu (millisecond)
const long interval = 1000; // Interval 1 detik
// Inisialisasi objek LCD I2C
// Alamat I2C umum adalah 0x27 atau 0x3F. Jika tidak berfungsi, coba ganti alamat ini.
// Format: LiquidCrystal_I2C(alamat_i2c, kolom, baris)
LiquidCrystal_I2C lcd(0x3F, 16, 2); // Contoh: 0x27 adalah alamat I2C, 16 kolom, 2 baris
void setup() {
// Inisialisasi Serial untuk debugging (opsional, bisa dihapus jika tidak dipakai)
Serial.begin(115200);
// Inisialisasi LCD
lcd.init(); // Inisialisasi modul LCD
lcd.backlight(); // Nyalakan backlight LCD
lcd.clear(); // Bersihkan tampilan LCD
lcd.setCursor(0, 0); // Atur kursor ke kolom 0, baris 0
lcd.print("Timer STM32");
lcd.setCursor(0, 1); // Atur kursor ke kolom 0, baris 1
lcd.print("Siap!");
// Konfigurasi pin tombol sebagai input
pinMode(setTimeButtonPin, INPUT);
pinMode(startPauseButtonPin, INPUT);
pinMode(resetButtonPin, INPUT);
delay(2000); // Tunda sebentar agar pesan awal terlihat
updateLCD(); // Perbarui tampilan LCD
}
void loop() {
// Baca status tombol saat ini
bool currentSetTimeButton = digitalRead(setTimeButtonPin);
bool currentStartPauseButton = digitalRead(startPauseButtonPin);
bool currentResetButton = digitalRead(resetButtonPin);
// Deteksi tepi naik untuk Tombol Atur Waktu (dengan debounce)
if (currentSetTimeButton == HIGH && lastSetTimeButtonState == LOW) {
delay(50); // Debounce
if (digitalRead(setTimeButtonPin) == HIGH) { // Pastikan tombol masih ditekan
countdownTime += 5; // Tambah 5 detik
if (countdownTime > 999) countdownTime = 999; // Batasi waktu maks
timerRunning = false; // Hentikan timer saat waktu diatur ulang
updateLCD();
}
}
lastSetTimeButtonState = currentSetTimeButton;
// Deteksi tepi naik untuk Tombol Mulai/Jeda (dengan debounce)
if (currentStartPauseButton == HIGH && lastStartPauseButtonState == LOW) {
delay(50); // Debounce
if (digitalRead(startPauseButtonPin) == HIGH) {
if (countdownTime > 0) { // Hanya bisa mulai jika ada waktu
timerRunning = !timerRunning; // Toggle status timer
updateLCD();
} else {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Atur Waktu Dulu!");
delay(1500);
updateLCD();
}
}
}
lastStartPauseButtonState = currentStartPauseButton;
// Deteksi tepi naik untuk Tombol Reset (dengan debounce)
if (currentResetButton == HIGH && lastResetButtonState == LOW) {
delay(50); // Debounce
if (digitalRead(resetButtonPin) == HIGH) {
countdownTime = 0; // Reset waktu ke 0
timerRunning = false; // Hentikan timer
updateLCD();
}
}
lastResetButtonState = currentResetButton;
// Logika hitungan mundur
if (timerRunning && countdownTime > 0) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
countdownTime--;
updateLCD();
if (countdownTime == 0) {
timerRunning = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WAKTU HABIS!");
lcd.setCursor(0, 1);
lcd.print("Reset / Set Waktu");
}
}
}
}
// Fungsi untuk memperbarui tampilan LCD
void updateLCD() {
lcd.clear(); // Bersihkan tampilan sebelumnya
lcd.setCursor(0, 0); // Baris pertama
lcd.print("Waktu: ");
// Format tampilan waktu ke MM:SS jika lebih dari 60 detik
if (countdownTime >= 60) {
int minutes = countdownTime / 60;
int seconds = countdownTime % 60;
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
lcd.print(" (MM:SS)");
} else {
lcd.print(countdownTime);
lcd.print(" detik");
}
lcd.setCursor(0, 1); // Baris kedua
if (!timerRunning && countdownTime > 0) {
lcd.print("DIJEDA");
} else if (!timerRunning && countdownTime == 0) {
lcd.print("SIAP (0 detik)");
} else {
lcd.print("BERJALAN");
}
}