Skip to content

Commit 3586ddf

Browse files
committed
changed abbreviation and red border wall
1 parent 921f9d8 commit 3586ddf

File tree

7 files changed

+260
-38
lines changed

7 files changed

+260
-38
lines changed

inc/sp140/alert_display.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern QueueHandle_t alertCarouselQueue; // depth 1, overwrite
3131
// Message for UI to show a single alert text (or hide)
3232
struct AlertDisplayMsg {
3333
SensorID id; // Valid sensor when show == true
34+
AlertLevel level; // Alert level for dynamic abbreviations
3435
bool critical; // true = critical colouring
3536
bool show; // false = hide label
3637
};

inc/sp140/lvgl/lvgl_display.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,10 @@ extern int8_t displayCS;
8282
void updateAlertCounterDisplay(const AlertCounts& counts);
8383
void loadAlertSnapshot(const AlertSnapshot& snap);
8484
void lv_showAlertText(SensorID id, bool critical);
85+
void lv_showAlertTextWithLevel(SensorID id, AlertLevel level, bool critical);
8586
void lv_hideAlertText();
87+
88+
// Critical border flashing functions
89+
void startCriticalBorderFlash();
90+
void stopCriticalBorderFlash();
91+
bool isCriticalBorderFlashing();

inc/sp140/simple_monitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ extern bool monitoringEnabled; // Flag to control monitoring state
171171
// Functions
172172
const char* sensorIDToString(SensorID id);
173173
const char* sensorIDToAbbreviation(SensorID id);
174+
const char* sensorIDToAbbreviationWithLevel(SensorID id, AlertLevel level);
174175
void initSimpleMonitor();
175176
void checkAllSensors();
176177
void checkAllSensorsWithData(const STR_ESC_TELEMETRY_140& escData, const STR_BMS_TELEMETRY_140& bmsData);

src/sp140/alert_display.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static void alertAggregationTask(void* parameter) {
8080
AlertDisplayMsg msg;
8181
msg.show = true;
8282
msg.id = g_activeList[g_rotateIdx];
83+
msg.level = g_currentLevels[g_activeList[g_rotateIdx]]; // Get the alert level for this sensor
8384
msg.critical = g_showingCrit;
8485
if (alertDisplayQueue) {
8586
xQueueOverwrite(alertDisplayQueue, &msg);
@@ -150,6 +151,7 @@ static void recalcCountsAndPublish() {
150151
} else {
151152
msg.show = true;
152153
msg.id = g_activeList[g_rotateIdx];
154+
msg.level = g_currentLevels[g_activeList[g_rotateIdx]]; // Get the alert level for this sensor
153155
msg.critical = g_showingCrit;
154156
}
155157
if (alertDisplayQueue) {
@@ -195,11 +197,21 @@ static void handleAlertVibration(const AlertCounts& newCounts, const AlertCounts
195197
if (!isCriticalVibrationActive()) {
196198
startCriticalVibration();
197199
}
200+
201+
// Start critical border flashing (if not already active)
202+
if (!isCriticalBorderFlashing()) {
203+
startCriticalBorderFlash();
204+
}
198205
} else {
199206
// Stop critical vibration if no critical alerts remain
200207
if (isCriticalVibrationActive()) {
201208
stopCriticalVibration();
202209
}
210+
211+
// Stop critical border flashing if no critical alerts remain
212+
if (isCriticalBorderFlashing()) {
213+
stopCriticalBorderFlash();
214+
}
203215

204216
// Handle warning transitions (only when no critical alerts)
205217
if (previousCounts.warningCount == 0 && newCounts.warningCount > 0) {

src/sp140/lvgl/lvgl_display.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ static void arm_fail_flash_timer_cb(lv_timer_t* timer); // Forward declaration
165165
static lv_color_t original_arm_fail_icon_color; // To restore color after flashing
166166
// --- End Arm Fail Icon Flashing ---
167167

168+
// --- Critical Alert Border Flashing ---
169+
static lv_obj_t* critical_border = NULL;
170+
static lv_timer_t* critical_border_flash_timer = NULL;
171+
static bool isFlashingCriticalBorder = false;
172+
static void critical_border_flash_timer_cb(lv_timer_t* timer); // Forward declaration
173+
// --- End Critical Alert Border Flashing ---
174+
168175
void setupLvglBuffer() {
169176
// Initialize LVGL library
170177
USBSerial.println("Initializing LVGL");
@@ -572,6 +579,20 @@ void setupMainScreen(bool darkMode) {
572579
}
573580
*/
574581

582+
// Create critical alert border (initially hidden)
583+
if (critical_border == NULL) {
584+
critical_border = lv_obj_create(main_screen);
585+
lv_obj_set_size(critical_border, SCREEN_WIDTH, SCREEN_HEIGHT);
586+
lv_obj_set_pos(critical_border, 0, 0);
587+
lv_obj_set_style_border_width(critical_border, 4, LV_PART_MAIN);
588+
lv_obj_set_style_border_color(critical_border, LVGL_RED, LV_PART_MAIN);
589+
lv_obj_set_style_bg_opa(critical_border, LV_OPA_0, LV_PART_MAIN); // Transparent background
590+
lv_obj_set_style_radius(critical_border, 0, LV_PART_MAIN); // Sharp corners
591+
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Initially hidden
592+
// Move border to front so it's visible over all other elements
593+
lv_obj_move_foreground(critical_border);
594+
}
595+
575596
// Create arm indicator (initially hidden)
576597
arm_indicator = lv_obj_create(main_screen);
577598
lv_obj_set_size(arm_indicator, 52, 33);
@@ -939,11 +960,101 @@ void startArmFailIconFlash() {
939960
}
940961
// --- End Arm Fail Icon Flashing Implementation ---
941962

963+
// --- Critical Alert Border Flashing Implementation ---
964+
static void critical_border_flash_timer_cb(lv_timer_t* timer) {
965+
// This callback runs within the LVGL task handler, which is already protected by lvglMutex
966+
967+
if (critical_border == NULL) {
968+
// Safety check
969+
if (critical_border_flash_timer != NULL) {
970+
lv_timer_del(critical_border_flash_timer);
971+
critical_border_flash_timer = NULL;
972+
}
973+
isFlashingCriticalBorder = false;
974+
return;
975+
}
976+
977+
// Toggle visibility
978+
if (lv_obj_has_flag(critical_border, LV_OBJ_FLAG_HIDDEN)) {
979+
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
980+
} else {
981+
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
982+
}
983+
}
984+
985+
void startCriticalBorderFlash() {
986+
// This function can be called from other tasks, so protect with mutex
987+
if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { // Use a timeout
988+
if (critical_border == NULL) {
989+
xSemaphoreGive(lvglMutex);
990+
return; // Can't flash if border doesn't exist
991+
}
992+
993+
// If a flash timer is already running, delete it first
994+
if (critical_border_flash_timer != NULL) {
995+
lv_timer_del(critical_border_flash_timer);
996+
critical_border_flash_timer = NULL;
997+
}
998+
999+
// Reset state and start flashing
1000+
isFlashingCriticalBorder = true;
1001+
1002+
// Start with the border visible
1003+
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
1004+
1005+
// Create the timer (500ms interval for on/off cycle - matches vibration rate)
1006+
critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 500, NULL);
1007+
if (critical_border_flash_timer == NULL) {
1008+
// Failed to create timer, reset state
1009+
isFlashingCriticalBorder = false;
1010+
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Hide it again
1011+
USBSerial.println("Error: Failed to create critical border flash timer!");
1012+
}
1013+
1014+
xSemaphoreGive(lvglMutex);
1015+
} else {
1016+
USBSerial.println("Warning: Failed to acquire LVGL mutex for startCriticalBorderFlash");
1017+
}
1018+
}
1019+
1020+
void stopCriticalBorderFlash() {
1021+
// This function can be called from other tasks, so protect with mutex
1022+
if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { // Use a timeout
1023+
if (critical_border_flash_timer != NULL) {
1024+
lv_timer_del(critical_border_flash_timer);
1025+
critical_border_flash_timer = NULL;
1026+
}
1027+
1028+
isFlashingCriticalBorder = false;
1029+
1030+
// Hide the border
1031+
if (critical_border != NULL) {
1032+
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
1033+
}
1034+
1035+
xSemaphoreGive(lvglMutex);
1036+
} else {
1037+
USBSerial.println("Warning: Failed to acquire LVGL mutex for stopCriticalBorderFlash");
1038+
}
1039+
}
1040+
1041+
bool isCriticalBorderFlashing() {
1042+
return isFlashingCriticalBorder;
1043+
}
1044+
// --- End Critical Alert Border Flashing Implementation ---
1045+
9421046
// Public helpers to control alert text externally
9431047
void lv_showAlertText(SensorID id, bool critical) {
9441048
if (alert_text_label == NULL) return;
9451049
const char* txt = sensorIDToAbbreviation(id);
9461050
lv_label_set_text(alert_text_label, txt);
1051+
}
1052+
1053+
// New function that accepts alert level for dynamic abbreviations
1054+
void lv_showAlertTextWithLevel(SensorID id, AlertLevel level, bool critical) {
1055+
if (alert_text_label == NULL) return;
1056+
const char* txt = sensorIDToAbbreviationWithLevel(id, level);
1057+
lv_label_set_text(alert_text_label, txt);
9471058
// Use larger font for critical alerts, smaller for warnings
9481059
if (critical) {
9491060
lv_obj_set_style_text_font(alert_text_label, &lv_font_montserrat_18, 0);

src/sp140/simple_monitor.cpp

Lines changed: 128 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -137,48 +137,48 @@ const char* sensorIDToString(SensorID id) {
137137
const char* sensorIDToAbbreviation(SensorID id) {
138138
switch (id) {
139139
// ESC
140-
case SensorID::ESC_MOS_Temp: return "ESC-M"; // MOSFET temp
141-
case SensorID::ESC_MCU_Temp: return "ESC-C"; // Controller temp
142-
case SensorID::ESC_CAP_Temp: return "ESC-P"; // Capacitor temp
143-
case SensorID::Motor_Temp: return "MTR-T"; // Motor temp
140+
case SensorID::ESC_MOS_Temp: return "MC-F"; // MOSFET temp
141+
case SensorID::ESC_MCU_Temp: return "MC-C"; // Controller temp
142+
case SensorID::ESC_CAP_Temp: return "MC-P"; // Capacitor temp
143+
case SensorID::Motor_Temp: return "MC-M"; // Motor temp
144144
// ESC Running Errors (Critical) - with bit numbers
145-
case SensorID::ESC_OverCurrent_Error: return "ESC-RE-0"; // Bit 0
146-
case SensorID::ESC_LockedRotor_Error: return "ESC-RE-1"; // Bit 1
147-
case SensorID::ESC_OverTemp_Error: return "ESC-RE-2"; // Bit 2
148-
case SensorID::ESC_OverVolt_Error: return "ESC-RE-6"; // Bit 6
149-
case SensorID::ESC_VoltageDrop_Error: return "ESC-RE-7"; // Bit 7
145+
case SensorID::ESC_OverCurrent_Error: return "MC-RE-0"; // Bit 0
146+
case SensorID::ESC_LockedRotor_Error: return "MC-RE-1"; // Bit 1
147+
case SensorID::ESC_OverTemp_Error: return "MC-RE-2"; // Bit 2
148+
case SensorID::ESC_OverVolt_Error: return "MC-RE-6"; // Bit 6
149+
case SensorID::ESC_VoltageDrop_Error: return "MC-RE-7"; // Bit 7
150150
// ESC Running Warnings - with bit numbers
151-
case SensorID::ESC_ThrottleSat_Warning: return "ESC-RW-5"; // Bit 5
151+
case SensorID::ESC_ThrottleSat_Warning: return "MC-RW-5"; // Bit 5
152152
// ESC Self-Check Errors - with bit numbers
153-
case SensorID::ESC_MotorCurrentOut_Error: return "ESC-SE-0"; // Bit 0
154-
case SensorID::ESC_TotalCurrentOut_Error: return "ESC-SE-1"; // Bit 1
155-
case SensorID::ESC_MotorVoltageOut_Error: return "ESC-SE-2"; // Bit 2
156-
case SensorID::ESC_CapNTC_Error: return "ESC-SE-3"; // Bit 3
157-
case SensorID::ESC_MosNTC_Error: return "ESC-SE-4"; // Bit 4
158-
case SensorID::ESC_BusVoltRange_Error: return "ESC-SE-5"; // Bit 5
159-
case SensorID::ESC_BusVoltSample_Error: return "ESC-SE-6"; // Bit 6
160-
case SensorID::ESC_MotorZLow_Error: return "ESC-SE-7"; // Bit 7
161-
case SensorID::ESC_MotorZHigh_Error: return "ESC-SE-8"; // Bit 8
162-
case SensorID::ESC_MotorVDet1_Error: return "ESC-SE-9"; // Bit 9
163-
case SensorID::ESC_MotorVDet2_Error: return "ESC-SE-10"; // Bit 10
164-
case SensorID::ESC_MotorIDet2_Error: return "ESC-SE-11"; // Bit 11
165-
case SensorID::ESC_SwHwIncompat_Error: return "ESC-SE-13"; // Bit 13
166-
case SensorID::ESC_BootloaderBad_Error: return "ESC-SE-14"; // Bit 14
153+
case SensorID::ESC_MotorCurrentOut_Error: return "MC-SE-0"; // Bit 0
154+
case SensorID::ESC_TotalCurrentOut_Error: return "MC-SE-1"; // Bit 1
155+
case SensorID::ESC_MotorVoltageOut_Error: return "MC-SE-2"; // Bit 2
156+
case SensorID::ESC_CapNTC_Error: return "MC-SE-3"; // Bit 3
157+
case SensorID::ESC_MosNTC_Error: return "MC-SE-4"; // Bit 4
158+
case SensorID::ESC_BusVoltRange_Error: return "MC-SE-5"; // Bit 5
159+
case SensorID::ESC_BusVoltSample_Error: return "MC-SE-6"; // Bit 6
160+
case SensorID::ESC_MotorZLow_Error: return "MC-SE-7"; // Bit 7
161+
case SensorID::ESC_MotorZHigh_Error: return "MC-SE-8"; // Bit 8
162+
case SensorID::ESC_MotorVDet1_Error: return "MC-SE-9"; // Bit 9
163+
case SensorID::ESC_MotorVDet2_Error: return "MC-SE-10"; // Bit 10
164+
case SensorID::ESC_MotorIDet2_Error: return "MC-SE-11"; // Bit 11
165+
case SensorID::ESC_SwHwIncompat_Error: return "MC-SE-13"; // Bit 13
166+
case SensorID::ESC_BootloaderBad_Error: return "MC-SE-14"; // Bit 14
167167

168168
// BMS (Battery Management System)
169-
case SensorID::BMS_MOS_Temp: return "BMS-M";
170-
case SensorID::BMS_Balance_Temp: return "BMS-B";
171-
case SensorID::BMS_T1_Temp: return "BMS-T1";
172-
case SensorID::BMS_T2_Temp: return "BMS-T2";
173-
case SensorID::BMS_T3_Temp: return "BMS-T3";
174-
case SensorID::BMS_T4_Temp: return "BMS-T4";
175-
case SensorID::BMS_High_Cell_Voltage: return "BMS-CV-H";
176-
case SensorID::BMS_Low_Cell_Voltage: return "BMS-CV-L";
177-
case SensorID::BMS_SOC: return "BMS-SOC";
178-
case SensorID::BMS_Total_Voltage: return "BMS-Vtot";
179-
case SensorID::BMS_Voltage_Differential:return "BMS-dV";
180-
case SensorID::BMS_Charge_MOS: return "BMS-CHG";
181-
case SensorID::BMS_Discharge_MOS: return "BMS-DSG";
169+
case SensorID::BMS_MOS_Temp: return "BC-F";
170+
case SensorID::BMS_Balance_Temp: return "BC-B";
171+
case SensorID::BMS_T1_Temp: return "BC-T1";
172+
case SensorID::BMS_T2_Temp: return "BC-T2";
173+
case SensorID::BMS_T3_Temp: return "BC-T3";
174+
case SensorID::BMS_T4_Temp: return "BC-T4";
175+
case SensorID::BMS_High_Cell_Voltage: return "BC-CV-H";
176+
case SensorID::BMS_Low_Cell_Voltage: return "BC-CV-L";
177+
case SensorID::BMS_SOC: return "BC-SOC";
178+
case SensorID::BMS_Total_Voltage: return "BC-Vtot";
179+
case SensorID::BMS_Voltage_Differential:return "BC-dV";
180+
case SensorID::BMS_Charge_MOS: return "BC-CHG";
181+
case SensorID::BMS_Discharge_MOS: return "BC-DSG";
182182

183183
// Altimeter
184184
case SensorID::Baro_Temp: return "BARO-T";
@@ -190,6 +190,97 @@ const char* sensorIDToAbbreviation(SensorID id) {
190190
}
191191
}
192192

193+
// Dynamic abbreviations for temperature sensors based on alert level
194+
const char* sensorIDToAbbreviationWithLevel(SensorID id, AlertLevel level) {
195+
switch (id) {
196+
// ESC Temperature sensors with dynamic suffixes
197+
case SensorID::ESC_MOS_Temp:
198+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
199+
return "MC-FT-H"; // MOSFET temp high
200+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
201+
return "MC-FT-L"; // MOSFET temp low
202+
}
203+
return "MC-F"; // Default
204+
205+
case SensorID::ESC_MCU_Temp:
206+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
207+
return "MC-CT-H"; // Controller temp high
208+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
209+
return "MC-CT-L"; // Controller temp low
210+
}
211+
return "MC-C"; // Default
212+
213+
case SensorID::ESC_CAP_Temp:
214+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
215+
return "MC-PT-H"; // Capacitor temp high
216+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
217+
return "MC-PT-L"; // Capacitor temp low
218+
}
219+
return "MC-P"; // Default
220+
221+
case SensorID::Motor_Temp:
222+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
223+
return "MC-MT-H"; // Motor temp high
224+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
225+
return "MC-MT-L"; // Motor temp low
226+
}
227+
return "MC-M"; // Default
228+
229+
// BMS Temperature sensors with dynamic suffixes
230+
case SensorID::BMS_MOS_Temp:
231+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
232+
return "BC-F-H"; // MOS temp high
233+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
234+
return "BC-F-L"; // MOS temp low
235+
}
236+
return "BC-F"; // Default
237+
238+
case SensorID::BMS_Balance_Temp:
239+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
240+
return "BC-B-H"; // Balance temp high
241+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
242+
return "BC-B-L"; // Balance temp low
243+
}
244+
return "BC-B"; // Default
245+
246+
case SensorID::BMS_T1_Temp:
247+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
248+
return "BC-T1-H"; // Cell 1 temp high
249+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
250+
return "BC-T1-L"; // Cell 1 temp low
251+
}
252+
return "BC-T1"; // Default
253+
254+
case SensorID::BMS_T2_Temp:
255+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
256+
return "BC-T2-H"; // Cell 2 temp high
257+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
258+
return "BC-T2-L"; // Cell 2 temp low
259+
}
260+
return "BC-T2"; // Default
261+
262+
case SensorID::BMS_T3_Temp:
263+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
264+
return "BC-T3-H"; // Cell 3 temp high
265+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
266+
return "BC-T3-L"; // Cell 3 temp low
267+
}
268+
return "BC-T3"; // Default
269+
270+
case SensorID::BMS_T4_Temp:
271+
if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) {
272+
return "BC-T4-H"; // Cell 4 temp high
273+
} else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) {
274+
return "BC-T4-L"; // Cell 4 temp low
275+
}
276+
return "BC-T4"; // Default
277+
278+
// For all other sensors, use the standard abbreviation
279+
default:
280+
return sensorIDToAbbreviation(id);
281+
}
282+
}
283+
193284
void initSimpleMonitor() {
194285
USBSerial.println("Initializing Simple Monitor System");
195286
setupLoggerSinks();

src/sp140/sp140.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ void refreshDisplay() {
369369
AlertDisplayMsg dmsg;
370370
if (xQueueReceive(alertDisplayQueue, &dmsg, 0) == pdTRUE) {
371371
if (dmsg.show) {
372-
lv_showAlertText(dmsg.id, dmsg.critical);
372+
lv_showAlertTextWithLevel(dmsg.id, dmsg.level, dmsg.critical);
373373
} else {
374374
lv_hideAlertText();
375375
}

0 commit comments

Comments
 (0)