Arduino Alarm | DS3231 RTC Module, 128x32 I2C OLED Display, Push Button, LED, Buzzer | Example Code
ฝัง
- เผยแพร่เมื่อ 20 ก.ย. 2024
- Arduino Alarm | DS3231 RTC Module, 128x32 I2C OLED Display, Push Button, LED, Buzzer | Example Code
#robot #robotics #engineering #education #educational #school #college #learning #code #coading #diy
Code : code is on the comment below.
Facebook : / doit20-104218935882053
Please Subscribe my Channel. ThankYou!
#include
#include
#include
#include
#include // Include the pitches library for note constants
RTC_DS3231 rtc;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
#define BUTTON_PIN 3
#define UP_BUTTON_PIN 4
#define DOWN_BUTTON_PIN 5
#define LED_PIN 12
#define BUZZER_PIN 11 // Buzzer pin
#define LED_ON_TIME 5000
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
enum State {
NORMAL,
SETTING_ALARM_DATE,
SETTING_ALARM_HOUR,
SETTING_ALARM_MINUTE,
SETTING_ALARM_CONFIRM,
MELODY_PLAYBACK
};
State currentState = NORMAL;
DateTime alarmTime;
DateTime currentTime;
unsigned long alarmActivationTime = 0;
bool updateDisplay = true; // Flag to control display updates
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(UP_BUTTON_PIN, INPUT_PULLUP);
pinMode(DOWN_BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000);
display.clearDisplay();
}
void loop() {
currentTime = rtc.now();
handleButtons();
switch (currentState) {
case NORMAL:
displayNormalView(currentTime);
break;
case SETTING_ALARM_DATE:
case SETTING_ALARM_HOUR:
case SETTING_ALARM_MINUTE:
case SETTING_ALARM_CONFIRM:
displaySettingAlarmView(alarmTime);
break;
case MELODY_PLAYBACK:
playSweetMelody();
break;
}
// Check if the alarm time has been reached
if (checkAlarmTimeReached(currentTime, alarmTime)) {
activateAlarm(); // Activate the alarm
} else {
deactivateAlarm(); // Deactivate the alarm
}
if (updateDisplay) {
display.display();
delay(1000);
display.clearDisplay();
}
}
void handleButtons() {
static unsigned long lastButtonPressTime = 0;
static const unsigned long buttonDebounceDelay = 200;
unsigned long currentMillis = millis();
if (currentMillis - lastButtonPressTime >= buttonDebounceDelay) {
if (digitalRead(BUTTON_PIN) == LOW) {
handleEnterButtonPress();
}
if (currentState == SETTING_ALARM_DATE) {
handleSettingAlarmDateButtons();
} else if (currentState == SETTING_ALARM_HOUR || currentState == SETTING_ALARM_MINUTE) {
handleSettingAlarmTimeButtons();
}
lastButtonPressTime = currentMillis;
}
}
void handleEnterButtonPress() {
switch (currentState) {
case NORMAL:
currentState = SETTING_ALARM_DATE;
alarmTime = currentTime;
break;
case SETTING_ALARM_DATE:
currentState = SETTING_ALARM_HOUR;
break;
case SETTING_ALARM_HOUR:
currentState = SETTING_ALARM_MINUTE;
break;
case SETTING_ALARM_MINUTE:
currentState = SETTING_ALARM_CONFIRM;
break;
case SETTING_ALARM_CONFIRM:
currentState = NORMAL;
// Save the alarm time or take any necessary action
break;
}
}
void handleSettingAlarmDateButtons() {
if (digitalRead(UP_BUTTON_PIN) == LOW) {
incrementDate(alarmTime, 1);
}
if (digitalRead(DOWN_BUTTON_PIN) == LOW) {
decrementDate(alarmTime, 1);
}
}
void handleSettingAlarmTimeButtons() {
if (digitalRead(UP_BUTTON_PIN) == LOW) {
incrementTime(alarmTime, 1);
}
if (digitalRead(DOWN_BUTTON_PIN) == LOW) {
decrementTime(alarmTime, 1);
}
}
void activateAlarm() {
if (currentState == NORMAL && !digitalRead(LED_PIN)) {
digitalWrite(LED_PIN, HIGH); // Turn on the LED
currentState = MELODY_PLAYBACK; // Switch to melody playback state
updateDisplay = false; // Avoid display updates during melody playback
}
}
void deactivateAlarm() {
// Check if the LED has been on for more than 5 seconds
if (digitalRead(LED_PIN) && millis() - alarmActivationTime >= LED_ON_TIME) {
digitalWrite(LED_PIN, LOW); // Turn off the LED
alarmActivationTime = 0; // Reset the activation time
}
}
bool checkAlarmTimeReached(const DateTime ¤t, const DateTime &alarm) {
// Check if all components are equal except for seconds
return (current.year() == alarm.year() &&
current.month() == alarm.month() &&
current.day() == alarm.day() &&
current.hour() == alarm.hour() &&
current.minute() == alarm.minute());
}
void incrementDate(DateTime &dateTime, int days) {
dateTime = dateTime + TimeSpan(days, 0, 0, 0);
}
void decrementDate(DateTime &dateTime, int days) {
dateTime = dateTime - TimeSpan(days, 0, 0, 0);
}
void incrementTime(DateTime &dateTime, int minutes) {
if (currentState == SETTING_ALARM_HOUR) {
dateTime = dateTime + TimeSpan(0, minutes, 0, 0);
} else if (currentState == SETTING_ALARM_MINUTE) {
dateTime = dateTime + TimeSpan(0, 0, minutes, 0);
}
}
void decrementTime(DateTime &dateTime, int minutes) {
if (currentState == SETTING_ALARM_HOUR) {
dateTime = dateTime - TimeSpan(0, minutes, 0, 0);
} else if (currentState == SETTING_ALARM_MINUTE) {
dateTime = dateTime - TimeSpan(0, 0, minutes, 0);
}
}
String dayStr(uint8_t day) {
switch (day) {
case 1:
return "Sunday";
case 2:
return "Monday";
case 3:
return "Tuesday";
case 4:
return "Wednesday";
case 5:
return "Thursday";
case 6:
return "Friday";
case 7:
return "Saturday";
default:
return "Unknown";
}
}
void displayNormalView(DateTime ¤tTime) {
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print(currentTime.year(), DEC);
display.print('/');
display.print(currentTime.month(), DEC);
display.print('/');
display.print(currentTime.day(), DEC);
display.print(" ");
display.print(dayStr(currentTime.dayOfTheWeek()));
display.setTextSize(2);
display.setCursor(0, 18);
display.print(currentTime.hour(), DEC);
display.print(':');
printTwoDigits(currentTime.minute());
display.print(':');
printTwoDigits(currentTime.second());
}
void displaySettingAlarmView(DateTime &alarmTime) {
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
switch (currentState) {
case SETTING_ALARM_DATE:
display.print("Setting Date:");
display.setCursor(0, 20);
display.print(alarmTime.year(), DEC);
display.print('/');
display.print(alarmTime.month(), DEC);
display.print('/');
display.print(alarmTime.day(), DEC);
display.print(" ");
display.print(dayStr(alarmTime.dayOfTheWeek()));
break;
case SETTING_ALARM_HOUR:
display.print("Setting Hour:");
display.setCursor(0, 20);
display.print(alarmTime.hour(), DEC);
break;
case SETTING_ALARM_MINUTE:
display.print("Setting Minute:");
display.setCursor(0, 20);
display.print(alarmTime.hour(), DEC);
display.print(':');
printTwoDigits(alarmTime.minute());
break;
case SETTING_ALARM_CONFIRM:
display.print("Press OK to Confirm");
display.setCursor(0, 40);
display.print("Alarm set for: ");
display.print(alarmTime.year(), DEC);
display.print('/');
display.print(alarmTime.month(), DEC);
display.print('/');
display.print(alarmTime.day(), DEC);
display.print(" ");
display.print(dayStr(alarmTime.dayOfTheWeek()));
display.print(" ");
display.print(alarmTime.hour(), DEC);
display.print(':');
printTwoDigits(alarmTime.minute());
display.print(':');
printTwoDigits(alarmTime.second());
break;
}
}
void printTwoDigits(int number) {
if (number < 10) {
display.print("0");
}
display.print(number);
}
void playSweetMelody() {
static unsigned long melodyStartTime = 0;
static int currentNoteIndex = 0;
int melody[] = {
NOTE_C4, NOTE_E4, NOTE_G4, NOTE_E4,
NOTE_C4, NOTE_D4, NOTE_E4, NOTE_D4,
NOTE_C4, NOTE_E4, NOTE_G4, NOTE_E4,
NOTE_C4, NOTE_D4, NOTE_E4, NOTE_D4
};
int noteDurations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; // Use the same duration for each note
unsigned long currentMillis = millis();
if (currentMillis - melodyStartTime >= (1000 / noteDurations[currentNoteIndex])) {
tone(BUZZER_PIN, melody[currentNoteIndex]);
++currentNoteIndex;
if (currentNoteIndex >= sizeof(melody) / sizeof(melody[0])) {
currentState = NORMAL; // Switch back to the normal state after the melody finishes
noTone(BUZZER_PIN); // Stop the buzzer
updateDisplay = true; // Allow display updates after melody playback
}
melodyStartTime = currentMillis; // Record the start time of the next note
}
}