#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
RtcDateTime now;
volatile bool interrupt_2 = false;
volatile unsigned long bounce_2 = 0;
volatile unsigned long lpress_2 = 0;
volatile bool interrupt_3 = false;
volatile unsigned long bounce_3 = 0;
volatile unsigned long lpress_3 = 0;
void buttons_interrupt_handler_2() {
interrupt_2 = true;
bounce_2 = millis();
lpress_2 = millis();
}
void buttons_interrupt_handler_3() {
interrupt_3 = true;
bounce_3 = millis();
lpress_3 = millis();
}
void setup() {
Serial.begin(9600);
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), buttons_interrupt_handler_2, FALLING);
pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(3), buttons_interrupt_handler_3, FALLING);
Rtc.Begin();
//RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
//Rtc.SetDateTime(compiled + 0*60*60 + 8);
//Rtc.SetDateTime(RtcDateTime(2018, 1, 17, 7, 53, 00));
rtc_set();
}
void loop() {
static bool init = true;
if (init) {
init = false;
u8g2.initDisplay();
u8g2.setContrast(30);
u8g2.setFlipMode(0);
u8g2.setPowerSave(0);
}
now = Rtc.GetDateTime();
bool rtclock_err = !Rtc.IsDateTimeValid();
static char date[11], time[9];
snprintf(date, 11, "%02u-%02u-%04u", now.Month(), now.Day(), now.Year());
snprintf(time, 9, "%02u:%02u:%02u", now.Hour(), now.Minute(), now.Second());
u8g2.clearBuffer();
u8g2.drawRFrame(0, 0, 128, 64, 5);
u8g2.setFont(u8g2_font_t0_22b_mf);
u8g2.drawStr(9, 18, date);
u8g2.drawStr(20, 38, time);
if (!rtclock_err) u8g2.drawStr(53, 58, "OK");
else u8g2.drawStr(26, 58, "rtc err");
u8g2.sendBuffer();
delay(300);
}
int pin2int() {
int impulse = 0;
static bool longpress = false;
noInterrupts();
if (digitalRead(2)) lpress_2 = millis();
else bounce_2 = millis();
if (interrupt_2) {
if (millis() - bounce_2 > 20) {
interrupt_2 = false;
impulse = !longpress; //impulse shortpress
longpress = false;
}
}
if (!longpress) {
if (millis() - lpress_2 > 750) {
longpress = true;
lpress_2 = millis();
impulse = 2; //impulse longpress(once)
}
}
if (longpress) {
if (millis() - lpress_2 > 500) {
lpress_2 = millis();
impulse = 3; //impulse longpress(repeat)
}
}
interrupts();
return impulse;
}
int pin3int() {
int impulse = 0;
static bool longpress = false;
noInterrupts();
if (digitalRead(3)) lpress_3 = millis();
else bounce_3 = millis();
if (interrupt_3) {
if (millis() - bounce_3 > 20) {
interrupt_3 = false;
impulse = !longpress; //impulse shortpress
longpress = false;
}
}
if (!longpress) {
if (millis() - lpress_3 > 750) {
longpress = true;
lpress_3 = millis();
impulse = 2; //impulse longpress(once)
}
}
if (longpress) {
if (millis() - lpress_3 > 500) {
lpress_3 = millis();
impulse = 3; //impulse longpress(repeat)
}
}
interrupts();
return impulse;
}
void rtc_set() {
RtcDateTime now = Rtc.GetDateTime();
u8g2.initDisplay();
u8g2.setContrast(30);
u8g2.setFlipMode(0);
u8g2.setPowerSave(0);
int Mon = now.Month();
int Day = now.Day();
int Yrs = now.Year();
int Hrs = now.Hour();
int Min = now.Minute();
int Sec = now.Second();
int cases = 8;
bool init = true;
unsigned long refresh = millis();
unsigned long timeout = millis() + 10000;
while (millis() < timeout) {
int m = pin3int();
int p = pin2int();
if (!m & !p & !init) {
if (millis() - refresh < 500)continue;
refresh = millis();
goto display;
}
if (!init) timeout = millis() + 99999;
init = false;
if (m >= 2) cases --;
if (p >= 2) cases ++;
if (cases < 1) cases = 8;
if (cases > 8) cases = 1;
switch (cases) {
case 1:
if (m == 1) Mon --;
if (p == 1) Mon ++;
break;
case 2:
if (m == 1) Day --;
if (p == 1) Day ++;
break;
case 3:
if (m == 1) Yrs --;
if (p == 1) Yrs ++;
break;
case 4:
if (m == 1) Hrs --;
if (p == 1) Hrs ++;
break;
case 5:
if (m == 1) Min --;
if (p == 1) Min ++;
break;
case 6:
if (m == 1) Sec --;
if (p == 1) Sec ++;
break;
case 7:
if (m == 1 | p == 1) {
Rtc.SetDateTime(RtcDateTime(Yrs, Mon, Day, Hrs, Min, Sec));
return;
}
break;
case 8:
if (m == 1 | p == 1) return;
break;
}
if (Yrs < 2000)Yrs = 2099;
if (Yrs > 2099)Yrs = 2000;
if (Mon < 1)Mon = 12;
if (Mon > 12)Mon = 1;
if (Day < 1)Day = 31;
if (Day > 31)Day = 1;
if (Hrs < 0)Hrs = 23;
if (Hrs > 23)Hrs = 0;
if (Min < 0)Min = 59;
if (Min > 59)Min = 0;
if (Sec < 0)Sec = 59;
if (Sec > 59)Sec = 0;
static char date[11], time[9];
snprintf(date, 11, "%02u-%02u-%04u", Mon, Day, Yrs);
snprintf(time, 9, "%02u:%02u:%02u", Hrs, Min, Sec);
display:
u8g2.clearBuffer();
u8g2.drawRFrame(0, 0, 128, 64, 5);
u8g2.setFont(u8g2_font_t0_22b_mf);
u8g2.drawStr(9, 18, date);
u8g2.drawStr(20, 38, time);
u8g2.drawStr(8, 58, "SET EXIT");
switch (cases) {
case 1:
u8g2.drawFrame(8, 3, 24, 17);
break;
case 2:
u8g2.drawFrame(41, 3, 24, 17);
break;
case 3:
u8g2.drawFrame(74, 3, 46, 17);
break;
case 4:
u8g2.drawFrame(19, 23, 24, 17);
break;
case 5:
u8g2.drawFrame(52, 23, 24, 17);
break;
case 6:
u8g2.drawFrame(85, 23, 24, 17);
break;
case 7:
u8g2.drawFrame(7, 43, 36, 17);
break;
case 8:
u8g2.drawFrame(73, 43, 47, 17);
break;
}
u8g2.sendBuffer();
}
}
Simulate
RTC error
Try also to set the rtc
with only one Button!
LongPress to select