From 0ec4916ecab720b119a58831cee1a956566a8df0 Mon Sep 17 00:00:00 2001 From: RomanAlexandroff Date: Sat, 22 Aug 2026 14:30:56 +0200 Subject: [PATCH 1/3] refactor display-handling.cpp --- src/42-Smart-Cluster-Sign.h | 4 +- src/battery_management.cpp | 4 +- src/cluster_number_mode.cpp | 8 +- src/constants.h | 12 +- src/display_handling.cpp | 336 +++++++++++++++++++++++++++--------- src/display_handling.h | 60 +++++++ src/exam_mode.cpp | 12 +- src/file_system.cpp | 2 +- src/ota.cpp | 7 +- 9 files changed, 333 insertions(+), 112 deletions(-) create mode 100644 src/display_handling.h diff --git a/src/42-Smart-Cluster-Sign.h b/src/42-Smart-Cluster-Sign.h index a166a1a..ca8066d 100644 --- a/src/42-Smart-Cluster-Sign.h +++ b/src/42-Smart-Cluster-Sign.h @@ -48,9 +48,7 @@ void IRAM_ATTR isr_warning(void); void cluster_number_mode(unsigned int* p_sleep_length); /* display_handling.cpp */ -void draw_colour_bitmap(const unsigned char* black_image, const unsigned char* red_image); -void IRAM_ATTR display_cluster_number(IMAGE_t mode); -void clear_display(void); +void IRAM_ATTR draw_on_display(IMAGE_t mode); void IRAM_ATTR display_init(void); /* exam_mode.cpp */ diff --git a/src/battery_management.cpp b/src/battery_management.cpp index 4a117a6..490cec6 100644 --- a/src/battery_management.cpp +++ b/src/battery_management.cpp @@ -55,7 +55,7 @@ void battery_monitor(void) return ; if (battery < BATTERY_CRITICAL) { - display_cluster_number(LOW_BATTERY); + draw_on_display(LOW_BATTERY); DEBUG_PRINTF("[BATTERY] Battery charge 0%%! Going into extensive sleep\n\n"); send_telegram_message(compose_message(DEAD_BATTERY, 0)); com_g.block_validation = true; @@ -63,7 +63,7 @@ void battery_monitor(void) } else if (battery < BATTERY_GOOD) { - display_cluster_number(LOW_BATTERY); + draw_on_display(LOW_BATTERY); DEBUG_PRINTF("[BATTERY] Low battery. Need charging.\n\n"); send_telegram_message(compose_message(LOW_BATTERY, 0)); } diff --git a/src/cluster_number_mode.cpp b/src/cluster_number_mode.cpp index eb44d2f..6c5023a 100644 --- a/src/cluster_number_mode.cpp +++ b/src/cluster_number_mode.cpp @@ -21,7 +21,7 @@ static bool handle_secret_expiration(void) days_left = expiration_counter(); if (days_left <= 3 && days_left != FAILED_TO_COUNT) { - display_cluster_number(SECRET_EXPIRED); + draw_on_display(SECRET_EXPIRED); DEBUG_PRINTF("\n[INTRA] IT IS TIME TO UPDATE THE SECRET!\n"); send_telegram_message(compose_message(SECRET_EXPIRED, days_left)); return (true); @@ -56,7 +56,7 @@ static bool ensure_exams(unsigned int* p_sleep_length) { send_telegram_message(compose_message(intra_status, 0)); WiFi.mode(WIFI_OFF); - display_cluster_number(INTRA_ERROR); + draw_on_display(INTRA_ERROR); DEBUG_PRINTF("\n[INTRA] ERROR OBTAINING EXAMS. Turning off\n"); rtc_g.exam_status = false; *p_sleep_length = time_till_wakeup(); @@ -92,7 +92,7 @@ void cluster_number_mode(unsigned int* p_sleep_length) *p_sleep_length = REBOOT; else { - display_cluster_number(EXAM_DAY); + draw_on_display(EXAM_DAY); *p_sleep_length = time_till_event(rtc_g.exam_start_hour - 1, rtc_g.exam_start_minutes); } return; @@ -100,6 +100,6 @@ void cluster_number_mode(unsigned int* p_sleep_length) *p_sleep_length = time_till_wakeup(); if (handle_secret_expiration()) return; - display_cluster_number(DEFAULT_IMG); + draw_on_display(CLUSTER_DEFAULT); } diff --git a/src/constants.h b/src/constants.h index 3677f77..bc03168 100644 --- a/src/constants.h +++ b/src/constants.h @@ -55,8 +55,7 @@ /* Images constants */ typedef enum { - CLUSTER = 1000, - DEFAULT_IMG, + CLUSTER_DEFAULT = 100, INTRA_ERROR, SECRET_EXPIRED, EXAM_DAY, @@ -67,12 +66,17 @@ typedef enum { OTA_FAIL, OTA_CANCELED, TELEGRAM_ERROR, - TELEGRAM_STATUS + TELEGRAM_STATUS, + PREEXAM_50, + PREEXAM_25, + PREEXAM_5, + EXAM_ACTIVE, + BLANK } IMAGE_t; /* Errors constants */ typedef enum { - UNKNOWN = 2000, + UNKNOWN = 200, TIME_OK, TIME_NO_WIFI, TIME_NO_SERVER, diff --git a/src/display_handling.cpp b/src/display_handling.cpp index 8803935..ff205fe 100644 --- a/src/display_handling.cpp +++ b/src/display_handling.cpp @@ -12,7 +12,7 @@ /* ************************************************************************** */ #include "42-Smart-Cluster-Sign.h" - +#include "display_handling.h" /* * For all the text notes on the right side @@ -49,7 +49,7 @@ static void draw_text(String output, uint16_t x, uint16_t y) * the cluster number. * Partial display update, text only, no images */ -static void draw_exam_start_time(void) +static void draw_exam_start_time(uint16_t hour, uint16_t minutes) { String text; const int16_t text_x PROGMEM = 27; @@ -62,11 +62,11 @@ static void draw_exam_start_time(void) watchdog_stop(); display.init(115200); // insures the display is still on text = "TODAY AT "; - text += String(rtc_g.exam_start_hour); - if (rtc_g.exam_start_minutes < 10) - text += ":0" + String(rtc_g.exam_start_minutes); + text += String(hour); + if (minutes < 10) + text += ":0" + String(minutes); else - text += ":" + String(rtc_g.exam_start_minutes); + text += ":" + String(minutes); DEBUG_PRINTF("[THE DISPLAY] Printing the exam time: %s\n", text.c_str()); display.setFont(&FreeSansBold24pt7b); display.setTextColor(GxEPD_BLACK); @@ -108,7 +108,7 @@ static void draw_bitmap_partial_update(const unsigned char* image, uint16_t widt * For full-screen b/r/w images. * Full display update, Black-Red-White only */ -void draw_colour_bitmap(const unsigned char* black_image, const unsigned char* red_image) +static void draw_colour_bitmap_raw(const unsigned char* black_image, const unsigned char* red_image) { watchdog_stop(); display.setRotation(0); @@ -146,107 +146,271 @@ static void draw_bitmap_full_update(const unsigned char* image, uint16_t width, /* -* This function displays the number of the cluster and -* any additional image/message separately. -* The function ensures that whatever is already drawn -* on the display does not get drawn repeatedly. -* -* "displaying_now = CLUSTER" is there to unblock drawing -* of ALL the additional images/messages. Useful after exams. +* Decides what to draw on the display in Exam mode. */ -void display_cluster_number(IMAGE_t mode) +static void draw_exam_screen(EXAM_SCREEN_t screen) { - RTC_DATA_ATTR static bool display_cluster; - RTC_DATA_ATTR static IMAGE_t displaying_now; + if (screen == EXAM_SCREEN_PRE_50) + draw_colour_bitmap_raw(preexam_50mins, preexam_warning_red); + else if (screen == EXAM_SCREEN_PRE_25) + draw_colour_bitmap_raw(preexam_25mins, preexam_warning_red); + else if (screen == EXAM_SCREEN_PRE_5) + draw_colour_bitmap_raw(preexam_5mins, preexam_warning_red); + else if (screen == EXAM_SCREEN_ACTIVE) + draw_colour_bitmap_raw(exam_warning_black, exam_warning_red); +} - watchdog_reset(); - /* DECIDE WHETHER TO DRAW ANYTHING AT ALL */ - if (display_cluster && mode == displaying_now) - { - DEBUG_PRINTF("\n[THE DISPLAY] Nothing new to draw. Drawing aborted\n\n"); - return; - } - /* DECIDE WHETHER TO DRAW THE CLUSTER NUMBER PART OR NOT */ - if (!display_cluster) - { - DEBUG_PRINTF("\n[THE DISPLAY] Drawing the cluster number with...\n"); - draw_bitmap_full_update(cluster_number_img, 630, 480); - display_cluster = true; - displaying_now = CLUSTER; - } - /* DECIDE WHAT TO DRAW ON THE SIDE NOTE PART */ - if (mode == DEFAULT_IMG && (displaying_now != DEFAULT_IMG && displaying_now != LOW_BATTERY)) - { - DEBUG_PRINTF("[THE DISPLAY] ...the default cluster icons\n"); + +/* +* In Cluster-number mode there is a strip of display on +* the right where some useful information gets displayed. +* This function decides what to draw on that strip. +*/ +static void draw_cluster_side(const DISPLAY_STATE_t& state) +{ + if (state.cluster_side == CLUSTER_SIDE_DEFAULT) draw_bitmap_partial_update(default_cluster_icons, 170, 480); - displaying_now = DEFAULT_IMG; - } - else if (mode == INTRA_ERROR && displaying_now != INTRA_ERROR) - { - DEBUG_PRINTF("[THE DISPLAY] ...the Intra error warning\n"); + else if (state.cluster_side == CLUSTER_SIDE_INTRA_ERROR) draw_bitmap_partial_update(intra_error_img, 170, 480); - displaying_now = INTRA_ERROR; - } - else if (mode == SECRET_EXPIRED && displaying_now != SECRET_EXPIRED) - { - DEBUG_PRINTF("[THE DISPLAY] ...the Secret expiration warning\n"); + else if (state.cluster_side == CLUSTER_SIDE_SECRET_EXPIRED) draw_bitmap_partial_update(secret_expire_img, 170, 480); - displaying_now = SECRET_EXPIRED; - } - else if (mode == EXAM_DAY && displaying_now != EXAM_DAY) + else if (state.cluster_side == CLUSTER_SIDE_EXAM_DAY) { - DEBUG_PRINTF("[THE DISPLAY] ...the exam time note\n"); draw_bitmap_partial_update(reserve_note_img, 170, 480); - draw_exam_start_time(); - display_cluster = false; - displaying_now = EXAM_DAY; + draw_exam_start_time(state.exam_hour, state.exam_minutes); } - else if (mode == LOW_BATTERY && displaying_now != LOW_BATTERY) - { - DEBUG_PRINTF("[THE DISPLAY] ...the low battery warning\n"); + else if (state.cluster_side == CLUSTER_SIDE_LOW_BATTERY) draw_bitmap_partial_update(low_battery_img, 170, 480); - displaying_now = LOW_BATTERY; - } - else if (mode == OTA_WAITING && displaying_now != OTA_WAITING) - { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); + else if (state.cluster_side == CLUSTER_SIDE_OTA_WAITING) draw_text(" WAITING FOR\n OTA UPDATE", 0, 710); - displaying_now = OTA_WAITING; - } - else if (mode == OTA_SUCCESS && displaying_now != OTA_SUCCESS) - { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); + else if (state.cluster_side == CLUSTER_SIDE_OTA_SUCCESS) draw_text(" OTA UPDATE\n SUCCESS", 0, 710); - displaying_now = OTA_SUCCESS; + else if (state.cluster_side == CLUSTER_SIDE_OTA_FAIL) + draw_text(" OTA UPDATE\n FAIL", 0, 710); + else if (state.cluster_side == CLUSTER_SIDE_OTA_CANCELED) + draw_text(" OTA UPDATE\n WAS CANCELED", 0, 710); + else if (state.cluster_side == CLUSTER_SIDE_TELEGRAM_ERROR) + draw_text(" TELEGRAM BOT\n ERROR", 0, 710); +} + + +/* +* Compares the two given display states. +* Returns true if they are completely equal. +* Otherwise returns false. +*/ +static bool same_display_state(const DISPLAY_STATE_t& a, const DISPLAY_STATE_t& b) +{ + return ( + a.view == b.view && + a.cluster_side == b.cluster_side && + a.exam_screen == b.exam_screen && + a.exam_hour == b.exam_hour && + a.exam_minutes == b.exam_minutes + ); +} + + +/* +* Decides what to draw on the display and what not to. +* The function ensures that whatever is already drawn +* on the display does not get redrawn repeatedly. +*/ +static void filter_request_and_draw(const DISPLAY_STATE_t& requested) +{ + bool cluster_already_visible; + + watchdog_reset(); + if (display_cache_valid && same_display_state(display_cache, requested)) + { + DEBUG_PRINTF("\n[THE DISPLAY] Nothing new to draw. Drawing aborted\n\n"); + return; } - else if (mode == OTA_FAIL && displaying_now != OTA_FAIL) + if (requested.view == DISPLAY_VIEW_BLANK) { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); - draw_text(" OTA UPDATE\n FAIL", 0, 710); - displaying_now = OTA_FAIL; + display.clearScreen(); + display.writeScreenBuffer(); + display_cache = requested; + display_cache_valid = true; + return; } - else if (mode == OTA_CANCELED && displaying_now != OTA_CANCELED) + if (requested.view == DISPLAY_VIEW_EXAM) { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); - draw_text(" OTA UPDATE\n WAS CANCELED", 0, 710); - displaying_now = OTA_CANCELED; + draw_exam_screen(requested.exam_screen); + display_cache = requested; + display_cache_valid = true; + return; } - else if (mode == TELEGRAM_ERROR && displaying_now != TELEGRAM_ERROR) + if (requested.view == DISPLAY_VIEW_CLUSTER) { - DEBUG_PRINTF("[THE DISPLAY] ...the Telegram error warning\n"); - draw_text(" TELEGRAM BOT\n ERROR", 0, 710); - displaying_now = TELEGRAM_ERROR; - } - DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); + cluster_already_visible = display_cache_valid && (display_cache.view == DISPLAY_VIEW_CLUSTER); + if (!cluster_already_visible) + draw_bitmap_full_update(cluster_number_img, 630, 480); + if (!cluster_already_visible || + display_cache.cluster_side != requested.cluster_side || + display_cache.exam_hour != requested.exam_hour || + display_cache.exam_minutes != requested.exam_minutes) + { + draw_cluster_side(requested); + } + display_cache = requested; + display_cache_valid = true; + DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); + } } -void clear_display(void) + +static void display_draw_cluster_default(void) { - watchdog_reset(); - display.clearScreen(); - display.writeScreenBuffer(); + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_DEFAULT, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with default cluster icons\n"); + filter_request_and_draw(state); } +static void display_draw_cluster_intra_error(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_INTRA_ERROR, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with Intra error warning\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_secret_expired(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_SECRET_EXPIRED, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with Secret expiration warning\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_low_battery(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_LOW_BATTERY, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with low battery warning\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_ota_waiting(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_WAITING, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with OTA waiting notification\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_ota_success(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_SUCCESS, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with OTA success notification\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_ota_fail(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_FAIL, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with failed OTA update notification\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_ota_canceled(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_CANCELED, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with canceled OTA update notification\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_telegram_error(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_TELEGRAM_ERROR, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with Telegram error warning\n"); + filter_request_and_draw(state); +} + +static void display_draw_cluster_exam_day(uint16_t hour, uint16_t minutes) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_EXAM_DAY, EXAM_SCREEN_NONE, hour, minutes}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with exam time notification\n"); + filter_request_and_draw(state); +} + +static void display_draw_exam_pre_50(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_50, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen pre-exam warning with 50 mins left\n"); + filter_request_and_draw(state); +} + +static void display_draw_exam_pre_25(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_25, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen pre-exam warning with 25 mins left\n"); + filter_request_and_draw(state); +} + +static void display_draw_exam_pre_5(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_5, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen pre-exam warning with 5 mins left\n"); + filter_request_and_draw(state); +} + +static void display_draw_exam_active(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_ACTIVE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen Exam sign\n"); + filter_request_and_draw(state); +} + +static void display_clear(void) +{ + DISPLAY_STATE_t state = {DISPLAY_VIEW_BLANK, CLUSTER_SIDE_NONE, EXAM_SCREEN_NONE, 0, 0}; + DEBUG_PRINTF("[THE DISPLAY] Requested to clear the display\n"); + filter_request_and_draw(state); +} + + +/* +* Universal API function for drawing anything +* on the eInk display. +*/ +void draw_on_display(IMAGE_t image) +{ + if (image == EXAM_ACTIVE) + display_draw_exam_active(); + else if (image == PREEXAM_5) + display_draw_exam_pre_5(); + else if (image == PREEXAM_25) + display_draw_exam_pre_25(); + else if (image == PREEXAM_50) + display_draw_exam_pre_50(); + else if (image == CLUSTER_DEFAULT) + display_draw_cluster_default(); + else if (image == INTRA_ERROR) + display_draw_cluster_intra_error(); + else if (image == SECRET_EXPIRED) + display_draw_cluster_secret_expired(); + else if (image == EXAM_DAY) + display_draw_cluster_exam_day(rtc_g.exam_start_hour, rtc_g.exam_start_minutes); + else if (image == LOW_BATTERY) + display_draw_cluster_low_battery(); + else if (image == OTA_WAITING) + display_draw_cluster_ota_waiting(); + else if (image == OTA_SUCCESS) + display_draw_cluster_ota_success(); + else if (image == OTA_FAIL) + display_draw_cluster_ota_fail(); + else if (image == OTA_CANCELED) + display_draw_cluster_ota_canceled(); + else if (image == TELEGRAM_ERROR) + display_draw_cluster_telegram_error(); + else if (image == BLANK) + display_clear(); + else + { + DEBUG_PRINTF("[THE DISPLAY] Unsupported image requested: %d\n", image); + return; + } + DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); +} + + void display_init(void) { watchdog_reset(); @@ -254,4 +418,4 @@ void display_init(void) SPI.begin(SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN, SPI_SS_PIN); display.init(115200); } - + \ No newline at end of file diff --git a/src/display_handling.h b/src/display_handling.h new file mode 100644 index 0000000..9fb03f9 --- /dev/null +++ b/src/display_handling.h @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* display_handling.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: roaleksa +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/08/22 10:00:00 by roaleksa #+# #+# */ +/* Updated: 2026/08/22 15:00:00 by roaleksa ### ########.fr */ +/* */ +/* */ +/* For use with display_handling.cpp only! Do not include elsewhere. */ +/* */ +/* ************************************************************************** */ + +#ifndef DISPLAY_HANDLING_H +# define DISPLAY_HANDLING_H + +typedef enum { + DISPLAY_VIEW_INVALID, + DISPLAY_VIEW_BLANK, + DISPLAY_VIEW_CLUSTER, + DISPLAY_VIEW_EXAM +} DISPLAY_VIEW_t; + +typedef enum { + CLUSTER_SIDE_NONE, + CLUSTER_SIDE_DEFAULT, + CLUSTER_SIDE_INTRA_ERROR, + CLUSTER_SIDE_SECRET_EXPIRED, + CLUSTER_SIDE_EXAM_DAY, + CLUSTER_SIDE_LOW_BATTERY, + CLUSTER_SIDE_OTA_WAITING, + CLUSTER_SIDE_OTA_SUCCESS, + CLUSTER_SIDE_OTA_FAIL, + CLUSTER_SIDE_OTA_CANCELED, + CLUSTER_SIDE_TELEGRAM_ERROR +} CLUSTER_SIDE_t; + +typedef enum { + EXAM_SCREEN_NONE, + EXAM_SCREEN_PRE_50, + EXAM_SCREEN_PRE_25, + EXAM_SCREEN_PRE_5, + EXAM_SCREEN_ACTIVE +} EXAM_SCREEN_t; + +typedef struct { + DISPLAY_VIEW_t view; + CLUSTER_SIDE_t cluster_side; + EXAM_SCREEN_t exam_screen; + uint16_t exam_hour; + uint16_t exam_minutes; +} DISPLAY_STATE_t; + +RTC_DATA_ATTR static bool display_cache_valid; +RTC_DATA_ATTR static DISPLAY_STATE_t display_cache; + +#endif + \ No newline at end of file diff --git a/src/exam_mode.cpp b/src/exam_mode.cpp index fb11cd9..5c7a95c 100644 --- a/src/exam_mode.cpp +++ b/src/exam_mode.cpp @@ -18,9 +18,7 @@ static unsigned int exam(void) watchdog_reset(); exam_remaining_time = time_till_event(com_g.exam_end_hour, com_g.exam_end_minutes); - DEBUG_PRINTF("\n[THE DISPLAY] Drawing the Exam sign...\n"); - draw_colour_bitmap(exam_warning_black, exam_warning_red); // execution takes 25 sec - DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); + draw_on_display(EXAM_ACTIVE); // execution takes 25 sec rtc_g.exam_status = false; return (exam_remaining_time); } @@ -38,21 +36,19 @@ static void preexam_warning(unsigned int* p_preexam_time) minutes = time_sync(*p_preexam_time); if (minutes == 60 || minutes == 50) { - DEBUG_PRINTF("\n[THE DISPLAY] Drawing the Reservation sign...\n"); - draw_colour_bitmap(preexam_50mins, preexam_warning_red); // execution takes 25 sec - DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); + draw_on_display(PREEXAM_50); // execution takes 25 sec ft_delay((minutes - 40) * 60000); minutes = 40; } if (minutes == 40 || minutes == 30 || minutes == 20) { - draw_colour_bitmap(preexam_25mins, preexam_warning_red); // execution takes 25 sec + draw_on_display(PREEXAM_25); // execution takes 25 sec ft_delay((minutes - 10) * 60000); minutes = 10; } if (minutes == 10) { - draw_colour_bitmap(preexam_5mins, preexam_warning_red); // execution takes 25 sec + draw_on_display(PREEXAM_5); // execution takes 25 sec ft_delay(480000); } *p_preexam_time = 0; diff --git a/src/file_system.cpp b/src/file_system.cpp index a1595e3..04946f6 100644 --- a/src/file_system.cpp +++ b/src/file_system.cpp @@ -77,7 +77,7 @@ void data_integrity_check(void) } else DEBUG_PRINTF("\n[FILE SYSTEM] Failed to create the chat_id.txt file!\n"); - display_cluster_number(TELEGRAM_ERROR); + draw_on_display(TELEGRAM_ERROR); } data_restore("/secret.txt"); data_restore("/chat_id.txt"); diff --git a/src/ota.cpp b/src/ota.cpp index 5b0e5d3..aafcb39 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -466,18 +466,17 @@ static OTA_RESULT_t ota_check_and_update(void) /* PROCEED TO DOWNLOADING THE SOFTWARE AND FLASHING THE DEVICE */ ota_send_telegram(String(DEVICE_NAME) + " found OTA update. Downloading firmware..."); - display_cluster_number(OTA_WAITING); + draw_on_display(OTA_WAITING); watchdog_stop(); if (!ota_download_and_flash(target)) { watchdog_start(); - display_cluster_number(OTA_FAIL); + draw_on_display(OTA_FAIL); ota_send_telegram(String(DEVICE_NAME) + " failed OTA update. Try again later."); ft_delay(5000); - clear_display(); return (OTA_RESULT_ERR_FIRMWARE_DOWNLOAD); } - display_cluster_number(OTA_SUCCESS); + draw_on_display(OTA_SUCCESS); ota_send_telegram(String(DEVICE_NAME) + " installed OTA update. Rebooting..."); ft_delay(3000); ESP.restart(); From b9db45ebc50f00ab19263c553affa184d87e67cf Mon Sep 17 00:00:00 2001 From: RomanAlexandroff Date: Sat, 22 Aug 2026 23:14:39 +0200 Subject: [PATCH 2/3] update the logic and fix debugging messages --- src/display_handling.cpp | 238 +++++++++++++++++---------------------- 1 file changed, 102 insertions(+), 136 deletions(-) diff --git a/src/display_handling.cpp b/src/display_handling.cpp index ff205fe..9283d54 100644 --- a/src/display_handling.cpp +++ b/src/display_handling.cpp @@ -6,7 +6,7 @@ /* By: raleksan +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/09 13:00:00 by raleksan #+# #+# */ -/* Updated: 2024/11/27 18:30:00 by raleksan ### ########.fr */ +/* Updated: 2026/08/22 18:30:00 by roaleksa ### ########.fr */ /* */ /* */ /* ************************************************************************** */ @@ -151,13 +151,27 @@ static void draw_bitmap_full_update(const unsigned char* image, uint16_t width, static void draw_exam_screen(EXAM_SCREEN_t screen) { if (screen == EXAM_SCREEN_PRE_50) + { + DEBUG_PRINTF("\n[THE DISPLAY] Drawing Pre-exam warning with the \"50 minutes left\" note\n"); draw_colour_bitmap_raw(preexam_50mins, preexam_warning_red); + } else if (screen == EXAM_SCREEN_PRE_25) + { + DEBUG_PRINTF("\n[THE DISPLAY] Drawing Pre-exam warning with the \"25 minutes left\" note\n"); draw_colour_bitmap_raw(preexam_25mins, preexam_warning_red); + } else if (screen == EXAM_SCREEN_PRE_5) + { + DEBUG_PRINTF("\n[THE DISPLAY] Drawing Pre-exam warning with the \"5 minutes left\" note\n"); draw_colour_bitmap_raw(preexam_5mins, preexam_warning_red); + } else if (screen == EXAM_SCREEN_ACTIVE) + { + DEBUG_PRINTF("\n[THE DISPLAY] Drawing full-screen EXAM IN PROGRESS sign\n"); draw_colour_bitmap_raw(exam_warning_black, exam_warning_red); + } + else + DEBUG_PRINTF("[THE DISPLAY] Unknown EXAM_SCREEN signature! Error!\n"); } @@ -169,28 +183,58 @@ static void draw_exam_screen(EXAM_SCREEN_t screen) static void draw_cluster_side(const DISPLAY_STATE_t& state) { if (state.cluster_side == CLUSTER_SIDE_DEFAULT) + { + DEBUG_PRINTF("[THE DISPLAY] ...the default cluster icons\n"); draw_bitmap_partial_update(default_cluster_icons, 170, 480); + } else if (state.cluster_side == CLUSTER_SIDE_INTRA_ERROR) + { + DEBUG_PRINTF("[THE DISPLAY] ...the Intra error warning\n"); draw_bitmap_partial_update(intra_error_img, 170, 480); + } else if (state.cluster_side == CLUSTER_SIDE_SECRET_EXPIRED) + { + DEBUG_PRINTF("[THE DISPLAY] ...the Secret expiration warning\n"); draw_bitmap_partial_update(secret_expire_img, 170, 480); + } else if (state.cluster_side == CLUSTER_SIDE_EXAM_DAY) { + DEBUG_PRINTF("[THE DISPLAY] ...the exam time note\n"); draw_bitmap_partial_update(reserve_note_img, 170, 480); draw_exam_start_time(state.exam_hour, state.exam_minutes); } else if (state.cluster_side == CLUSTER_SIDE_LOW_BATTERY) + { + DEBUG_PRINTF("[THE DISPLAY] ...the low battery warning\n"); draw_bitmap_partial_update(low_battery_img, 170, 480); + } else if (state.cluster_side == CLUSTER_SIDE_OTA_WAITING) + { + DEBUG_PRINTF("[THE DISPLAY] ...the OTA waiting notification\n"); draw_text(" WAITING FOR\n OTA UPDATE", 0, 710); + } else if (state.cluster_side == CLUSTER_SIDE_OTA_SUCCESS) + { + DEBUG_PRINTF("[THE DISPLAY] ...the OTA success notification\n"); draw_text(" OTA UPDATE\n SUCCESS", 0, 710); + } else if (state.cluster_side == CLUSTER_SIDE_OTA_FAIL) + { + DEBUG_PRINTF("[THE DISPLAY] ...the OTA fail notification\n"); draw_text(" OTA UPDATE\n FAIL", 0, 710); + } else if (state.cluster_side == CLUSTER_SIDE_OTA_CANCELED) + { + DEBUG_PRINTF("[THE DISPLAY] ...the OTA canceled notification\n"); draw_text(" OTA UPDATE\n WAS CANCELED", 0, 710); + } else if (state.cluster_side == CLUSTER_SIDE_TELEGRAM_ERROR) + { + DEBUG_PRINTF("[THE DISPLAY] ...the Telegram error warning\n"); draw_text(" TELEGRAM BOT\n ERROR", 0, 710); + } + else + DEBUG_PRINTF("[THE DISPLAY] ...unknown CLUSTER_SIDE signature! Error!\n"); } @@ -224,28 +268,33 @@ static void filter_request_and_draw(const DISPLAY_STATE_t& requested) if (display_cache_valid && same_display_state(display_cache, requested)) { DEBUG_PRINTF("\n[THE DISPLAY] Nothing new to draw. Drawing aborted\n\n"); - return; + return ; } if (requested.view == DISPLAY_VIEW_BLANK) { + DEBUG_PRINTF("\n[THE DISPLAY] Drawing a blank display\n\n"); display.clearScreen(); display.writeScreenBuffer(); display_cache = requested; display_cache_valid = true; - return; + return ; } if (requested.view == DISPLAY_VIEW_EXAM) { draw_exam_screen(requested.exam_screen); display_cache = requested; display_cache_valid = true; - return; + return ; } if (requested.view == DISPLAY_VIEW_CLUSTER) { cluster_already_visible = display_cache_valid && (display_cache.view == DISPLAY_VIEW_CLUSTER); + DEBUG_PRINTF("\n[THE DISPLAY] Drawing "); if (!cluster_already_visible) + { + DEBUG_PRINTF("the Cluster number with...\n"); draw_bitmap_full_update(cluster_number_img, 630, 480); + } if (!cluster_already_visible || display_cache.cluster_side != requested.cluster_side || display_cache.exam_hour != requested.exam_hour || @@ -255,159 +304,76 @@ static void filter_request_and_draw(const DISPLAY_STATE_t& requested) } display_cache = requested; display_cache_valid = true; - DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); } } -static void display_draw_cluster_default(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_DEFAULT, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with default cluster icons\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_intra_error(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_INTRA_ERROR, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with Intra error warning\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_secret_expired(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_SECRET_EXPIRED, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with Secret expiration warning\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_low_battery(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_LOW_BATTERY, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with low battery warning\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_ota_waiting(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_WAITING, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with OTA waiting notification\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_ota_success(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_SUCCESS, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with OTA success notification\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_ota_fail(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_FAIL, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with failed OTA update notification\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_ota_canceled(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_CANCELED, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with canceled OTA update notification\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_telegram_error(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_TELEGRAM_ERROR, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with Telegram error warning\n"); - filter_request_and_draw(state); -} - -static void display_draw_cluster_exam_day(uint16_t hour, uint16_t minutes) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_EXAM_DAY, EXAM_SCREEN_NONE, hour, minutes}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Cluster number with exam time notification\n"); - filter_request_and_draw(state); -} - -static void display_draw_exam_pre_50(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_50, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen pre-exam warning with 50 mins left\n"); - filter_request_and_draw(state); -} - -static void display_draw_exam_pre_25(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_25, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen pre-exam warning with 25 mins left\n"); - filter_request_and_draw(state); -} - -static void display_draw_exam_pre_5(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_5, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen pre-exam warning with 5 mins left\n"); - filter_request_and_draw(state); -} - -static void display_draw_exam_active(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_ACTIVE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to draw: Full-screen Exam sign\n"); - filter_request_and_draw(state); -} - -static void display_clear(void) -{ - DISPLAY_STATE_t state = {DISPLAY_VIEW_BLANK, CLUSTER_SIDE_NONE, EXAM_SCREEN_NONE, 0, 0}; - DEBUG_PRINTF("[THE DISPLAY] Requested to clear the display\n"); - filter_request_and_draw(state); -} - - /* -* Universal API function for drawing anything -* on the eInk display. +* Most of the images consists of multiple parts that +* have to be printed together in order to achive +* the final desirable result. This function contains +* "recipes" for all the images that the device can +* draw on the display. When it is told what image +* the device wants to draw, the function looks up +* the recipe for the image and puts it into the state +* struct. */ -void draw_on_display(IMAGE_t image) +static bool display_state_init(IMAGE_t image, DISPLAY_STATE_t* state) { - if (image == EXAM_ACTIVE) - display_draw_exam_active(); - else if (image == PREEXAM_5) - display_draw_exam_pre_5(); - else if (image == PREEXAM_25) - display_draw_exam_pre_25(); - else if (image == PREEXAM_50) - display_draw_exam_pre_50(); - else if (image == CLUSTER_DEFAULT) - display_draw_cluster_default(); + if (!state) + return (false); + *state = {DISPLAY_VIEW_INVALID, CLUSTER_SIDE_NONE, EXAM_SCREEN_NONE, 0, 0}; + if (image == CLUSTER_DEFAULT) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_DEFAULT, EXAM_SCREEN_NONE, 0, 0}; else if (image == INTRA_ERROR) - display_draw_cluster_intra_error(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_INTRA_ERROR, EXAM_SCREEN_NONE, 0, 0}; else if (image == SECRET_EXPIRED) - display_draw_cluster_secret_expired(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_SECRET_EXPIRED, EXAM_SCREEN_NONE, 0, 0}; else if (image == EXAM_DAY) - display_draw_cluster_exam_day(rtc_g.exam_start_hour, rtc_g.exam_start_minutes); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_EXAM_DAY, EXAM_SCREEN_NONE, rtc_g.exam_start_hour, rtc_g.exam_start_minutes}; else if (image == LOW_BATTERY) - display_draw_cluster_low_battery(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_LOW_BATTERY, EXAM_SCREEN_NONE, 0, 0}; else if (image == OTA_WAITING) - display_draw_cluster_ota_waiting(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_WAITING, EXAM_SCREEN_NONE, 0, 0}; else if (image == OTA_SUCCESS) - display_draw_cluster_ota_success(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_SUCCESS, EXAM_SCREEN_NONE, 0, 0}; else if (image == OTA_FAIL) - display_draw_cluster_ota_fail(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_FAIL, EXAM_SCREEN_NONE, 0, 0}; else if (image == OTA_CANCELED) - display_draw_cluster_ota_canceled(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_CANCELED, EXAM_SCREEN_NONE, 0, 0}; else if (image == TELEGRAM_ERROR) - display_draw_cluster_telegram_error(); + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_TELEGRAM_ERROR, EXAM_SCREEN_NONE, 0, 0}; + else if (image == PREEXAM_50) + *state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_50, 0, 0}; + else if (image == PREEXAM_25) + *state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_25, 0, 0}; + else if (image == PREEXAM_5) + *state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_PRE_5, 0, 0}; + else if (image == EXAM_ACTIVE) + *state = {DISPLAY_VIEW_EXAM, CLUSTER_SIDE_NONE, EXAM_SCREEN_ACTIVE, 0, 0}; else if (image == BLANK) - display_clear(); + *state = {DISPLAY_VIEW_BLANK, CLUSTER_SIDE_NONE, EXAM_SCREEN_NONE, 0, 0}; else { DEBUG_PRINTF("[THE DISPLAY] Unsupported image requested: %d\n", image); - return; + return (false); } - DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); + return (true); +} + + +/* +* Universal API function for drawing anything +* on the eInk display. +*/ +void draw_on_display(IMAGE_t image) +{ + DISPLAY_STATE_t state; + + if (!display_state_init(image, &state)) + return ; + filter_request_and_draw(state); + DEBUG_PRINTF("[THE DISPLAY] The drawing process is concluded\n"); } From fcf8808d7e6232dccd23b456bd7f4036e0174d7c Mon Sep 17 00:00:00 2001 From: RomanAlexandroff Date: Sun, 23 Aug 2026 17:57:12 +0200 Subject: [PATCH 3/3] fix endless blocking wait in time_sync if device woken up in Exam mode --- src/config.h | 2 +- src/constants.h | 5 +++-- src/exam_mode.cpp | 8 +++++--- src/time_utilities.cpp | 10 +++++----- src/utils.cpp | 4 ++-- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/config.h b/src/config.h index ccbc9f6..1f983ea 100644 --- a/src/config.h +++ b/src/config.h @@ -17,7 +17,7 @@ #ifndef CONFIG_H # define CONFIG_H -# define SOFTWARE_VERSION 4.38 +# define SOFTWARE_VERSION 4.40 # define DEVICE_NAME "42PRAGUEAPI SCREEN" # define DEBUG // comment out this line to turn off Serial output diff --git a/src/constants.h b/src/constants.h index bc03168..8325285 100644 --- a/src/constants.h +++ b/src/constants.h @@ -21,8 +21,9 @@ # define REBOOT 1000 # define mS_TO_uS_FACTOR 1000ull // milliseconds to microseconds # define mS_TO_S_FACTOR 1000ul // milliseconds to seconds -# define MINUTE_MS 60000 -# define HOUR_MS 3600000 +# define ONE_SECOND_MS 1000 +# define ONE_MINUTE_MS 60000 +# define ONE_HOUR_MS 3600000 # define MONTHS_DAYS 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 # define YEAR_DAYS 365 # define NOT_FOUND -1 diff --git a/src/exam_mode.cpp b/src/exam_mode.cpp index 5c7a95c..e89136a 100644 --- a/src/exam_mode.cpp +++ b/src/exam_mode.cpp @@ -73,10 +73,12 @@ void exam_mode(void) if (!rtc_g.exam_status) return ; preexam_time = time_till_event(rtc_g.exam_start_hour, rtc_g.exam_start_minutes); - if (preexam_time > 600000) + if (preexam_time > 2 * ONE_HOUR_MS) + return ; + if (preexam_time > 10 * ONE_MINUTE_MS) preexam_warning(&preexam_time); - if (preexam_time <= 600000 && preexam_time >= 25000) - ft_delay(preexam_time - 25000); + if (preexam_time <= 10 * ONE_MINUTE_MS && preexam_time >= 25 * ONE_SECOND_MS) + ft_delay(preexam_time - 25 * ONE_SECOND_MS); fetch_exams(); if (!rtc_g.exam_status) return ; diff --git a/src/time_utilities.cpp b/src/time_utilities.cpp index bec9dbc..282cd1f 100644 --- a/src/time_utilities.cpp +++ b/src/time_utilities.cpp @@ -273,11 +273,11 @@ unsigned int time_till_wakeup(void) watchdog_reset(); i = sizeof(wakeup_hour) / sizeof(wakeup_hour[0]) - 1; if (com_g.hour >= wakeup_hour[i]) - return ((wakeup_hour[0] + 24 - com_g.hour) * HOUR_MS - (com_g.minute * MINUTE_MS) - millis()); + return ((wakeup_hour[0] + 24 - com_g.hour) * ONE_HOUR_MS - (com_g.minute * ONE_MINUTE_MS) - millis()); i = 0; while ((wakeup_hour[i] - com_g.hour) <= 0) i++; - return ((wakeup_hour[i] - com_g.hour) * HOUR_MS - (com_g.minute * MINUTE_MS) - millis()); + return ((wakeup_hour[i] - com_g.hour) * ONE_HOUR_MS - (com_g.minute * ONE_MINUTE_MS) - millis()); } @@ -291,8 +291,8 @@ unsigned int time_till_event(int8_t hours, uint8_t minutes) long time_left_ms; watchdog_reset(); - time_left_ms = (hours - com_g.hour) * HOUR_MS; - time_left_ms += (minutes * MINUTE_MS) - (com_g.minute * MINUTE_MS); + time_left_ms = (hours - com_g.hour) * ONE_HOUR_MS; + time_left_ms += (minutes * ONE_MINUTE_MS) - (com_g.minute * ONE_MINUTE_MS); if (time_left_ms < 0) time_left_ms = 0; return ((unsigned int)time_left_ms); @@ -311,7 +311,7 @@ int time_sync(unsigned int preexam_time) minutes = ceil(preexam_time / 1000); ft_delay(1000); } - minutes = ceil(preexam_time / MINUTE_MS); + minutes = ceil(preexam_time / ONE_MINUTE_MS); while (minutes % 10 != 0 || minutes > 60) { ft_delay(59990); diff --git a/src/utils.cpp b/src/utils.cpp index a03efca..dd41bd6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -189,9 +189,9 @@ void bluetooth_deinit(void) else day = String(com_g.day); virtual_exam = "[{\"begin_at\":\""; - virtual_exam += String(com_g.year) + "-" + month + "-" + day + "T20:00:00.000Z\","; // Change begin time here. Mind the TIME_ZONE correction + virtual_exam += String(com_g.year) + "-" + month + "-" + day + "T17:00:00.000Z\","; // Change begin time here. Mind the TIME_ZONE correction virtual_exam += "\"end_at\":\""; - virtual_exam += String(com_g.year) + "-" + month + "-" + day + "T22:00:00.000Z\","; // Change end time here. Mind the TIME_ZONE correction + virtual_exam += String(com_g.year) + "-" + month + "-" + day + "T20:00:00.000Z\","; // Change end time here. Mind the TIME_ZONE correction virtual_exam += "\"nbr_subscribers\":4,}]"; DEBUG_PRINTF("\n\n[EXAM SIMULATION] ATTENTION! EXAM SIMULATION IS ACTIVE!\n"); DEBUG_PRINTF("[EXAM SIMULATION] The following exam is just a simulation!\n");