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/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 3677f77..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 @@ -55,8 +56,7 @@ /* Images constants */ typedef enum { - CLUSTER = 1000, - DEFAULT_IMG, + CLUSTER_DEFAULT = 100, INTRA_ERROR, SECRET_EXPIRED, EXAM_DAY, @@ -67,12 +67,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..9283d54 100644 --- a/src/display_handling.cpp +++ b/src/display_handling.cpp @@ -6,13 +6,13 @@ /* 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 */ /* */ /* */ /* ************************************************************************** */ #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,237 @@ 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; - - watchdog_reset(); - /* DECIDE WHETHER TO DRAW ANYTHING AT ALL */ - if (display_cluster && mode == displaying_now) + if (screen == EXAM_SCREEN_PRE_50) { - DEBUG_PRINTF("\n[THE DISPLAY] Nothing new to draw. Drawing aborted\n\n"); - return; + 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); } - /* DECIDE WHETHER TO DRAW THE CLUSTER NUMBER PART OR NOT */ - if (!display_cluster) + else if (screen == EXAM_SCREEN_PRE_5) { - 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; + 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); } - /* DECIDE WHAT TO DRAW ON THE SIDE NOTE PART */ - if (mode == DEFAULT_IMG && (displaying_now != DEFAULT_IMG && displaying_now != LOW_BATTERY)) + 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"); +} + + +/* +* 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) { DEBUG_PRINTF("[THE DISPLAY] ...the default cluster icons\n"); draw_bitmap_partial_update(default_cluster_icons, 170, 480); - displaying_now = DEFAULT_IMG; } - else if (mode == INTRA_ERROR && displaying_now != INTRA_ERROR) + 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); - displaying_now = INTRA_ERROR; } - else if (mode == SECRET_EXPIRED && displaying_now != SECRET_EXPIRED) + 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); - 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) + 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); - displaying_now = LOW_BATTERY; } - else if (mode == OTA_WAITING && displaying_now != OTA_WAITING) + else if (state.cluster_side == CLUSTER_SIDE_OTA_WAITING) { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); + DEBUG_PRINTF("[THE DISPLAY] ...the OTA waiting notification\n"); draw_text(" WAITING FOR\n OTA UPDATE", 0, 710); - displaying_now = OTA_WAITING; } - else if (mode == OTA_SUCCESS && displaying_now != OTA_SUCCESS) + else if (state.cluster_side == CLUSTER_SIDE_OTA_SUCCESS) { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); + DEBUG_PRINTF("[THE DISPLAY] ...the OTA success notification\n"); draw_text(" OTA UPDATE\n SUCCESS", 0, 710); - displaying_now = OTA_SUCCESS; } - else if (mode == OTA_FAIL && displaying_now != OTA_FAIL) + else if (state.cluster_side == CLUSTER_SIDE_OTA_FAIL) { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); + DEBUG_PRINTF("[THE DISPLAY] ...the OTA fail notification\n"); draw_text(" OTA UPDATE\n FAIL", 0, 710); - displaying_now = OTA_FAIL; } - else if (mode == OTA_CANCELED && displaying_now != OTA_CANCELED) + else if (state.cluster_side == CLUSTER_SIDE_OTA_CANCELED) { - DEBUG_PRINTF("[THE DISPLAY] ...the OTA notification\n"); + DEBUG_PRINTF("[THE DISPLAY] ...the OTA canceled notification\n"); draw_text(" OTA UPDATE\n WAS CANCELED", 0, 710); - displaying_now = OTA_CANCELED; } - else if (mode == TELEGRAM_ERROR && displaying_now != TELEGRAM_ERROR) + 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); - displaying_now = TELEGRAM_ERROR; - } - DEBUG_PRINTF("[THE DISPLAY] The drawing process is complete\n"); + } + else + DEBUG_PRINTF("[THE DISPLAY] ...unknown CLUSTER_SIDE signature! Error!\n"); +} + + +/* +* 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 + ); } -void clear_display(void) + +/* +* 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(); - display.clearScreen(); - display.writeScreenBuffer(); + if (display_cache_valid && same_display_state(display_cache, requested)) + { + DEBUG_PRINTF("\n[THE DISPLAY] Nothing new to draw. Drawing aborted\n\n"); + 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 ; + } + if (requested.view == DISPLAY_VIEW_EXAM) + { + draw_exam_screen(requested.exam_screen); + display_cache = requested; + display_cache_valid = true; + 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 || + display_cache.exam_minutes != requested.exam_minutes) + { + draw_cluster_side(requested); + } + display_cache = requested; + display_cache_valid = true; + } } + +/* +* 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. +*/ +static bool display_state_init(IMAGE_t image, DISPLAY_STATE_t* state) +{ + 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) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_INTRA_ERROR, EXAM_SCREEN_NONE, 0, 0}; + else if (image == SECRET_EXPIRED) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_SECRET_EXPIRED, EXAM_SCREEN_NONE, 0, 0}; + else if (image == EXAM_DAY) + *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) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_LOW_BATTERY, EXAM_SCREEN_NONE, 0, 0}; + else if (image == OTA_WAITING) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_WAITING, EXAM_SCREEN_NONE, 0, 0}; + else if (image == OTA_SUCCESS) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_SUCCESS, EXAM_SCREEN_NONE, 0, 0}; + else if (image == OTA_FAIL) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_FAIL, EXAM_SCREEN_NONE, 0, 0}; + else if (image == OTA_CANCELED) + *state = {DISPLAY_VIEW_CLUSTER, CLUSTER_SIDE_OTA_CANCELED, EXAM_SCREEN_NONE, 0, 0}; + else if (image == 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) + *state = {DISPLAY_VIEW_BLANK, CLUSTER_SIDE_NONE, EXAM_SCREEN_NONE, 0, 0}; + else + { + DEBUG_PRINTF("[THE DISPLAY] Unsupported image requested: %d\n", image); + return (false); + } + 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"); +} + + void display_init(void) { watchdog_reset(); @@ -254,4 +384,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..e89136a 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; @@ -77,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/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(); 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");