# HG changeset patch # User Ideenmodellierer # Date 1725118552 -7200 # Node ID 608d3e918146271a926a047f61706f43c41c9ff1 # Parent 5b675077ccfb5abf24398c717aafaed9899d1631 Added slow exit timer function: At the end of the dive the final ascent to surface should be done slowly. The new function provides a comparison of the current divers depth compared to a linear ascent simulated by the OSTC. The visualization is shown instead of the ascent speed with a little different appearance. The linear ascent is starting from the last stop depth and the time for the ascent may be configurated in the deco settings. The simulated and real peth is compared and the depth color changes based on the difference of the values. In case the diver is much below the timer depth then the timer will stop and wait for the diver to follow. diff -r 5b675077ccfb -r 608d3e918146 Common/Inc/settings.h --- a/Common/Inc/settings.h Sat Aug 31 17:28:37 2024 +0200 +++ b/Common/Inc/settings.h Sat Aug 31 17:35:52 2024 +0200 @@ -313,6 +313,7 @@ uint8_t scrubTimerMode; uint8_t ext_sensor_map[8]; /* redefined in 0xFFFF0027 */ uint8_t cvAutofocus; + uint8_t slowExitTime; } SSettings; typedef struct diff -r 5b675077ccfb -r 608d3e918146 Discovery/Inc/tStructure.h --- a/Discovery/Inc/tStructure.h Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Inc/tStructure.h Sat Aug 31 17:35:52 2024 +0200 @@ -245,8 +245,9 @@ #define StMDECO3_PPO2Max _MB(2,5,2,1,0) #define StMDECO4_SafetyStop _MB(2,5,3,1,0) -#define StMDECO5_FUTURE _MB(2,5,4,1,0) -#define StMDECO6_SALINITY _MB(2,5,5,1,0) +#define StMDECO_SlowExit _MB(2,5,4,1,0) +#define StMDECO5_FUTURE _MB(2,5,5,1,0) +#define StMDECO6_SALINITY _MB(2,5,6,1,0) /* PAGE 6 */ #define StMDECOP _MB(2,6,0,0,0) diff -r 5b675077ccfb -r 608d3e918146 Discovery/Inc/text_multilanguage.h --- a/Discovery/Inc/text_multilanguage.h Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Inc/text_multilanguage.h Sat Aug 31 17:35:52 2024 +0200 @@ -346,6 +346,7 @@ TXT2BYTE_Navigation, TXT2BYTE_DepthData, TXT2BYTE_DecoTTS, + TXT2BYTE_SlowExit, TXT2BYTE_Minimum, TXT2BYTE_Normal, diff -r 5b675077ccfb -r 608d3e918146 Discovery/Src/settings.c --- a/Discovery/Src/settings.c Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Src/settings.c Sat Aug 31 17:35:52 2024 +0200 @@ -89,7 +89,7 @@ * There might even be entries with fixed values that have no range */ const SSettings SettingsStandard = { - .header = 0xFFFF002A, + .header = 0xFFFF002B, .warning_blink_dsec = 8 * 2, .lastDiveLogId = 0, .logFlashNextSampleStartAddress = SAMPLESTART, @@ -340,6 +340,7 @@ .delaySetpointLow = false, .timerDurationS = 180, .cvAutofocus = 0, + .slowExitTime = 0 }; /* Private function prototypes -----------------------------------------------*/ @@ -599,6 +600,9 @@ case 0xFFFF0029: Settings.cvAutofocus = 0; // no break; + case 0xFFFF002A: + Settings.slowExitTime = 0; + // no break; default: pSettings->header = pStandard->header; break; // no break before!! @@ -1300,6 +1304,13 @@ setFirstCorrection(parameterId); } parameterId++; + if(Settings.slowExitTime > 9) + { + Settings.divetimeToCreateLogbook = 0; + corrections++; + setFirstCorrection(parameterId); + } + parameterId++; /* uint8_t serialHigh; */ diff -r 5b675077ccfb -r 608d3e918146 Discovery/Src/t7.c --- a/Discovery/Src/t7.c Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Src/t7.c Sat Aug 31 17:35:52 2024 +0200 @@ -79,6 +79,9 @@ uint8_t t7_customtextPrepare(char * text); +static void t7_drawAcentGraph(uint8_t color); +static uint8_t t7_drawSlowExitGraph(void); + /* Imported function prototypes ---------------------------------------------*/ extern uint8_t write_gas(char *text, uint8_t oxygen, uint8_t helium); @@ -121,6 +124,13 @@ /* Private types -------------------------------------------------------------*/ +typedef enum +{ + SE_INIT = 0, + SE_ACTIVE, + SE_END +} SSlowExitState; + const uint8_t customviewsSurfaceStandard[] = { // CVIEW_CompassDebug, @@ -2733,8 +2743,8 @@ SafetyStopTime.Minutes = SafetyStopTime.Total / 60; SafetyStopTime.Seconds = SafetyStopTime.Total - (SafetyStopTime.Minutes * 60); - TimeoutTime.Total = settingsGetPointer()->timeoutDiveReachedZeroDepth - stateUsed->lifeData.counterSecondsShallowDepth; - if(TimeoutTime.Total > settingsGetPointer()->timeoutDiveReachedZeroDepth) + TimeoutTime.Total = pSettings->timeoutDiveReachedZeroDepth - stateUsed->lifeData.counterSecondsShallowDepth; + if(TimeoutTime.Total > pSettings->timeoutDiveReachedZeroDepth) { TimeoutTime.Total = 0; } @@ -2752,6 +2762,32 @@ nextstopLengthSeconds = 0; } + + /* max depth */ + snprintf(TextL2,TEXTSIZE,"\032\f%c",TXT_MaxDepth); + GFX_write_string(&FontT42,&t7l2,TextL2,0); + + if(unit_depth_float(stateUsed->lifeData.max_depth_meter) < 100) + snprintf(TextL2,TEXTSIZE,"\020%01.1f",unit_depth_float(stateUsed->lifeData.max_depth_meter)); + else + snprintf(TextL2,TEXTSIZE,"\020%01.0f",unit_depth_float(stateUsed->lifeData.max_depth_meter)); + + Gfx_colorsscheme_mod(TextL2, 0); + GFX_write_string(&FontT105,&t7l2,TextL2,1); + +/* ascent rate graph */ + + if((pSettings->slowExitTime != 0) && (stateUsed->lifeData.depth_meter < pSettings->last_stop_depth_meter)) + { + color = t7_drawSlowExitGraph(); + } + else if(stateUsed->lifeData.ascent_rate_meter_per_min > 1) /* a value < 1 would cause a bar in negative direction brush rectangle of 12 and step width of 6 */ + { + color = drawingColor_from_ascentspeed(stateUsed->lifeData.ascent_rate_meter_per_min); + t7_drawAcentGraph(color); + } + + /* depth */ float depth = unit_depth_float(stateUsed->lifeData.depth_meter); @@ -2763,9 +2799,6 @@ else snprintf(TextL1,TEXTSIZE,"\032\f%c",TXT_Depth); - color = drawingColor_from_ascentspeed(stateUsed->lifeData.ascent_rate_meter_per_min); - - GFX_write_string(&FontT24,&t7l1,TextL1,0); if((stateUsed->lifeData.ascent_rate_meter_per_min > 8) || (stateUsed->lifeData.ascent_rate_meter_per_min < -10)) @@ -2785,71 +2818,11 @@ Gfx_colorsscheme_mod(TextL1, color); - - GFX_write_string(&FontT144,&t7l1,TextL1,0); - /* max depth */ - snprintf(TextL2,TEXTSIZE,"\032\f%c",TXT_MaxDepth); - GFX_write_string(&FontT42,&t7l2,TextL2,0); - - if(unit_depth_float(stateUsed->lifeData.max_depth_meter) < 100) - snprintf(TextL2,TEXTSIZE,"\020%01.1f",unit_depth_float(stateUsed->lifeData.max_depth_meter)); - else - snprintf(TextL2,TEXTSIZE,"\020%01.0f",unit_depth_float(stateUsed->lifeData.max_depth_meter)); - - Gfx_colorsscheme_mod(TextL2, 0); - GFX_write_string(&FontT105,&t7l2,TextL2,1); - - /* ascent rate graph */ - if(stateUsed->lifeData.ascent_rate_meter_per_min > 1) /* a value < 1 would cause a bar in negative direction brush rectangle of 12 and step width of 6 */ - { - if(!pSettings->FlipDisplay) - { - start.y = t7l1.WindowY0 - 1; - } - else - { - start.y = t7l3.WindowY0 - 25; - } - - for(int i = 0; i<4;i++) - { - start.y += 5*6; - stop.y = start.y; - start.x = CUSTOMBOX_LINE_LEFT - 1; - stop.x = start.x - 17; - GFX_draw_line(&t7screen, start, stop, 0); -// start.x = CUSTOMBOX_LINE_RIGHT + 2; old right too -// stop.x = start.x + 17; -// GFX_draw_line(&t7screen, start, stop, 0); - } - // new thick bar design Sept. 2015 - start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 3 - 5; - stop.x = start.x; - if(!pSettings->FlipDisplay) - { - start.y = t7l1.WindowY0 - 1; - } - else - { - start.y = t7l3.WindowY0 - 25; - } - stop.y = start.y + (uint16_t)(stateUsed->lifeData.ascent_rate_meter_per_min * 6); - stop.y -= 3; // wegen der Liniendicke von 12 anstelle von 9 - if(stop.y >= 470) - stop.y = 470; - start.y += 7; // starte etwas weiter oben - if(color == 0) - { - color = CLUT_EverythingOkayGreen; /* do not use white color for drawing graph */ - } - - GFX_draw_thick_line(12,&t7screen, start, stop, color); - } - //snprintf(TextL2,TEXTSIZE,"\f%.1f m/min",stateUsed->lifeData.ascent_rate_meter_per_min); - - /* divetime */ + + +/* divetime */ if(stateUsed->lifeData.counterSecondsShallowDepth) { snprintf(TextR1,TEXTSIZE,"\f\002\136 %u:%02u",TimeoutTime.Minutes, TimeoutTime.Seconds); @@ -4671,7 +4644,175 @@ return selection_customview == CVIEW_Compass || selection_custom_field == LLC_Compass; } - +void t7_drawAcentGraph(uint8_t color) +{ + point_t start, stop; + + SSettings* pSettings; + pSettings = settingsGetPointer(); + + + if(!pSettings->FlipDisplay) + { + start.y = t7l1.WindowY0 - 1; + } + else + { + start.y = t7l3.WindowY0 - 25; + } + + for(int i = 0; i<4;i++) + { + start.y += 5*6; + stop.y = start.y; + start.x = CUSTOMBOX_LINE_LEFT - 1; + stop.x = start.x - 17; + GFX_draw_line(&t7screen, start, stop, 0); +// start.x = CUSTOMBOX_LINE_RIGHT + 2; old right too +// stop.x = start.x + 17; +// GFX_draw_line(&t7screen, start, stop, 0); + } + // new thick bar design Sept. 2015 + start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 3 - 5; + stop.x = start.x; + if(!pSettings->FlipDisplay) + { + start.y = t7l1.WindowY0 - 1; + } + else + { + start.y = t7l3.WindowY0 - 25; + } + stop.y = start.y + (uint16_t)(stateUsed->lifeData.ascent_rate_meter_per_min * 6); + stop.y -= 3; // wegen der Liniendicke von 12 anstelle von 9 + if(stop.y >= 470) + stop.y = 470; + start.y += 7; // starte etwas weiter oben + if(color == 0) + { + color = CLUT_EverythingOkayGreen; /* do not use white color for drawing graph */ + } + + GFX_draw_thick_line(12,&t7screen, start, stop, color); +} + +#define ASCENT_GRAPH_YPIXEL 120 + +uint8_t t7_drawSlowExitGraph() +{ + static SSlowExitState slowExitState = SE_END; + static uint16_t countDownSec = 0; + static uint8_t drawingMeterStep; + static float exitDepthMeter = 0.0; + static uint32_t exitSecTick = 0; + + uint8_t index = 0; + static uint8_t color = 0; + point_t start, stop; + + SSettings* pSettings; + pSettings = settingsGetPointer(); + + if(stateUsed->lifeData.max_depth_meter < pSettings->last_stop_depth_meter) /* start of dive => reinit timer */ + { + if(slowExitState != SE_INIT) + { + //stepPerSecond = pSettings->last_stop_depth_meter / pSettings->slowExitTime; + countDownSec = pSettings->slowExitTime * 60; + drawingMeterStep = ASCENT_GRAPH_YPIXEL / pSettings->last_stop_depth_meter; /* based on 120 / 4 = 30 of standard ascent graph */ + slowExitState = SE_INIT; + exitDepthMeter = pSettings->last_stop_depth_meter; + color = 0; + } + } + else + { + if(slowExitState != SE_END) + { + if(slowExitState == SE_INIT) + { + slowExitState = SE_ACTIVE; + exitSecTick = HAL_GetTick(); + } + if(time_elapsed_ms(exitSecTick, HAL_GetTick()) > 1000) + { + exitSecTick = HAL_GetTick(); + + /* select depth digit color */ + if(fabsf(stateUsed->lifeData.depth_meter - exitDepthMeter) < 0.5 ) + { + color = CLUT_NiceGreen; + } + else if(fabsf(stateUsed->lifeData.depth_meter - exitDepthMeter) <= 1.5) + { + color = CLUT_WarningYellow; + } + else if(stateUsed->lifeData.depth_meter - exitDepthMeter < -1.5 ) + { + color = CLUT_WarningRed; + } + else + { + color = 0; + } + + if((fabsf(stateUsed->lifeData.depth_meter - exitDepthMeter) <= 1.6 ) /* only decrease counter if diver is close to target depth */ + || (color == CLUT_WarningRed)) /* or if diver is far ahead */ + { + countDownSec--; + if(countDownSec == 0) + { + slowExitState = SE_END; + color = 0; + } + exitDepthMeter -= (pSettings->last_stop_depth_meter / (float)(pSettings->slowExitTime * 60)); + } + } + if(!pSettings->FlipDisplay) + { + start.y = t7l1.WindowY0 - 1; + } + else + { + start.y = t7l3.WindowY0 - 25; + } + + for(index = 0; index < pSettings->last_stop_depth_meter; index++) /* draw meter indicators */ + { + start.y += drawingMeterStep; + stop.y = start.y; + start.x = CUSTOMBOX_LINE_LEFT - 1; + stop.x = start.x - 40; + GFX_draw_line(&t7screen, start, stop, 0); + } + + start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 20; + stop.x = start.x; + if(!pSettings->FlipDisplay) + { + start.y = t7l1.WindowY0 + ASCENT_GRAPH_YPIXEL; + } + else + { + start.y = t7l3.WindowY0 - 25; + } + stop.y = start.y - countDownSec * (ASCENT_GRAPH_YPIXEL / (float)(pSettings->slowExitTime * 60.0)); + if(stop.y >= 470) + stop.y = 470; + + GFX_draw_thick_line(15,&t7screen, start, stop, 3); + /* mark diver depth */ + start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 25; + stop.x = start.x + 15; + + start.y = start.y - (stateUsed->lifeData.depth_meter *120 / pSettings->last_stop_depth_meter); + stop.y = start.y; + GFX_draw_thick_line(10,&t7screen, start, stop, 9); + //GFX_draw_line(&t7screen, start, stop, 2); + } + } + return color; +} void t7_tick(void) { SSettings *settings = settingsGetPointer(); diff -r 5b675077ccfb -r 608d3e918146 Discovery/Src/tMenuDeco.c --- a/Discovery/Src/tMenuDeco.c Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Src/tMenuDeco.c Sat Aug 31 17:35:52 2024 +0200 @@ -134,6 +134,33 @@ if((line == 0) || (line == 4)) { + if(settingsGetPointer()->slowExitTime != 0) + { + textPointer += snprintf(&text[textPointer], 60,\ + "%c%c\t%u\016\016 %c\017 ^ %u\016\016 %c%c\017" + , TXT_2BYTE + , TXT2BYTE_SlowExit + , settingsGetPointer()->slowExitTime + ,TXT_Minutes + , unit_depth_integer(settingsGetPointer()->last_stop_depth_meter) + , unit_depth_char1() + , unit_depth_char2() + ); + } + else + { + textPointer += snprintf(&text[textPointer], 60, "%c%c\t%c%c" + , TXT_2BYTE + , TXT2BYTE_SlowExit + , TXT_2BYTE + , TXT2BYTE_MoCtrlNone + ); + } + } + strcpy(&text[textPointer],"\n\r"); + textPointer += 2; + if((line == 0) || (line == 5)) + { textPointer += snprintf(&text[textPointer], 60,\ "%c" "\t" @@ -149,7 +176,7 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; - if((line == 0) || (line == 5)) + if((line == 0) || (line == 6)) { textPointer += snprintf(&text[textPointer], 60,\ "%c" diff -r 5b675077ccfb -r 608d3e918146 Discovery/Src/tMenuEditDeco.c --- a/Discovery/Src/tMenuEditDeco.c Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Src/tMenuEditDeco.c Sat Aug 31 17:35:52 2024 +0200 @@ -42,6 +42,7 @@ static void openEdit_DiveMode(void); static void openEdit_ppO2max(void); static void openEdit_SafetyStop(void); +static void openEdit_ExitTime(void); static void openEdit_FutureTTS(void); static void openEdit_Salinity(void); @@ -50,6 +51,7 @@ static uint8_t OnAction_FutureTTS (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_ppO2Max (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_SafetyStop (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +static uint8_t OnAction_SlowExitTime (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); static uint8_t OnAction_Salinity (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); /* Exported functions --------------------------------------------------------*/ @@ -73,9 +75,12 @@ openEdit_SafetyStop(); break; case 4: + openEdit_ExitTime(); + break; + case 5: openEdit_FutureTTS(); break; - case 5: + case 6: openEdit_Salinity(); break; } @@ -259,6 +264,44 @@ } +static void openEdit_ExitTime(void) +{ + uint32_t SlowExitTime; + char text[64]; + uint16_t y_line; + + SlowExitTime = settingsGetPointer()->safetystopDuration; + + y_line = ME_Y_LINE_BASE + (lineSelected * ME_Y_LINE_STEP); + + text[0] = '\001'; + text[1] = TXT_2BYTE; + text[2] = TXT2BYTE_SlowExit; + text[3] = 0; + write_topline(text); + + write_label_var( 20, 800, y_line, &FontT48, &text[1]); + + strcpy(text,"\016\016"); + text[2] = TXT_Minutes; + if(settingsGetPointer()->nonMetricalSystem) + { + sprintf(&text[3], "\017 ^ %u\016\016 ft\017", settingsGetPointer()->slowExitTime); + } + else + { + sprintf(&text[3], "\017 ^ %u\016\016 m\017", settingsGetPointer()->slowExitTime); + } + write_label_var( 410, 800, y_line, &FontT48, text); + + write_field_udigit(StMDECO_SlowExit, 370, 800, y_line, &FontT48, "#", SlowExitTime, 0, 0, 0); + write_buttonTextline(TXT2BYTE_ButtonMinus,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonPlus); + + setEvent(StMDECO_SlowExit, (uint32_t)OnAction_SlowExitTime); + startEdit(); +} + + static uint8_t OnAction_SafetyStop (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) { uint8_t digitContentNew; @@ -346,6 +389,48 @@ return EXIT_TO_MENU; } +static uint8_t OnAction_SlowExitTime (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + uint8_t digitContentNew; + uint32_t newExitTime; + + if(action == ACTION_BUTTON_ENTER) + { + return digitContent; + } + if(action == ACTION_BUTTON_ENTER_FINAL) + { + evaluateNewString(editId, &newExitTime, 0, 0, 0); + + settingsGetPointer()->slowExitTime = newExitTime; + + tMenuEdit_newInput(editId, newExitTime, 0, 0, 0); + return UPDATE_AND_EXIT_TO_MENU; + } + if(action == ACTION_BUTTON_NEXT) + { + digitContentNew = digitContent + 1; + if(blockNumber == 0) + { + if(digitContentNew > '9') + digitContentNew = '0'; + } + + return digitContentNew; + } + if(action == ACTION_BUTTON_BACK) + { + digitContentNew = digitContent - 1; + if(blockNumber == 0) + { + if(digitContentNew < '0') + digitContentNew = '9'; + } + + return digitContentNew; + } + return EXIT_TO_MENU; +} static void openEdit_Salinity(void) { diff -r 5b675077ccfb -r 608d3e918146 Discovery/Src/text_multilanguage.c --- a/Discovery/Src/text_multilanguage.c Sat Aug 31 17:28:37 2024 +0200 +++ b/Discovery/Src/text_multilanguage.c Sat Aug 31 17:35:52 2024 +0200 @@ -1776,6 +1776,12 @@ static uint8_t text_IT_DecoTTS[] = ""; static uint8_t text_ES_DecoTTS[] = ""; +static uint8_t text_EN_SlowExit[] = "Slow exit"; +static uint8_t text_DE_SlowExit[] = "Ausstieg"; +static uint8_t text_FR_SlowExit[] = ""; +static uint8_t text_IT_SlowExit[] = ""; +static uint8_t text_ES_SlowExit[] = ""; + static uint8_t text_EN_ScrubTime[] = "Scrubber time"; static uint8_t text_DE_ScrubTime[] = "Kalkstandzeit"; static uint8_t text_FR_ScrubTime[] = "Scrubber time"; @@ -2199,6 +2205,7 @@ {(uint8_t)TXT2BYTE_Navigation, {text_EN_Navigation, text_DE_Navigation, text_FR_Navigation, text_IT_Navigation, text_ES_Navigation}}, {(uint8_t)TXT2BYTE_DepthData, {text_EN_DepthData, text_DE_DepthData, text_FR_DepthData, text_IT_DepthData, text_ES_DepthData}}, {(uint8_t)TXT2BYTE_DecoTTS, {text_EN_DecoTTS, text_DE_DecoTTS, text_FR_DecoTTS, text_IT_DecoTTS, text_ES_DecoTTS}}, + {(uint8_t)TXT2BYTE_SlowExit, {text_EN_SlowExit, text_DE_SlowExit, text_FR_SlowExit, text_IT_SlowExit, text_ES_SlowExit}}, {(uint8_t)TXT2BYTE_Minimum, {text_EN_Minimum, text_DE_Minimum, text_FR_Minimum, text_IT_Minimum, text_ES_Minimum}}, {(uint8_t)TXT2BYTE_Normal, {text_EN_Normal, text_DE_Normal, text_FR_Normal, text_IT_Normal, text_ES_Normal}},