RTC3231 Alarm Clock Coding

Hello. I have a problem on setting the alarm clock. I'm using Arduino Mega, DS3231 RTC, LCD I2C, and a buzzer. Regarding on the coding below, I tried inserting alarm clock coding, declared the alarm, and put alarm and buzzer code into void setup(). I just want to know how and where to set and trigger the alarm clock code, that's all.

The codes below are my attempt to make alarm clock works. The clock displays well, but not for alarm clock. Seems like I'm missing something.

#include <Wire.h>
#include "ds3231.h"
#include <LiquidCrystal_I2C.h>
#undef int()               //For stdio
#include <stdio.h>         //For sprintf
#define BUFF_MAX 128
#ifndef __rtc_3231_h_
#define __rtc_3231_h_

void parse_cmd(char *cmd, int cmdsize);
void set_alarm(char *cmd, int cmdsize);

#endif

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;
uint8_t time[8];

// time when to wake up
uint8_t wake_HOUR = 15;
uint8_t wake_MINUTE = 49;
uint8_t wake_SECOND = 9;

void setup()
{
   //real time clock
   Serial.begin(9600);
   Wire.begin();
   DS3231_init(DS3231_INTCN);
   memset(recv, 0, BUFF_MAX);
   Serial.println("GET time");
   lcd.begin(16, 2);
   lcd.clear();
   
   Serial.println("Setting time");     //To set time manually
   parse_cmd("T010101101012016",16);   //TSSMMHHWDDMMYYYY

   //alarm
    DS3231_clear_a2f(); 
    set_alarm();
    
   //buzzer
    pinMode(15, OUTPUT);
}

void loop()
{
   char in;
   char tempF[6];  
   float temperature;
   char buff[BUFF_MAX];
   unsigned long now = millis();
   struct ts t;

   // show time once in a while
   if ((now - prev > interval) && (Serial.available() <= 0)) 
   {
       DS3231_get(&t); //Get time
       parse_cmd("C",1);
       temperature = DS3231_get_treg(); //Get temperature
       dtostrf(temperature, 5, 1, tempF);

       lcd.clear();
       lcd.setCursor(1,0);
       
       lcd.print(t.mday);
       
       printMonth(t.mon);
       
       lcd.print(t.year);
       
       lcd.setCursor(0,1); //Go to second line of the LCD Screen
       lcd.print(t.hour);
       lcd.print(":");
       if(t.min<10)
       {
         lcd.print("0");
       }
       lcd.print(t.min);
       lcd.print(":");
       if(t.sec<10)
       {
         lcd.print("0");
       }
       lcd.print(t.sec);
       
       lcd.print(' ');
       lcd.print(tempF);
       lcd.print((char)223);
       lcd.print("C ");
       prev = now;
   }

   if ((now - prev > interval) && (Serial.available() <= 0)) {
       DS3231_get(&t);

       // display current time
       snprintf(buff, BUFF_MAX, "%d.%02d.%02d %02d:%02d:%02d", t.year,
            t.mon, t.mday, t.hour, t.min, t.sec);
       Serial.println(buff);

       // display a1 debug info
       DS3231_get_a1(&buff[0], 59);
       Serial.println(buff);

       if (DS3231_triggered_a1()) {
           // INT has been pulled low
           Serial.println(" -> alarm1 has been triggered");
           // clear a1 alarm flag and let INT go into hi-z
           DS3231_clear_a1f();
       }
       prev = now;
   }

   
   if (Serial.available() > 0) 
   {
       in = Serial.read();

       if ((in == 10 || in == 13) && (recv_size > 0)) 
       {
           parse_cmd(recv, recv_size);
           recv_size = 0;
           recv[0] = 0;
       } 
       else if (in < 48 || in > 122) 
       {;
        // ignore ~[0-9A-Za-z]
       } 
       else if (recv_size > BUFF_MAX - 2) 
       {   // drop lines that are too long
           // drop
           recv_size = 0;
           recv[0] = 0;
       } 
       else if (recv_size < BUFF_MAX - 2) 
       {
           recv[recv_size] = in;
           recv[recv_size + 1] = 0;
           recv_size += 1;
       }
   }
}

void parse_cmd(char *cmd, int cmdsize)
{
   uint8_t i;
   uint8_t reg_val;
   char buff[BUFF_MAX];
   struct ts t;

   snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
   Serial.print(buff);

   // TssmmhhWDDMMYYYY aka set time
   if (cmd[0] == 84 && cmdsize == 16) 
   {
       //T010201101012016
       t.sec = inp2toi(cmd, 1);
       t.min = inp2toi(cmd, 3);
       t.hour = inp2toi(cmd, 5);
       t.wday = inp2toi(cmd, 7);
       t.mday = inp2toi(cmd, 8);
       t.mon = inp2toi(cmd, 10);
       t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
       DS3231_set(t);
       Serial.println("OK");
   } 
   
   else if (cmd[0] == 49 && cmdsize == 1) 
   {  // "1" get alarm 1
       DS3231_get_a1(&buff[0], 59);
       Serial.println(buff);
   } 
  
   else if (cmd[0] == 50 && cmdsize == 1) 
   {  // "2" get alarm 1
       DS3231_get_a2(&buff[0], 59);
       Serial.println(buff);
   } 
   
   else if (cmd[0] == 51 && cmdsize == 1) 
   {  // "3" get aging register
       Serial.print("aging reg is ");
       Serial.println(DS3231_get_aging(), DEC);
   } 
   
   else if (cmd[0] == 65 && cmdsize == 9) 
   {   //"A" set alarm 1
       DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
       //ASSMMHHDD
       //A00010101
       
       for (i = 0; i < 4; i++) {
           time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
       }
       byte flags[5] = { 0, 0, 0, 0, 0 };
       DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
       DS3231_get_a1(&buff[0], 59);
       Serial.println(buff);
   } 
   
   else if (cmd[0] == 66 && cmdsize == 7) 
   {  // "B" Set Alarm 2
       DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
       //BMMHHDD
       
       for (i = 0; i < 4; i++) 
       {
           time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
       }
       byte flags[5] = { 0, 0, 0, 0 };
       DS3231_set_a2(time[0], time[1], time[2], flags);
       DS3231_get_a2(&buff[0], 59);
       Serial.println(buff);
   } 
   
   else if (cmd[0] == 67 && cmdsize == 1) 
   {  // "C" - get temperature register
       Serial.print("temperature reg is ");
       Serial.println(DS3231_get_treg(), DEC);
   } 
   
   else if (cmd[0] == 68 && cmdsize == 1) 
   {  // "D" - reset status register alarm flags
       reg_val = DS3231_get_sreg();
       reg_val &= B11111100;
       DS3231_set_sreg(reg_val);
   } 
   
   else if (cmd[0] == 70 && cmdsize == 1) 
   {  // "F" - custom fct
       reg_val = DS3231_get_addr(0x5);
       Serial.print("orig ");
       Serial.print(reg_val,DEC);
       Serial.print("month is ");
       Serial.println(bcdtodec(reg_val & 0x1F),DEC);
   } 
  
   else if (cmd[0] == 71 && cmdsize == 1) {  // "G" - set aging status register
       DS3231_set_aging(0);
   } 
   
   else if (cmd[0] == 83 && cmdsize == 1) {  // "S" - get status register
       Serial.print("status reg is ");
       Serial.println(DS3231_get_sreg(), DEC);
   } else {
       Serial.print("unknown command prefix ");
       Serial.println(cmd[0]);
       Serial.println(cmd[0], DEC);
   }
}

void printMonth(int month)
{
 switch(month)
 {
   case 1: lcd.print(" January ");break;
   case 2: lcd.print(" February ");break;
   case 3: lcd.print(" March ");break;
   case 4: lcd.print(" April ");break;
   case 5: lcd.print(" May ");break;
   case 6: lcd.print(" June ");break;
   case 7: lcd.print(" July ");break;
   case 8: lcd.print(" August ");break;
   case 9: lcd.print(" September ");break;
   case 10: lcd.print(" October ");break;
   case 11: lcd.print(" November ");break;
   case 12: lcd.print(" December ");break;
   default: lcd.print(" Error ");break;
 } 
}

void set_alarm(void)
{
   // flags define what calendar component to be checked against the current time in order
   // to trigger the alarm - see datasheet
   // A1M1 (seconds) (0 to enable, 1 to disable)
   // A1M2 (minutes) (0 to enable, 1 to disable)
   // A1M3 (hour)    (0 to enable, 1 to disable) 
   // A1M4 (day)     (0 to enable, 1 to disable)
   // DY/DT          (dayofweek == 1/dayofmonth == 0)
   
   unsigned long prev = 5000, interval = 5000; // how often to refresh the info on stdout (ms)
   uint8_t flags[5] = { 0, 0, 0, 1, 1 };

   //set Alarm1 
   DS3231_set_a1(wake_SECOND, wake_MINUTE, wake_HOUR, 0, flags);

   //activate Alarm1
   DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
}


void beep()
{
  #define buzzer 15
 
  digitalWrite(buzzer,HIGH);
  delay(500);
  digitalWrite(buzzer, LOW);
  delay(500);
}

Sorry for my long question, I'm weak in coding, and terrible at explaining.

Did you write this code?

I'm with aarg on this: if you wrote that code and knew enough about interfacing with a DS3231 you would certainly be able to figure out how to set the alarm command codes too.

Perhaps you need to take a step back and understand how to program some very simple stuff for the DS3231 before attempting the alarm? Setting the initial date/time is a once-off operation (that code you posted probably does it) and the DS3231 is very accurate to won't need adjusting (unless daylight saving is an issue for you in your part of the world in which case you'll be getting up an hour early for work for six months of the year).

Back to your question, the answer (in general terms) is that you send command codes and data to the DS3231 to set the alarm to come on at a particular day of week / hour / minute whatever and when it does an output goes high for you to detect (possibly by the use of an interrupt, but if you're already on a steep learning curve we might just ignore interrupts for now). In fact the DS3231 has two alarms so you can have an alarm for weekdays (work days) and one for weekends (sleep ins). But the datasheet tells you all this.

I don't want to teach anybody's grandmother to suck eggs but have you read the datasheet and understood the registers that enable you to set the alarm - but are having issues implementing that functionality or are you just starting out?

There's a video (#5) about RTCs on my YouTube channel (see URL in signature below) which may be helpful if you're just starting out. If not, then post back some specific issues you're having and I (and others) will be very happy to help out.