Hi @felmue,
thanks in advance for your exquisite answer, which clarity left me stunned. Kudos to you!
I missed the concept in the very first try because basically I'm doing my best to reduce the on-time, the main concept is that I'm not giving a shutdown(58) but a shutdown(time), so I didn't need to print the 58th second time then waiting for the refresh (worst case: 2sec on), I was directly updating the new time since the RTC was setted to trigger on the new minute tick (:actual_time+1 min). The simple solution is to print the previous minute or if xx:00 lcd full begin with refresh (so there isn't the need to subtract time cascading back to the year), than the new time, the on-time it's so rapid that the battery benefits and the system after two weeks is still running with no additional charges.
The epd refresh on min 00 is barely noticeable but I'm trying to understand if is really needed since I never get "bad pixels" that would motivate a screen refresh (with the M5.M5Ink.begin() ), maybe this will be the very last try to improve furthermore the on-time...
This is why I took so much time to answer here, I tought I would have give an answer in detail releasing the code here referring to it as the highest system autonomy that I reached but it still doesn't want to go off...
Thanks for your support!
Luca
void setup() {
digitalWrite(LED_EXT_PIN, HIGH); //Turn off LED
// Check power on reason before calling M5.begin(), which calls Rtc.begin() which clears the timer flag.
uint8_t data = 0;
Wire1.begin(21, 22);
Wire1.beginTransmission(0x51);
Wire1.write(0x01);
Wire1.endTransmission();
if (Wire1.requestFrom(0x51, 1)) {
data = Wire1.read();
}
//Init system but not EPD (prevent EPD refresh)
M5.begin(false);
RTC_TimeTypeDef time;
RTC_DateTypeDef date;
TimePageSprite.creatSprite(0, 0, 200, 200);
// Check timer flag
if ((data & 0b00001000) == 0b00001000) { //Reset by RTC alarm
M5.rtc.GetTime(&time);
M5.rtc.GetDate(&date);
//If hh:00 full refresh...
if (time.Minutes == 0) {
M5.M5Ink.begin();
//M5.M5Ink.clear(); //Already cleared in the M5.M5Ink.begin()
}
//...else
else {
//Init EPD without refreshing the screen
M5.M5Ink.init_without_reset();
M5.M5Ink.setEpdMode(epd_mode_t::epd_text);
M5.M5Ink.invertDisplay(true);
//Print previous hh:mm (prevent misprinting if a M5.M5Ink.clear() is not performed)
drawTimeAndDate(time, date, 1);
TimePageSprite.pushSprite();
}
}
else { //Reset by PON
digitalWrite(LED_EXT_PIN, LOW); //CONFIGURATION: LED on
//Start the system
M5.M5Ink.begin();
M5.M5Ink.clear();
//Check if EPD is correctly initialized
if (M5.M5Ink.isInit() == false) {
while (1){ //ERROR: strobe
digitalWrite(LED_EXT_PIN, LOW);
delay(500);
digitalWrite(LED_EXT_PIN, HIGH);
delay(500);
}
}
//Welcome screen
StartupPageSprite.creatSprite(0, 0, 200, 200, true);
StartupPageSprite.drawString(0, rowp*(rown++), "######## HELLO! ########");
StartupPageSprite.pushSprite();
//Fetch current time from Internet
getNTPTime();
M5.rtc.GetTime(&time);
M5.rtc.GetDate(&date);
StartupPageSprite.drawString(0, rowp*(rown++), "Going online...");
StartupPageSprite.pushSprite();
delay(1000);
M5.M5Ink.clear();
}
//Draw actual time and date
drawTimeAndDate(time, date, 0);
TimePageSprite.pushSprite();
//Config RTC for wakeup on the next minute (via HW interrupt) and shutdown ESP
time.Seconds=0;
if(time.Minutes<59) time.Minutes++;
else{
time.Minutes=00;
if(time.Hours<23) time.Hours++;
else time.Hours=00;
}
M5.shutdown(time);
//Following code is executed only in USB powered mode (e.g. Recharge\Debug)
delay(60*1000);
ESP.restart(); //<--Not working! Debug me!
}