/*
Wokwi | projects
Need help with a speaker with lcd screen
armin Wednesday, December 10, 2025 6:30 PM
i really dont know what i did wrong, im new to this,
so any help would come in handy.
https://wokwi.com/projects/449989709560970241
*/
#include <Wire.h>
#include <LiquidCrystal.h>
#include <RTClib.h>
#include "melodyPlayer.h"
const int NUM_BTNS = 3;
const int BTN_PINS[NUM_BTNS] = {3, 4, 5};
const char BTN_NAMES[3][5] = {"Set", "Down", "Up"};
const char WEEK_DAY_NAMES[7][4] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
const byte bell[8] = {
0b00100, // Row 1
0b01110, // Row 2
0b01110, // Row 3
0b01110, // Row 4
0b11111, // Row 5
0b00000, // Row 6
0b00100, // Row 7
0b00000 // Row 8
};
bool isAlarmOn = false;
bool isPlaying = false;
int state = 0;
int alarmHour = 0;
int alarmMin = 0;
int btnState[NUM_BTNS];
int oldBtnState[NUM_BTNS];
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
RTC_DS1307 rtc;
// function returns which button was pressed, or 0 if none
int checkButtons() {
int btnPressed = 0;
for (int i = 0; i < NUM_BTNS; i++) {
btnState[i] = digitalRead(BTN_PINS[i]); // check each button
if (btnState[i] != oldBtnState[i]) { // if it changed
oldBtnState[i] = btnState[i]; // remember state for next time
if (btnState[i] == 0) { // was just pressed
btnPressed = i + 1;
Serial.print(BTN_NAMES[i]);
Serial.println(" pressed.");
}
delay(20); // debounce
}
}
return btnPressed;
}
void setAlarmMode(int button) {
char dispBuffer[16];
if (button == 2 || button == 3) {
isAlarmOn = !isAlarmOn;
}
lcd.setCursor(1, 0);
if (isAlarmOn) {
lcd.print("Set alarm: ON ");
lcd.setCursor(15, 0);
lcd.write((byte)0);
lcd.setCursor(5, 1);
snprintf(dispBuffer, 15, "%2d:%02d", alarmHour, alarmMin);
lcd.print(dispBuffer);
} else {
lcd.print("Set alarm: OFF");
lcd.setCursor(15, 0);
lcd.print(' ');
}
}
void setAlarmHour(int button) {
char dispBuffer[16];
if (button == 3 ) {
alarmHour++;
if (alarmHour > 23) {
alarmHour = 0;
}
} else if (button == 2 ) {
alarmHour--;
if (alarmHour < 0) {
alarmHour = 23;
}
}
// Display the alarm time on the LCD
lcd.setCursor(1, 0);
lcd.print("Set alarm hour");
lcd.setCursor(5, 1);
snprintf(dispBuffer, 15, "%2d:%02d", alarmHour, alarmMin);
lcd.print(dispBuffer);
}
void setAlarmMinute(int button) {
char dispBuffer[16];
if (button == 3 ) {
alarmMin++;
if (alarmMin > 59) {
alarmMin = 0;
}
} else if (button == 2 ) {
alarmMin--;
if (alarmMin < 0) {
alarmMin = 59;
}
}
// Display the alarm time on the LCD
lcd.setCursor(0, 0);
lcd.print("Set alarm minute");
lcd.setCursor(5, 1);
snprintf(dispBuffer, 16, "%2d:%02d", alarmHour, alarmMin);
lcd.print(dispBuffer);
}
void showSplash() {
lcd.setCursor(1, 0);
lcd.print("LCD Alarm Clock");
lcd.setCursor(6, 1);
lcd.print("V1.0");
delay(2000);
lcd.clear();
}
void showTime(DateTime currTime) {
char dispBuffer[16];
lcd.setCursor(4, 0);
snprintf(dispBuffer, 10, "%2d:%02d:%02d",
currTime.hour(), currTime.minute(), currTime.second());
lcd.print(dispBuffer);
lcd.setCursor(1, 1);
snprintf(dispBuffer, 16, "%s %2d/%2d/%4d",
WEEK_DAY_NAMES[currTime.dayOfTheWeek()],
currTime.month(), currTime.day(), currTime.year());
lcd.print(dispBuffer);
if (isAlarmOn) {
lcd.setCursor(15, 0);
lcd.write((byte)0);
} else {
lcd.setCursor(15, 0);
lcd.print(' ');
}
}
void soundAlarm() {
startMelody();
}
void setup() {
Serial.begin(115200);
lcd.begin(16, 2);
lcd.createChar(0, bell);
rtc.begin();
// Set the time of RTC if it's not set
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
for (int i = 0; i < NUM_BTNS; i++) {
pinMode(BTN_PINS[i], INPUT_PULLUP);
}
pinMode(BUZZER_PIN, OUTPUT);
showSplash();
Serial.println("Setup complete!\n");
//startMelody(); // for test
}
void loop() {
DateTime now = rtc.now();
// Keep the melody running
//bool isPlaying = updateMelody();
updateMelody();
int btnNum = checkButtons();
if (btnNum) lcd.clear();
if (btnNum == 1) {
state++;
if ((state == 2 || state == 3) && !isAlarmOn) state = 0;
if (state == 4) state = 0;
}
if (state == 0) {
showTime(now);
} else if (state == 1) {
// set alarm on / off
setAlarmMode(btnNum);
} else if (state == 2) {
// set alarm hour
setAlarmHour(btnNum);
} else if (state == 3) {
// set alarm minute
setAlarmMinute(btnNum);
}
// Check if the alarm time is reached
//if (isAlarmOn && !isPlaying) {
//if (isAlarmOn) {
if (now.hour() == alarmHour && now.minute() == alarmMin && now.second() == 0) {
//if (now.hour() == alarmHour && now.minute() == alarmMin && now.second() == 0 && !isPlaying) {
if (isAlarmOn && !isPlaying) {
soundAlarm();
//Serial.println("Here");
isPlaying = true;
}
} else {
isPlaying = false;
}
}
//}
Up
Down
Set