[C] 纯文本查看 复制代码
/* arduino sketch --
arduino display date and time with IIC 1602 LCD and get them with ds3231 RTC breakout
SETUP:
arduino (UNO R3) ds3231/iic_1602
A4/SDA → SDA
A5/SCL → SCL
GND → GND
Read More DS3231: http://www.yfrobot.com.cn/wiki/index.php?title=RTC_3231
BY YFROBOT
*/
#include <Wire.h> // must be incuded here so that Arduino library object file references work
#include <RtcDS3231.h> // RTC DS3231
#include <LiquidCrystal_I2C.h> // for IIC lcd
#define YEAR 0
#define MONTH 1
#define DAY 2
#define HOUR 3
#define MINUTE 4
#define SECOND 5
#define ALARM_ONE 1
#define ALARM_TWO 2
RtcDS3231 Rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2); // set address 0X27 & 16 chars / 2 lines
// make some custom characters :
#define DU 0
#define SMILEY 1
#define BELL 2
byte du[8] = { 0x18, 0x18, 0x6, 0x9, 0x8, 0x9, 0x6, 0x0 };
byte smiley[8] = { 0x0, 0x0, 0xa, 0x0, 0x0, 0x11, 0xe, 0x0 };
byte bell[8] = { 0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4};
String daysOfWeek[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
const int Pin_Sel = 4; // 选择按钮
const int Pin_Adj_down = 5; // 调整按钮 下调
const int Pin_Adj_up = 6; // 调整按钮 上调
// Board int.0 int.1 int.2 int.3 int.4 int.5
// ---------------------------------------------------------------
// Uno, Ethernet [2] 3
// Mega2560 2 3 21 20 19 18
// Leonardo 3 2 0 1 7
const int Pin_Alarm = 2; // 闹钟引脚 -- 中断引脚
#define RtcSquareWaveInterrupt 0 // UNO
// 时钟参数
RtcDateTime c_dateTime;
uint16_t c_year;
uint8_t c_month, c_day, c_dayOfWeek, c_hour, c_minute, c_second;
uint8_t LCD_Col_Row_DT[6][2] = {
{6, 0}, {0, 0}, {3, 0}, {0, 1}, {3, 1}, {6, 1}
};
// 闹钟1参数
boolean Enable_Alarm_one = false;
int8_t a1_mode, a1_dayOf, a1_hour, a1_minute, a1_second;
int8_t a1_m;
const uint8_t A1Mode[6] = { 0x00, 0x08, 0x10, 0x14, 0x16, 0x17};
// 闹钟2参数
boolean Enable_Alarm_two = false;
int8_t a2_mode, a2_dayOf, a2_hour, a2_minute;
int8_t a2_m;
const uint8_t A2Mode[5] = { 0x00, 0x04, 0x08, 0x0a, 0x0b};
unsigned long previousMillis = 0; // 计时 -- 程序每隔一秒刷新显示一次
int8_t f_out = 0; // 退回主界面标志
int8_t f_tempRead = 0; // 读取温度标志
int8_t f_AlarmOne = 0; // 闹钟1 已触发标志
int8_t f_AlarmTwo = 0; // 闹钟2 已触发标志
boolean interuptFlag = false; // 闹钟中断触发标志
// 中断触发
void InterruptServiceRoutine() {
interuptFlag = true;
}
void setup ()
{
Serial.begin(115200);
pinMode(Pin_Sel, INPUT);
pinMode(Pin_Adj_up, INPUT);
pinMode(Pin_Adj_down, INPUT);
Serial.print("compiled: ");
Serial.print(__DATE__); // 编译文档的日期
Serial.println(__TIME__); // 编译文档的时间
//--------RTC SETUP ------------
Rtc.Begin();
// if you are using ESP-01 then uncomment the line below to reset the pins to
// the available pins for SDA, SCL
// Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); // 存储当前编译的时间及日期并打印
printDateTime(compiled);
Serial.println();
if (!Rtc.IsDateTimeValid()) // 判断时间日期是否有效(详见数据手册状态寄存器第7位描述)
{
// Common Cuases:
// 1) first time you ran and the device wasn't running yet
// 2) the battery on the device is low or even missing
Serial.println("RTC lost confidence in the DateTime!");
// following line sets the RTC to the date & time this sketch was compiled
// it will also reset the valid flag internally unless the Rtc device is
// having an issue
Rtc.SetDateTime(compiled);
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
RtcDateTime now = Rtc.GetDateTime(); // 获取当前DS3231时间及日期
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
Rtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
// never assume the Rtc was last configured by you, so
// just clear them to your needed state
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
// setup external interupt
attachInterrupt(RtcSquareWaveInterrupt, InterruptServiceRoutine, FALLING);
lcd.init(); // initialize the lcd
// create a new character
lcd.createChar(DU, du);
lcd.createChar(SMILEY, smiley);
lcd.createChar(BELL, bell);
lcd.backlight(); // Print a message to the LCD.
lcd.home();
lcd.print("YFROBOT CLOCK");
lcd.setCursor(0, 1);
lcd.print("WWW.YFROBOT.COM");
delay(3000);
lcd.clear();
}
#define countof(a) (sizeof(a) / sizeof(a[0]))
// 串口打印日期时间
void printDateTime(const RtcDateTime& dt)
{
char datestring[20];
snprintf_P(datestring, countof(datestring), PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
dt.Month(), dt.Day(), dt.Year(),
dt.Hour(), dt.Minute(), dt.Second() );
Serial.print(datestring);
}
void printEmpty(int8_t cou) {
String empty = "";
for (int i = 0; i < cou; i++) {
empty += ' ';
}
lcd.print(empty);
}
// LCD 输出日期时间
void displayDateTime(const RtcDateTime& dt) {
lcd.home();
if (dt.Month() < 10)
lcd.print("0");
lcd.print(dt.Month(), DEC);
lcd.print('/');
if (dt.Day() < 10)
lcd.print("0");
lcd.print(dt.Day(), DEC);
lcd.print('/');
lcd.print(dt.Year(), DEC);
lcd.setCursor(15, 0);
lcd.write(SMILEY);
lcd.setCursor(0, 1);
if (dt.Hour() < 10)
lcd.print("0");
lcd.print(dt.Hour(), DEC);
lcd.print(':');
if (dt.Minute() < 10)
lcd.print("0");
lcd.print(dt.Minute(), DEC);
lcd.print(':');
if (dt.Second() < 10)
lcd.print("0");
lcd.print(dt.Second(), DEC);
}
// LCD 输出星期
void displayDayWeek(const RtcDateTime& dt) {
lcd.setCursor(11, 0);
lcd.print(daysOfWeek[dt.DayOfWeek()]);
}
// LCD 输出温度
void displayTemp(const RtcTemperature& te) {
lcd.setCursor(12, 1);
printEmpty(4);
lcd.setCursor(12, 1);
if (int(te.AsFloat()) < 100 && int(te.AsFloat()) >= 0)
printEmpty(1);
lcd.print(int(te.AsFloat()));
lcd.setCursor(15, 1);
lcd.write(DU); // 写单位
}
// 读取按键
unsigned long LastTime;
boolean BtnPress(int btn) {
if (digitalRead(btn) == HIGH) { // check button press
if (millis() - LastTime >= 500) {
LastTime = millis();
return true;
} else {
return false;
}
} else {
return false;
}
}
// 显示数字
void AdjustDisplay(uint8_t c_item , uint8_t col, uint8_t row) {
lcd.setCursor(col, row);
if (c_item < 10)
lcd.print("0");
lcd.print(c_item);
}
// 调整-闪烁
void AdjustDisplayBlink(uint8_t c_item , uint8_t col, uint8_t row) {
unsigned long WT = millis() % 1000;
lcd.setCursor(col, row);
if (WT < 500) {
printEmpty(2);
} else {
if (c_item < 10)
lcd.print("0");
lcd.print(c_item);
}
}
// 上调下调按键调节
int8_t AdjustData(int8_t c_item, int8_t cmin, int8_t cmax) {
if (BtnPress(Pin_Adj_up)) {
c_item += 1;
if (c_item > cmax)
c_item = cmin;
}
if (BtnPress(Pin_Adj_down)) {
c_item -= 1;
if (c_item < cmin)
c_item = cmax;
}
return c_item;
}
// 界面-闪烁
void S_DisplayBlink(String c_item, uint8_t col, uint8_t row) {
unsigned long WT = millis() % 1000;
lcd.setCursor(col, row);
if (WT < 500) {
printEmpty(c_item.length());
// Serial.print(c_item.length());
} else {
lcd.print(c_item);
}
}
// 闹钟标志
void displayBell(boolean bellOn) {
if (bellOn) {
lcd.setCursor(9, 1);
lcd.write(BELL); // 写单位
}
}
// 闹钟执行
void displayBellAlarm() {
if (interuptFlag) {
interuptFlag = false; // reset the flag
// this gives us which alarms triggered and then allows for others to trigger again
DS3231AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags();
if ((flag & DS3231AlarmFlag_Alarm1) && Rtc.IsEnableAlarmOne()) {
f_AlarmOne = 1;
lcd.setCursor(10, 1);
printEmpty(1);
lcd.setCursor(10, 1);
lcd.print(1); // 输出闹钟标志
Serial.println("111111");
}
if ((flag & DS3231AlarmFlag_Alarm2) && Rtc.IsEnableAlarmTwo()) {
f_AlarmTwo = 1;
// lcd.setCursor(11, 1);
// printEmpty(1);
lcd.setCursor(11, 1);
lcd.print(2); // 输出闹钟标志
Serial.println("222222");
}
}
}
// 清除闹钟
void clearBellAlarm(int8_t Bell) {
if (Bell == ALARM_ONE) {
lcd.setCursor(10, 1);
printEmpty(1);
} else if (Bell == ALARM_TWO) {
lcd.setCursor(11, 1);
printEmpty(1);
}
}
// lcd Print
void D_lcdPrint(uint8_t c_item, uint8_t col, uint8_t row) {
lcd.setCursor(col, row);
lcd.print(c_item);
}
// lcd Print
void D_lcdPrint(String c_item, uint8_t col, uint8_t row) {
lcd.setCursor(col, row);
lcd.print(c_item);
}
// 初始化调整时钟参数
void InitAdjPer(const RtcDateTime& dt) {
c_year = dt.Year();
c_month = dt.Month();
c_day = dt.Day();
c_hour = dt.Hour();
c_minute = dt.Minute();
c_second = dt.Second();
}
// 进入设置时钟界面
void SetTime() {
/************ set year *************/
lcd.clear();
c_dateTime = Rtc.GetDateTime();
InitAdjPer(c_dateTime);
boolean F_Year = true;
displayDateTime(c_dateTime);
while (true) {
unsigned long WT = millis() % 1000;
if (WT < 500) {
lcd.setCursor(6, 0);
printEmpty(4);
} else {
lcd.setCursor(6, 0);
lcd.print(c_year);
}
if (BtnPress(Pin_Adj_up)) {
c_year += 1;
}
if (BtnPress(Pin_Adj_down)) {
c_year -= 1;
}
/************ set month *************/
if (BtnPress(Pin_Sel)) {
lcd.setCursor(LCD_Col_Row_DT[YEAR][0], LCD_Col_Row_DT[YEAR][1]);
lcd.print(c_year);
while (true) {
AdjustDisplayBlink(c_month, LCD_Col_Row_DT[MONTH][0], LCD_Col_Row_DT[MONTH][1]);
c_month = AdjustData(c_month, 1, 12);
/************ set day *************/
if (BtnPress(Pin_Sel)) {
AdjustDisplay(c_month, LCD_Col_Row_DT[MONTH][0], LCD_Col_Row_DT[MONTH][1]);
while (true) {
AdjustDisplayBlink(c_day, LCD_Col_Row_DT[DAY][0], LCD_Col_Row_DT[DAY][1]);
uint8_t c_daysInMon = pgm_read_byte_near(c_daysInMonth + c_month - 1);
// https://www.arduino.cc/en/Reference/PROGMEM
// http://www.yfrobot.com.cn/wiki/index.php?title=PROGMEM
// http://www.nongnu.org/avr-libc/u ... _avr__pgmspace.html
c_day = AdjustData(c_day, 1, c_daysInMon);
// Serial.print("\t");
// Serial.println( c_daysInMon);
/************ set hour *************/
if (BtnPress(Pin_Sel)) {
AdjustDisplay(c_day, LCD_Col_Row_DT[DAY][0], LCD_Col_Row_DT[DAY][1]);
while (true) {
AdjustDisplayBlink(c_hour, LCD_Col_Row_DT[HOUR][0], LCD_Col_Row_DT[HOUR][1]);
c_hour = AdjustData(c_hour, 0, 23);
/************ set minute *************/
if (BtnPress(Pin_Sel)) {
AdjustDisplay(c_hour, LCD_Col_Row_DT[HOUR][0], LCD_Col_Row_DT[HOUR][1]);
while (true) {
AdjustDisplayBlink(c_minute, LCD_Col_Row_DT[MINUTE][0], LCD_Col_Row_DT[MINUTE][1]);
c_minute = AdjustData(c_minute, 0, 59);
/************ set second *************/
if (BtnPress(Pin_Sel)) {
AdjustDisplay(c_minute, LCD_Col_Row_DT[MINUTE][0], LCD_Col_Row_DT[MINUTE][1]);
while (true) {
AdjustDisplayBlink(c_second, LCD_Col_Row_DT[SECOND][0], LCD_Col_Row_DT[SECOND][1]);
c_second = AdjustData(c_second, 0, 59);
/************ Sure set *************/
if (BtnPress(Pin_Sel)) { // sure set
f_out = 1; // 确认进入设置时钟界面标志
lcd.clear();
D_lcdPrint("Sure to Change!", 0, 0);
// S_DisplayBlink("YES", 3, 1);
// D_lcdPrint("NO", 8, 1);
boolean YesorNo = true;
while (true) {
if (BtnPress(Pin_Adj_up) || BtnPress(Pin_Adj_down)) {
YesorNo = !YesorNo;
}
if (YesorNo) {
D_lcdPrint("NO", 8, 1);
S_DisplayBlink("YES", 3, 1);
} else {
D_lcdPrint("YES", 3, 1);
S_DisplayBlink("NO", 8, 1);
}
if (YesorNo && BtnPress(Pin_Sel)) { // out set -- ok or cancel
lcd.clear();
RtcDateTime now_dataTime(c_year, c_month, c_day, c_hour, c_minute, c_second);
c_dateTime = now_dataTime;
Rtc.SetDateTime(c_dateTime);
return;
} else if (!YesorNo && BtnPress(Pin_Sel)) {
lcd.clear();
return;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
// 进入设置闹钟界面
void SelAlarms() {
/************ select alarms *************/
lcd.clear();
int8_t alarms_list = 0;
int8_t alarms_display = 0;
while (true) {
if (BtnPress(Pin_Adj_up)) {
alarms_list++;
if (alarms_list >= 3) {
alarms_list = 0;
}
alarms_display = alarms_list;
} else if (BtnPress(Pin_Adj_down)) {
alarms_list--;
if (alarms_list < 0) {
alarms_list = 2;
}
alarms_display = alarms_list;
}
if (alarms_list == 0 ) {
if (alarms_display == 0) {
D_lcdPrint("Set Alarms!", 0, 0);
D_lcdPrint("A_2", 6, 1);
D_lcdPrint("EXIT", 11, 1);
alarms_display = -1;
}
S_DisplayBlink("A_1", 1, 1);
} else if (alarms_list == 1) {
if (alarms_display == 1 ) {
D_lcdPrint("Set Alarms!", 0, 0);
D_lcdPrint("A_1", 1, 1);
D_lcdPrint("EXIT", 11, 1);
alarms_display = -1;
}
S_DisplayBlink("A_2", 6, 1);
} else if (alarms_list == 2) {
if (alarms_display == 2) {
D_lcdPrint("Set Alarms!", 0, 0);
D_lcdPrint("A_1", 1, 1);
D_lcdPrint("A_2", 6, 1);
alarms_display = -1;
}
S_DisplayBlink("EXIT", 11, 1);
}
if (alarms_list == 0 && BtnPress(Pin_Sel)) { // out set -- ok or cancel
SetAlarms_One();
alarms_display = 0;
} else if (alarms_list == 1 && BtnPress(Pin_Sel)) {
SetAlarms_Two();
alarms_display = 1;
} else if (alarms_list == 2 && BtnPress(Pin_Sel)) {
lcd.clear();
f_out = 1; //退回主界面
return;
}
}
}
// 进入闹钟一设置界面
void SetAlarms_One() {
lcd.clear();
lcd.print("A one");
lcd.setCursor(12, 0);
if (Enable_Alarm_one) {
lcd.print("ON ");
} else {
lcd.print("OFF");
}
DS3231AlarmOne c_alarmOne = Rtc.GetAlarmOne();
a1_mode = c_alarmOne.ControlFlags();
for (int i = 0; i < sizeof(A1Mode); i++) {
if (a1_mode == A1Mode) {
a1_m = i;
break;
}
}
/* a1 mode
0x00 DS3231AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch
0x08 DS3231AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch
0x10 DS3231AlarmOneControl_HoursMinutesSecondsMatch
0x14 DS3231AlarmOneControl_MinutesSecondsMatch
0x16 DS3231AlarmOneControl_SecondsMatch
0x17 DS3231AlarmOneControl_OncePerSecond
*/
a1_dayOf = c_alarmOne.DayOf();
a1_hour = c_alarmOne.Hour();
a1_minute = c_alarmOne.Minute();
a1_second = c_alarmOne.Second();
Serial.println(a1_mode);
Serial.println(a1_dayOf);
Serial.println(a1_hour);
Serial.println(a1_minute);
Serial.println(a1_second);
lcd.setCursor(1, 1);
if (a1_mode < 10)
lcd.print("0");
lcd.print(a1_mode);
lcd.setCursor(4, 1);
if (a1_dayOf < 10)
lcd.print("0");
lcd.print(a1_dayOf);
lcd.setCursor(7, 1);
if (a1_hour < 10)
lcd.print("0");
lcd.print(a1_hour);
lcd.setCursor(10, 1);
if (a1_minute < 10)
lcd.print("0");
lcd.print(a1_minute);
lcd.setCursor(13, 1);
if (a1_second < 10)
lcd.print("0");
lcd.print(a1_second);
int8_t c_a1 = 0;
while (true) {
c_a1 = AdjustData(c_a1, 0, 1);
if (c_a1 == 0) {
S_DisplayBlink("A one", 0, 0);
} else if (c_a1 == 1) {
D_lcdPrint("A one", 0, 0);
if (Enable_Alarm_one) {
S_DisplayBlink("ON ", 12, 0);
} else {
S_DisplayBlink("OFF", 12, 0);
}
if (BtnPress(Pin_Adj_up) || BtnPress(Pin_Adj_down)) {
Enable_Alarm_one = !Enable_Alarm_one;
}
if (BtnPress(Pin_Sel)) { // out set
if (Enable_Alarm_one) {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
DS3231AlarmOne alarm1(a1_dayOf, a1_hour, a1_minute, a1_second, a1_mode);
Rtc.SetAlarmOne(alarm1);
// throw away any old alarm state before we ran
Rtc.LatchAlarmsTriggeredFlags();
} else {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne_Off);
}
lcd.clear();
return;
}
}
if (BtnPress(Pin_Sel)) {
D_lcdPrint("A one", 0, 0);
while (true) {
AdjustDisplayBlink(a1_mode, 1, 1);
a1_m = AdjustData(a1_m, 0, 5);
a1_mode = A1Mode[a1_m];
if (BtnPress(Pin_Sel)) { // set day of month of week
AdjustDisplay(a1_mode, 1, 1);
while (true) {
AdjustDisplayBlink(a1_dayOf, 4, 1);
if (a1_mode == 0) {
uint8_t c_daysInMon = pgm_read_byte_near(c_daysInMonth + a1_mode - 1);
// https://www.arduino.cc/en/Reference/PROGMEM
// http://www.yfrobot.com.cn/wiki/index.php?title=PROGMEM
// http://www.nongnu.org/avr-libc/u ... _avr__pgmspace.html
a1_dayOf = AdjustData(a1_dayOf, 1, c_daysInMon);
} else if (a1_mode == 1) {
a1_dayOf = AdjustData(a1_dayOf, 0, 6);
}
if (BtnPress(Pin_Sel)) { // set hour
AdjustDisplay(a1_dayOf, 4, 1);
while (true) {
AdjustDisplayBlink(a1_hour, 7, 1);
a1_hour = AdjustData(a1_hour, 0, 23);
if (BtnPress(Pin_Sel)) { // set minute
AdjustDisplay(a1_hour, 7, 1);
while (true) {
AdjustDisplayBlink(a1_minute, 10, 1);
a1_minute = AdjustData(a1_minute, 0, 59);
if (BtnPress(Pin_Sel)) { // set second
AdjustDisplay(a1_minute, 10, 1);
while (true) {
AdjustDisplayBlink(a1_second, 13, 1);
a1_second = AdjustData(a1_second, 0, 59);
if (BtnPress(Pin_Sel)) { // turn on or off
AdjustDisplay(a1_second, 13, 1);
while (true) {
if (Enable_Alarm_one) {
S_DisplayBlink("ON ", 12, 0);
} else {
S_DisplayBlink("OFF", 12, 0);
}
if (BtnPress(Pin_Adj_up) || BtnPress(Pin_Adj_down)) {
Enable_Alarm_one = !Enable_Alarm_one;
}
if (BtnPress(Pin_Sel)) { // out set
if (Enable_Alarm_one) {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
DS3231AlarmOne alarm1(a1_dayOf, a1_hour, a1_minute, a1_second, a1_mode);
Rtc.SetAlarmOne(alarm1);
// throw away any old alarm state before we ran
Rtc.LatchAlarmsTriggeredFlags();
} else {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne_Off);
}
lcd.clear();
return;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
// 进入闹钟二设置界面
void SetAlarms_Two() {
lcd.clear();
lcd.print("A two");
lcd.setCursor(12, 0);
if (Enable_Alarm_two) {
lcd.print("ON ");
} else {
lcd.print("OFF");
}
DS3231AlarmTwo c_alarmTwo = Rtc.GetAlarmTwo();
a2_mode = c_alarmTwo.ControlFlags();
for (int i = 0; i < sizeof(A2Mode); i++) {
if (a2_mode == A2Mode) {
a2_m = i;
break;
}
}
/* a2 mode
0x00 DS3231AlarmTwoControl_HoursMinutesDayOfMonthMatch
0x04 DS3231AlarmTwoControl_HoursMinutesDayOfWeekMatch
0x08 DS3231AlarmTwoControl_HoursMinutesMatch
0x0a DS3231AlarmTwoControl_MinutesMatch
0x0b DS3231AlarmTwoControl_OncePerMinute
*/
a2_dayOf = c_alarmTwo.DayOf();
a2_hour = c_alarmTwo.Hour();
a2_minute = c_alarmTwo.Minute();
Serial.println(a2_mode);
Serial.println(a2_dayOf);
Serial.println(a2_hour);
Serial.println(a2_minute);
lcd.setCursor(1, 1);
if (a2_mode < 10)
lcd.print("0");
lcd.print(a2_mode);
lcd.setCursor(4, 1);
if (a2_dayOf < 10)
lcd.print("0");
lcd.print(a2_dayOf);
lcd.setCursor(7, 1);
if (a2_hour < 10)
lcd.print("0");
lcd.print(a2_hour);
lcd.setCursor(10, 1);
if (a2_minute < 10)
lcd.print("0");
lcd.print(a2_minute);
int8_t c_a2 = 0;
while (true) {
c_a2 = AdjustData(c_a2, 0, 1);
if (c_a2 == 0) {
S_DisplayBlink("A two", 0, 0);
} else if (c_a2 == 1) {
D_lcdPrint("A two", 0, 0);
if (Enable_Alarm_two) {
S_DisplayBlink("ON ", 12, 0);
} else {
S_DisplayBlink("OFF", 12, 0);
}
if (BtnPress(Pin_Adj_up) || BtnPress(Pin_Adj_down)) {
Enable_Alarm_two = !Enable_Alarm_two;
}
if (BtnPress(Pin_Sel)) { // out set
if (Enable_Alarm_two) {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmTwo);
DS3231AlarmTwo alarm2(a2_dayOf, a2_hour, a2_minute, a2_mode);
Rtc.SetAlarmTwo(alarm2);
// throw away any old alarm state before we ran
Rtc.LatchAlarmsTriggeredFlags();
} else {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmTwo_Off);
}
lcd.clear();
return;
}
}
if (BtnPress(Pin_Sel)) {
D_lcdPrint("A two", 0, 0);
while (true) {
AdjustDisplayBlink(a2_mode, 1, 1);
a2_m = AdjustData(a2_m, 0, 4);
a2_mode = A2Mode[a2_m];
if (BtnPress(Pin_Sel)) { // set day
AdjustDisplay(a2_mode, 1, 1);
while (true) {
AdjustDisplayBlink(a2_dayOf, 4, 1);
if (a2_m == 0) {
uint8_t c_daysInMon = pgm_read_byte_near(c_daysInMonth + a2_mode - 1);
// https://www.arduino.cc/en/Reference/PROGMEM
// http://www.yfrobot.com.cn/wiki/index.php?title=PROGMEM
// http://www.nongnu.org/avr-libc/u ... _avr__pgmspace.html
a2_dayOf = AdjustData(a2_dayOf, 1, c_daysInMon);
} else if (a2_m == 1) {
a2_dayOf = AdjustData(a2_dayOf, 0, 6);
}
if (BtnPress(Pin_Sel)) { // set hour
AdjustDisplay(a2_dayOf, 4, 1);
while (true) {
AdjustDisplayBlink(a2_hour, 7, 1);
a2_hour = AdjustData(a2_hour, 0, 23);
if (BtnPress(Pin_Sel)) { // set minute
AdjustDisplay(a2_hour, 7, 1);
while (true) {
AdjustDisplayBlink(a2_minute, 10, 1);
a2_minute = AdjustData(a2_minute, 0, 59);
if (BtnPress(Pin_Sel)) { // turn on or off
AdjustDisplay(a2_minute, 10, 1);
while (true) {
if (Enable_Alarm_two) {
S_DisplayBlink("ON ", 12, 0);
} else {
S_DisplayBlink("OFF", 12, 0);
}
if (BtnPress(Pin_Adj_up) || BtnPress(Pin_Adj_down)) {
Enable_Alarm_two = !Enable_Alarm_two;
}
if (BtnPress(Pin_Sel)) { // out set
if (Enable_Alarm_two) {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmTwo);
DS3231AlarmTwo alarm2(a2_dayOf, a2_hour, a2_minute, a2_mode);
Rtc.SetAlarmTwo(alarm2);
// throw away any old alarm state before we ran
Rtc.LatchAlarmsTriggeredFlags();
} else {
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmTwo_Off);
}
Serial.println(Enable_Alarm_two);
lcd.clear();
return;
}
}
}
}
}
}
}
}
}
}
}
}
}
// 进入设置选择界面
void Settings() {
if (BtnPress(Pin_Sel)) {
f_tempRead = 0; // 温度显示标志 -- 进入Set系统后,返回主界面依然显示温度
lcd.clear();
int8_t c_setting = 0;
int8_t c_display = 0;
while (true) {
//上下调节按键
if (BtnPress(Pin_Adj_up)) {
c_setting ++;
if (c_setting >= 3) {
c_setting = 0;
}
c_display = c_setting;
} else if (BtnPress(Pin_Adj_down)) {
c_setting --;
if (c_setting < 0) {
c_setting = 2;
}
c_display = c_setting;
}
if (c_setting == 0) {
if (c_display == 0) {
D_lcdPrint("Select One!", 0, 0);
D_lcdPrint("ALARM", 6, 1);
D_lcdPrint("EXIT", 12, 1);
Serial.println("test");
c_display = -1;
}
S_DisplayBlink("TIME", 0, 1);
} else if (c_setting == 1) {
if (c_display == 1) {
D_lcdPrint("Select One!", 0, 0);
D_lcdPrint("TIME", 0, 1);
D_lcdPrint("EXIT", 12, 1);
c_display = -1;
}
S_DisplayBlink("ALARM", 6, 1);
} else if (c_setting == 2) {
if (c_display == 2) {
D_lcdPrint("Select One!", 0, 0);
D_lcdPrint("TIME", 0, 1);
D_lcdPrint("ALARM", 6, 1);
c_display = -1;
}
S_DisplayBlink("EXIT", 12, 1);
}
if (c_setting == 0 && BtnPress(Pin_Sel)) {
SetTime();
c_display = 0;
} else if (c_setting == 1 && BtnPress(Pin_Sel)) {
SelAlarms();
c_display = 1;
} else if ((c_setting == 2 && BtnPress(Pin_Sel)) || f_out != 0) { // out set -- ok or cancel
f_out = 0; // 恢复标志
lcd.clear();
return;
}
}
}
}
void loop () {
if (!Rtc.IsDateTimeValid())
{
// Common Cuases:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime!");
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 1000) { // 每1000ms执行一次
RtcDateTime now = Rtc.GetDateTime();
printDateTime(now);
Serial.println();
displayDateTime(now);
displayDayWeek(now);
displayBell((Enable_Alarm_one || Enable_Alarm_two)); // 闹钟标志
displayBellAlarm(); // 闹钟响铃
// 每64秒读取温度一次
if (f_tempRead == 0) {
//输出温度 -- 温度每64秒更新一次 / 精度±3°C
RtcTemperature temp = Rtc.GetTemperature();
Serial.print("Temp:");
Serial.print(temp.AsFloat());
Serial.println("C");
displayTemp(temp);
}
f_tempRead ++;
if (f_tempRead == 63) {
f_tempRead = 0;
}
// 闹钟响铃后30s,清除屏幕标志
if (f_AlarmOne) {
f_AlarmOne ++;
if (f_AlarmOne >= 30) {
clearBellAlarm(ALARM_ONE);
f_AlarmOne = 0;
}
}
// 闹钟响铃后30s,清除屏幕标志
if (f_AlarmTwo) {
f_AlarmTwo++;
if (f_AlarmTwo >= 30) {
clearBellAlarm(ALARM_TWO);
f_AlarmTwo = 0;
}
}
previousMillis = currentMillis;
}
Settings();
}