alrm Clk
#include <>
/*H********************************************************************
*
**********************************************************************/
#include
#include "ds3231.h"
#include
#undef int() //For stdio
#include //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
//************************* DEFINES ************************************
typedef unsigned long ulong;
typedef unsigned int uint;
//************************* PROTOTYPES ************************************
void parse_cmd( char *cmd, int cmdsize);
void printMonth( int month);
void set_alarm( void );
void beep();
//************************* VARIABLES ************************************
LiquidCrystal_I2C Lcd( 0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
char Rcv[BUFF_MAX];
uint Rcv_size = 0;
ulong Prev, Intvl = 1000;
uint8_t Tim[8];
uint8_t WakHr = 15; // Tim when to wake up
uint8_t WkMin = 49;
uint8_t WkSec = 9;
/*F********************************************************************
*
**********************************************************************/
void setup()
{ //real Tim clock
Serial.begin( BAUD );
Wire.begin();
DS3231_init( DS3231_INTCN);
memset( Rcv, 0, BUFF_MAX);
Serial.println( "GET Tim");
Lcd.begin( 16, 2);
Lcd.clear();
Serial.println( "Setting Tim"); //To set Tim manually
parse_cmd( "T010101101012016",16); //TSSMMHHWDDMMYYYY
//alarm
DS3231_clear_a2f();
set_alarm();
//buzzer
pinMode( 15, OUTPUT);
}
/*F********************************************************************
*
**********************************************************************/
void
loop()
{
char in, tempF[6], buff[BUFF_MAX];
ulong now = millis();
float temp;
struct ts t;
if( (now - Prev > Intvl) && (Serial.available() <= 0)) // show Tim once in a while
{
DS3231_get( &t); //Get Tim
parse_cmd( "C", 1);
temp = DS3231_get_treg(); //Get temp
dtostrf( temp, 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 > Intvl) && (Serial.available() <= 0))
{
DS3231_get(&t);
// display current Tim
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) && (Rcv_size > 0))
{
parse_cmd( Rcv, Rcv_size);
Rcv_size = 0;
Rcv[0] = 0;
}
else if( in < 48 || in > 122)
{;
// ignore ~[0-9A-Za-z]
}
else if( Rcv_size > BUFF_MAX - 2)
{ // drop lines that are too long
Rcv_size = 0; // drop
Rcv[0] = 0;
}
else if( Rcv_size < BUFF_MAX - 2)
{
Rcv[Rcv_size] = in;
Rcv[Rcv_size + 1] = 0;
Rcv_size += 1;
}
}
}
/*F********************************************************************
*
**********************************************************************/
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 Tim
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++)
{ // ss, mm, hh, dd
Tim[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48;
}
byte flags[5] = { 0, 0, 0, 0, 0 };
DS3231_set_a1( Tim[0], Tim[1], Tim[2], Tim[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++)
{ // mm, hh, dd
Tim[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48;
}
byte flags[5] = { 0, 0, 0, 0 };
DS3231_set_a2( Tim[0], Tim[1], Tim[2], flags);
DS3231_get_a2( &buff[0], 59);
Serial.println( buff);
}
else if( cmd[0] == 67 && cmdsize == 1)
{ // "C" - get temp register
Serial.print( "temp 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);
}
}
/*F********************************************************************
*
**********************************************************************/
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;
}
}
/*F********************************************************************
*
**********************************************************************/
void
set_alarm( void )
{
// flags define what calendar component to be checked against the current
// Tim in order to trigger 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)
ulong Prev = 5000, Intvl = 5000; // how often refresh info on stdout (ms)
uint8_t flags[5] = { 0, 0, 0, 1, 1 };
DS3231_set_a1( WkSec, WkMin, WakHr, 0, flags); //set Alarm1
DS3231_set_creg( DS3231_INTCN | DS3231_A1IE); //activate Alarm1
}
/*F********************************************************************
*
**********************************************************************/
void
beep()
{
#define buzzer 15
digitalWrite( buzzer, HIGH);
delay( 500);
digitalWrite( buzzer, LOW);
delay( 500 );
}