/**********************************************************************
name file: rtc + alarm config
file create date: 23/08/2022
version: 1.0.0
author: Saul Martinez Cruz
copyrigth: roboPits
**********************************************************************/
/**********************************************************************
define enum
**********************************************************************/
enum{
ERROR = 0,
OK,
PENDING,
};
/**********************************************************************
define struct
**********************************************************************/
struct BTNFLAGS{
unsigned int forward :1;
unsigned int back :1;
unsigned int left :1;
unsigned int rigth :1;
unsigned int sw :8;
unsigned int cursor :4;
unsigned int select :1;
int cnt :8;
};
struct TIMEFLAGS{
unsigned int year :7;
unsigned int month :4;
unsigned int day :5;
unsigned int hour :5;
unsigned int minute :6;
unsigned int second :6;
};
/**********************************************************************
system include
**********************************************************************/
#include <string.h>
#include <stdlib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
/**********************************************************************
user include
**********************************************************************/
/**********************************************************************
user define
**********************************************************************/
#define printf(s) Serial.print(s);
#define btnForward 16
#define btnBack 17
#define btnLeft 15
#define btnRigth 14
#define btnSelect 2
/**********************************************************************
global variables
**********************************************************************/
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,16,2);
struct BTNFLAGS btnFlags;
struct TIMEFLAGS timeFlags;
int timeOutLCD = 0;
int timerOutLCD = 0;
/**********************************************************************
global functions
**********************************************************************/
void RTC_Init(void);
void RTC_Get(char *Date, char* Time);
void RTC_Set(int year,int month,int day,int hour,int minute,int sec);
void LCD_Ini(void);
void ItoA(int Num, char *Ptr, int Digi);
void showDateTime(void);
void BTN_Init(void);
void display(void);
void outToggle(char pin);
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN,OUTPUT);
RTC_Init();
LCD_Ini();
BTN_Init();
btnFlags.sw = 0;
// put your setup code here, to run once:
}
void loop(){
display();
// put your main code here, to run repeatedly:
}
/*
@param function:
@param def:
@param in:
@param out:
@param return:
*/
void display(void){
char date[15] = {0};
char time[15] = {0};
RTC_Get(date,time);
static char cursor = 12;
int timeCnt = btnFlags.cnt;
if(!digitalRead(btnForward)){
btnFlags.forward = 1;
lcd.clear();
cursor = 12;
}
else if(!digitalRead(btnBack)){
btnFlags.back = 1;
lcd.clear();
cursor = 12;
}
else if(!digitalRead(btnLeft)){
btnFlags.left = 1;
}
else if(!digitalRead(btnRigth)){
btnFlags.rigth = 1;
}
else if(!digitalRead(btnSelect)){
btnFlags.select = 1;
}
else{
if(btnFlags.forward) btnFlags.sw++;
else if(btnFlags.back) btnFlags.sw--;
else if(btnFlags.select){
lcd.setCursor(cursor,1);
lcd.print(" ");
cursor -=3;
if(cursor <= 3){
cursor = 12;
}
}
else if(btnFlags.left){
++btnFlags.cnt;
}
else if(btnFlags.rigth){
--btnFlags.cnt;
}
btnFlags.select = 0;
btnFlags.forward = 0;
btnFlags.back = 0;
btnFlags.left = 0;
btnFlags.rigth = 0;
switch(btnFlags.sw){
case 0:
lcd.setCursor(4,0);
lcd.print(date);
lcd.setCursor(4,1);
lcd.print(time);
break;
case 1:
lcd.setCursor(0,0);
lcd.print("time:");
lcd.setCursor(6,0);
lcd.print(time);
lcd.setCursor(cursor,1);
lcd.print("--");
if(cursor == 12){//segundos
if(timeCnt < btnFlags.cnt){
timeFlags.second++;
}else if(timeCnt > btnFlags.cnt){
timeFlags.second--;
}
}
else if(cursor == 9){//minutos
if(timeCnt < btnFlags.cnt){
timeFlags.minute++;
}
else if(timeCnt > btnFlags.cnt){
timeFlags.minute--;
}
}
else if(cursor == 6){//hora
if(timeCnt < btnFlags.cnt){
timeFlags.hour++;
}
else if(timeCnt > btnFlags.cnt){
timeFlags.hour--;
}
}
if(timeCnt != btnFlags.cnt){
RTC_Set(timeFlags.year,timeFlags.month,timeFlags.day,timeFlags.hour,timeFlags.minute,timeFlags.second);
}
break;
case 2:
lcd.setCursor(0,0);
lcd.print("date:");
lcd.setCursor(6,0);
lcd.print(date);
lcd.setCursor(cursor,1);
lcd.print("--");
if(cursor == 6){//day
if(timeCnt < btnFlags.cnt){
timeFlags.day++;
}else if(timeCnt > btnFlags.cnt){
timeFlags.day--;
}
}
else if(cursor == 9){//month
if(timeCnt < btnFlags.cnt){
timeFlags.month++;
}else if(timeCnt > btnFlags.cnt){
timeFlags.month--;
}
}
else if(cursor == 12){//year
if(timeCnt > btnFlags.cnt){
timeFlags.year++;
}else if(timeCnt < btnFlags.cnt){
timeFlags.year--;
}
}
if(timeCnt != btnFlags.cnt){
RTC_Set(timeFlags.year,timeFlags.month,timeFlags.day,timeFlags.hour,timeFlags.minute,timeFlags.second);
}
break;
case 3:
lcd.setCursor(0,0);
lcd.print("alarm 1");
break;
case 4:
lcd.setCursor(0,0);
lcd.print("alarm 2");
break;
default:
btnFlags.sw = 0;
break;
}
}
}
/*
@param function: void RTC_Init(void)
@param def: Initialize RTC driver
@param in: none
@param out: none
@param return: none
*/
void RTC_Init(void){
if(rtc.begin() == ERROR){
printf("fail init RTC\r\n");
}else{
printf("RTC OK\r\n");
}
}
/*
@param function: void RTC_Get(int year, int month, int day, int hour, int minut, int sec)
@param def: get the date and time
@param in: none
@param out: date/hour
@param return: none
*/
void RTC_Get(char *Date, char* Time){
char Tmp[10] = {0};
DateTime _get = rtc.now();
timeFlags.year = ((_get.year()-2000));
timeFlags.month = _get.month();
timeFlags.day = _get.day();
timeFlags.hour = _get.hour();
timeFlags.minute = _get.minute();
timeFlags.second = _get.second();
ItoA(timeFlags.day,Tmp,2);
strcat(Date,Tmp);
strcat(Date,"/");
ItoA(timeFlags.month,Tmp,2);
strcat(Date,Tmp);
strcat(Date,"/");
ItoA(timeFlags.year,Tmp,2);
strcat(Date,Tmp);
ItoA(timeFlags.hour,Tmp,2);
strcat(Time,Tmp);
strcat(Time,":");
ItoA(timeFlags.minute,Tmp,2);
strcat(Time,Tmp);
strcat(Time,":");
ItoA(timeFlags.second,Tmp,2);
strcat(Time,Tmp);
}
/*
@param function: void RTC_Set(int year, int month, int day, int hour, int minut, int sec)
@param def:
@param in:
@param out:
@param return:
*/
void RTC_Set(int year,int month,int day,int hour,int minute,int sec){
rtc.adjust(DateTime(year, month, day, hour, minute, sec));
}
/*
@param function: void LCD_Ini(void)
@param def: Initialize LCD driver
@param in: none
@param out: none
@param return: none
*/
void LCD_Ini(void){
lcd.init();
lcd.backlight();
lcd.clear();
}
/*
@param function: void ItoA(int Num, char *Ptr, int Digi)
@param def:
@param in:
@param out:
@param return:
*/
void ItoA(int Num, char *Ptr, int Digi){
int i = 0, j = 0;
do{
Ptr[i++] = (Num % 10) + 0x30;
Num /= 10;
}while(Num > 0);
if(i < Digi){
int k = i;
for(j = 0; j < (Digi - k); j++)
Ptr[i++] = 0x30;
}
char tmp[i + 1];
memcpy(tmp, (const char*)Ptr, i);
for(j = 0; j < i; j++)
*Ptr++ = tmp[i - j - 1];
*Ptr = 0;
}
/*
@param function:
@param def:
@param in:
@param out:
@param return:
*/
void showDateTime(void){
char fecha[15] = {0};
char hora[15] = {0};
RTC_Get(fecha,hora);
lcd.setCursor(4,0);
lcd.print(fecha);
lcd.setCursor(4,1);
lcd.print(hora);
}
/*
@param function:
@param def:
@param in:
@param out:
@param return:
*/
void BTN_Init(void){
pinMode(btnForward, INPUT_PULLUP);
pinMode(btnBack, INPUT_PULLUP);
pinMode(btnLeft, INPUT_PULLUP);
pinMode(btnRigth, INPUT_PULLUP);
pinMode(btnSelect, INPUT_PULLUP);
}
/*
@param function:
@param def:
@param in:
@param out:
@param return:
*/
void outToggle(char pin){
int status = digitalRead(pin);
digitalWrite(pin,!status);
}
/*
@param function:
@param def:
@param in:
@param out:
@param return:
*/