Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //pi pico version//
- //PROGRAM BY: RANDY N. CAÑADA
- /*SUBSCRIBE: FB PAGES:
- Playlist.ph:
- https://www.facebook.com/profile.php?id=61573177858722
- Arduino:
- https://www.facebook.com/rhacan2?__tn__=R
- YOUTUBE:
- PlaylistPH
- https://www.youtube.com/@PlaylistPh-h2v
- ElectroCrafters:
- https://www.youtube.com/channel/UCu1aqzUdTqSnTN5BHNlbVgA */
- #include <LiquidCrystal_I2C.h>
- #include <ThreeWire.h>
- #include <RtcDS1302.h>
- LiquidCrystal_I2C lcd(0x27, 16, 2);//sda=4,sda=5 //use your own LCD address. Use I2c scanner
- ThreeWire myWire(10, 11, 12); // DAT=GP10, CLK=GP11, RST=GP12
- RtcDS1302<ThreeWire> Rtc(myWire);
- const int pinCLK = 14;
- const int pinDT = 15;
- const int pinSW = 16;
- const int pinBuzzer = 17;
- enum TimeField {
- NONE, YEAR, MONTH, DAY, HOUR, MINUTE, SECOND,
- ALARM_HOUR, ALARM_MINUTE, DONE
- };
- enum SetupMode { MODE_NONE, MODE_TIME, MODE_ALARM, MODE_MENU };
- SetupMode setupMode = MODE_NONE;
- TimeField currentField = NONE;
- int year, month, day, hour, minute, second;
- int alarmHour = 6;
- int alarmMinute = 0;
- bool settingMode = false;
- bool alarmActive = false;
- bool buzzerOn = false;
- bool alarmDismissed = false;
- unsigned long buzzerStartTime = 0;
- const unsigned long buzzerDuration = 10000;
- int lastEncoded = 0;
- unsigned long lastRotateTime = 0;
- const unsigned long rotateDebounce = 170;
- bool swHeld = false;
- bool longPressTriggered = false;
- unsigned long swPressStart = 0;
- const unsigned long longPressDuration = 1000;
- int lastSecond = -1;
- TimeField lastField = NONE;
- int lastValue = -1;
- int menuIndex = 0; // 0 = Set Time, 1 = Set Alarm
- void setup() {
- Wire.setSDA(4);
- Wire.setSCL(5);
- lcd.init();
- lcd.backlight();
- Rtc.Begin();
- // Load RTC values into vars
- RtcDateTime now = Rtc.GetDateTime();
- year = now.Year();
- month = now.Month();
- day = now.Day();
- hour = now.Hour();
- minute = now.Minute();
- second = now.Second();
- pinMode(pinCLK, INPUT_PULLUP);
- pinMode(pinDT, INPUT_PULLUP);
- pinMode(pinSW, INPUT_PULLUP);
- pinMode(pinBuzzer, OUTPUT);
- digitalWrite(pinBuzzer, LOW);
- Serial.begin(9600);
- }
- void loop() {
- RtcDateTime now = Rtc.GetDateTime();
- // Reset alarmDismissed when minute changes
- static int lastAlarmMinute = -1;
- if (now.Minute() != lastAlarmMinute) {
- alarmDismissed = false;
- lastAlarmMinute = now.Minute();
- }
- // Trigger alarm
- if (alarmActive && !alarmDismissed && now.Hour() == alarmHour && now.Minute() == alarmMinute && !buzzerOn) {
- buzzerOn = true;
- buzzerStartTime = millis();
- digitalWrite(pinBuzzer,HIGH);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Alarm Ringing!");
- }
- // Auto-silence
- if (buzzerOn && millis() - buzzerStartTime > buzzerDuration) {
- buzzerOn = false;
- alarmDismissed = true;
- digitalWrite(pinBuzzer, LOW);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Alarm Stopped");
- }
- // Manual silence
- if (buzzerOn && digitalRead(pinSW) == LOW) {
- buzzerOn = false;
- alarmDismissed = true;
- digitalWrite(pinBuzzer, LOW);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Alarm Stopped");
- delay(1000);
- }
- // ---------------- Idle mode ----------------
- if (!settingMode) {
- if (now.Second() != lastSecond) {
- lastSecond = now.Second();
- char dateBuffer[11];
- sprintf(dateBuffer, "%02d/%02d/%04d", now.Day(), now.Month(), now.Year());
- char timeBuffer[9];
- sprintf(timeBuffer, "%02d:%02d:%02d", now.Hour(), now.Minute(), now.Second());
- lcd.setCursor(0, 0);
- lcd.print("Date: "); lcd.print(dateBuffer); lcd.print(" ");
- lcd.setCursor(0, 1);
- lcd.print("Time: "); lcd.print(timeBuffer); lcd.print(" ");
- }
- // Long press → enter menu
- if (digitalRead(pinSW) == LOW) {
- if (!swHeld) {
- swPressStart = millis();
- swHeld = true;
- longPressTriggered = false;
- } else if (!longPressTriggered && millis() - swPressStart > longPressDuration) {
- settingMode = true;
- longPressTriggered = true;
- setupMode = MODE_MENU;
- menuIndex = 0;
- showMenu();
- delay(500);
- }
- } else {
- swHeld = false;
- }
- return;
- }
- // ---------------- Menu ----------------
- if (setupMode == MODE_MENU) {
- handleMenu();
- } else {
- handleEditing();
- }
- }
- // ---------------- Menu Functions ----------------
- void showMenu() {
- lcd.setCursor(0, 0);
- lcd.print(menuIndex == 0 ? "> Set Time " : " Set Time "); // add spaces to clear leftover
- lcd.setCursor(0, 1);
- lcd.print(menuIndex == 1 ? "> Set Alarm " : " Set Alarm "); // add spaces
- }
- void handleMenu() {
- // Rotary encoder
- int MSB = digitalRead(pinCLK);
- int LSB = digitalRead(pinDT);
- int encoded = (MSB << 1) | LSB;
- int sum = (lastEncoded << 2) | encoded;
- if (millis() - lastRotateTime > rotateDebounce) {
- if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) {
- menuIndex = (menuIndex + 1) % 2;
- lastRotateTime = millis();
- } else if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) {
- menuIndex = (menuIndex == 0) ? 1 : 0;
- lastRotateTime = millis();
- }
- showMenu();
- }
- lastEncoded = encoded;
- // Short press → select
- if (digitalRead(pinSW) == LOW && !swHeld && !longPressTriggered) {
- swHeld = true;
- if (menuIndex == 0) { // Set Time
- setupMode = MODE_TIME;
- currentField = YEAR;
- lcd.clear();
- lcd.setCursor(0, 0); lcd.print("Set Time");
- } else { // Set Alarm
- setupMode = MODE_ALARM;
- currentField = ALARM_HOUR;
- lcd.clear();
- lcd.setCursor(0, 0); lcd.print("Set Alarm");
- }
- delay(500);
- lastField = NONE; // force LCD update
- lastValue = -1;
- } else if (digitalRead(pinSW) == HIGH) {
- swHeld = false;
- longPressTriggered = false;
- }
- }
- // ---------------- Editing Functions ----------------
- void handleEditing() {
- int MSB = digitalRead(pinCLK);
- int LSB = digitalRead(pinDT);
- int encoded = (MSB << 1) | LSB;
- int sum = (lastEncoded << 2) | encoded;
- if (millis() - lastRotateTime > rotateDebounce) {
- if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) { incrementField(currentField); lastRotateTime = millis();}
- if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) { decrementField(currentField); lastRotateTime = millis();}
- }
- lastEncoded = encoded;
- // LCD update
- int currentValue = getFieldValue(currentField);
- if (currentField != lastField || currentValue != lastValue) {
- lastField = currentField;
- lastValue = currentValue;
- lcd.setCursor(0, 0);
- if (currentField == DONE) {
- lcd.print("Press to Save ");
- lcd.setCursor(0, 1);
- lcd.print(" ");
- } else {
- lcd.print("Set "); lcd.print(fieldName(currentField)); lcd.print(" ");
- lcd.setCursor(0, 1);
- lcd.print("Value: "); lcd.print(paddedValue(currentField)); lcd.print(" ");
- }
- }
- // Short press confirm
- if (digitalRead(pinSW) == LOW && !swHeld && !longPressTriggered) {
- swHeld = true;
- if (setupMode == MODE_TIME) {
- if (currentField == SECOND) currentField = DONE;
- else currentField = static_cast<TimeField>(currentField + 1);
- } else if (setupMode == MODE_ALARM) {
- if (currentField == ALARM_MINUTE) currentField = DONE;
- else currentField = static_cast<TimeField>(currentField + 1);
- }
- lastField = NONE;
- if (currentField == DONE) {
- if (setupMode == MODE_TIME) {
- RtcDateTime newTime(year, month, day, hour, minute, second);
- Rtc.SetDateTime(newTime);
- lcd.clear(); lcd.print("Time Saved!");
- } else if (setupMode == MODE_ALARM) {
- alarmActive = true;
- lcd.clear(); lcd.print("Alarm Saved!");
- }
- delay(1000);
- setupMode = MODE_NONE;
- settingMode = false;
- currentField = NONE;
- lastSecond = -1;
- }
- delay(300);
- } else if (digitalRead(pinSW) == HIGH) {
- swHeld = false; longPressTriggered = false;
- }
- }
- // ---------------- Utility Functions ----------------
- String fieldName(TimeField field) {
- switch (field) {
- case YEAR: return "Year"; case MONTH: return "Month"; case DAY: return "Day";
- case HOUR: return "Hour"; case MINUTE: return "Minute"; case SECOND: return "Second";
- case ALARM_HOUR: return "AlarmHr"; case ALARM_MINUTE: return "AlarmMin";
- default: return "";
- }
- }
- String paddedValue(TimeField field) {
- char buffer[5];
- int value = getFieldValue(field);
- if (field == YEAR) sprintf(buffer, "%04d", value);
- else sprintf(buffer, "%02d", value);
- return String(buffer);
- }
- int getFieldValue(TimeField field) {
- switch (field) {
- case YEAR: return year; case MONTH: return month; case DAY: return day;
- case HOUR: return hour; case MINUTE: return minute; case SECOND: return second;
- case ALARM_HOUR: return alarmHour; case ALARM_MINUTE: return alarmMinute;
- default: return 0;
- }
- }
- void incrementField(TimeField field) {
- switch (field) {
- case YEAR: year++; break;
- case MONTH: month = (month % 12) + 1; break;
- case DAY: day = (day % 31) + 1; break;
- case HOUR: hour = (hour + 1) % 24; break;
- case MINUTE: minute = (minute + 1) % 60; break;
- case SECOND: second = (second + 1) % 60; break;
- case ALARM_HOUR: alarmHour = (alarmHour + 1) % 24; break;
- case ALARM_MINUTE: alarmMinute = (alarmMinute + 1) % 60; break;
- default: break;
- }
- }
- void decrementField(TimeField field) {
- switch (field) {
- case YEAR: year = max(2000, year - 1); break;
- case MONTH: month = (month == 1) ? 12 : month - 1; break;
- case DAY: day = (day == 1) ? 31 : day - 1; break;
- case HOUR: hour = (hour == 0) ? 23 : hour - 1; break;
- case MINUTE: minute = (minute == 0) ? 59 : minute - 1; break;
- case SECOND: second = (second == 0) ? 59 : second - 1; break;
- case ALARM_HOUR: alarmHour = (alarmHour == 0) ? 23 : alarmHour - 1; break;
- case ALARM_MINUTE: alarmMinute = (alarmMinute == 0) ? 59 : alarmMinute - 1; break;
- default: break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment