[1:34 PM] KYLE JOSHUA EINSTERN MANECLANG
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <Keypad.h>
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <queue>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int button = 8;
bool buttonState = false;
const int buzzer = 9;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {22, 24, 26, 28};
byte colPins[COLS] = {30, 32, 34, 36};
const int maxInput = 16;
char inputArray[maxInput];
int arrayIndex = 0;
static int cursorPos = 0;
static char inputBuffer[5];
struct Alarm {
int hour;
int minute;
bool enabled;
};
Alarm alarms[3];
int currentAlarm = 0;
SemaphoreHandle_t interruptSemaphore1;
SemaphoreHandle_t interruptSemaphore2;
QueueHandle_t queue1;
TaskHandle_t TaskHandel_1;
TaskHandle_t TaskHandel_3;
void Task1(void *pvParameters);
void Task2(void *pvParameters);
void Task3(void *pvParameters);
void setup() {
rtc.begin();
pinMode(buzzer, OUTPUT);
pinMode(button, INPUT);
lcd.init();
lcd.backlight();
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press '*' to set");
lcd.setCursor(0, 1);
lcd.print("alarm time");
interruptSemaphore1 = xSemaphoreCreateBinary();
interruptSemaphore2 = xSemaphoreCreateBinary();
queue1 = xQueueCreate(1, sizeof(Alarm));
xTaskCreate(Task1, "Real_Time_Clock", 128, NULL, 2, &TaskHandel_1);
xTaskCreate(Task2, "Set_Alarm", 128, NULL, 2, NULL);
xTaskCreate(Task3, "Buzzer_On", 128, NULL, 1, &TaskHandel_3);
}
void loop() {}
void Task1(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(interruptSemaphore1, portMAX_DELAY) == pdPASS) {
if (xSemaphoreTake(interruptSemaphore2, portMAX_DELAY) == pdPASS) {
DateTime now = rtc.now();
char key = keypad.getKey();
static unsigned long lastDisplayTime = 0;
if (millis() - lastDisplayTime >= 1000) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Current Time:");
lcd.setCursor(0, 1);
lcd.print(now.hour(), DEC);
lcd.print(":");
lcd.print(now.minute(), DEC);
lcd.print(":");
lcd.print(now.second(), DEC);
lastDisplayTime = millis();
}
for (int i = 0; i < 3; i++) {
if (alarms[i].enabled && now.hour() == alarms[i].hour && now.minute() == alarms[i].minute) {
xSemaphoreGive(interruptSemaphore1);
vTaskResume(TaskHandel_3);
}
}
if (key == '*') {
xSemaphoreGive(interruptSemaphore2);
vTaskDelay(100);
}
}
}
}
}
void Task2(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(interruptSemaphore2, portMAX_DELAY) == pdPASS) {
DateTime now = rtc.now();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Alarm " + String(currentAlarm + 1) + ":");
lcd.setCursor(0, 1);
lcd.print("HH:MM");
char key = NO_KEY;
while (key != '#') {
key = keypad.getKey();
if (key != NO_KEY) {
if (((inputBuffer[0] - '0') * 10 + (inputBuffer[1] - '0') <= 23) && (((inputBuffer[3] - '0') * 10) <= 50)) {
if (key >= '0' && key <= '9') {
inputBuffer[cursorPos] = key;
lcd.setCursor(cursorPos, 1);
lcd.print(key);
cursorPos++;
if (cursorPos == 2) {
cursorPos += 1;
}
if (cursorPos == 5)
break;
}
else if (key == '*') {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Alarm " + String(currentAlarm + 1) + ":");
lcd.setCursor(0, 1);
lcd.print("HH:MM");
cursorPos = 0;
}
else if (key == 'D'){
deleteLastCharacter();
lcd.setCursor(cursorPos, 1);
}
else if (key == 'C'){
clearArray();
clearLCD();
}
}
else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("error");
vTaskDelay(500/portTICK_PERIOD_MS);
xSemaphoreGive(interruptSemaphore2);
}
}
}
if (cursorPos == 5) {
alarms[currentAlarm].hour = (inputBuffer[0] - '0') * 10 + (inputBuffer[1] - '0');
alarms[currentAlarm].minute = (inputBuffer[3] - '0') * 10 + (inputBuffer[4] - '0');
alarms[currentAlarm].enabled = true;
lcd.setCursor(0, 1);
lcd.print("Alarm set ");
vTaskDelay(1000/portTICK_PERIOD_MS);
lcd.clear();
currentAlarm++;
if (currentAlarm >= 3) {
currentAlarm = 0;
}
}
lcd.setCursor(0, 0);
lcd.print("Press '*' to set");
lcd.setCursor(0, 1);
lcd.print("alarm time");
vTaskDelay(3000/portTICK_PERIOD_MS);
cursorPos = 0;
}
}
}
void Task3(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(interruptSemaphore1, portMAX_DELAY) == pdPASS) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALARM " + String(currentAlarm + 1) + "!");
vTaskDelay(2000/portTICK_PERIOD_MS);
tone(buzzer, 500, 200);
vTaskDelay(1000/portTICK_PERIOD_MS);
tone(buzzer, 1000, 200);
vTaskDelay(1000/portTICK_PERIOD_MS);
tone(buzzer, 2000, 200);
vTaskDelay(1000/portTICK_PERIOD_MS);
tone(buzzer, 3000, 200);
vTaskDelay(1000/portTICK_PERIOD_MS);
tone(buzzer, 4000, 200);
vTaskDelay(1000/portTICK_PERIOD_MS);
buttonState = digitalRead(button);
if (buttonState == HIGH) {
xSemaphoreGive(interruptSemaphore1);
vTaskSuspend(NULL);
vTaskResume(TaskHandel_1);
}
}
}
}