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.