comparison Discovery/Src/t7.c @ 882:608d3e918146 Evo_2_23

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.
author Ideenmodellierer
date Sat, 31 Aug 2024 17:35:52 +0200
parents db92692c014f
children 940f8e132638
comparison
equal deleted inserted replaced
881:5b675077ccfb 882:608d3e918146
77 uint8_t t7_test_customview_warnings_surface_mode(void); 77 uint8_t t7_test_customview_warnings_surface_mode(void);
78 void t7_show_customview_warnings_surface_mode(void); 78 void t7_show_customview_warnings_surface_mode(void);
79 79
80 uint8_t t7_customtextPrepare(char * text); 80 uint8_t t7_customtextPrepare(char * text);
81 81
82 static void t7_drawAcentGraph(uint8_t color);
83 static uint8_t t7_drawSlowExitGraph(void);
84
82 /* Imported function prototypes ---------------------------------------------*/ 85 /* Imported function prototypes ---------------------------------------------*/
83 extern uint8_t write_gas(char *text, uint8_t oxygen, uint8_t helium); 86 extern uint8_t write_gas(char *text, uint8_t oxygen, uint8_t helium);
84 87
85 /* Exported variables --------------------------------------------------------*/ 88 /* Exported variables --------------------------------------------------------*/
86 89
118 .pointer = 0, 121 .pointer = 0,
119 }; 122 };
120 123
121 124
122 /* Private types -------------------------------------------------------------*/ 125 /* Private types -------------------------------------------------------------*/
126
127 typedef enum
128 {
129 SE_INIT = 0,
130 SE_ACTIVE,
131 SE_END
132 } SSlowExitState;
123 133
124 const uint8_t customviewsSurfaceStandard[] = 134 const uint8_t customviewsSurfaceStandard[] =
125 { 135 {
126 // CVIEW_CompassDebug, 136 // CVIEW_CompassDebug,
127 CVIEW_Hello, 137 CVIEW_Hello,
2731 2741
2732 SafetyStopTime.Total = timer_Safetystop_GetCountDown(); 2742 SafetyStopTime.Total = timer_Safetystop_GetCountDown();
2733 SafetyStopTime.Minutes = SafetyStopTime.Total / 60; 2743 SafetyStopTime.Minutes = SafetyStopTime.Total / 60;
2734 SafetyStopTime.Seconds = SafetyStopTime.Total - (SafetyStopTime.Minutes * 60); 2744 SafetyStopTime.Seconds = SafetyStopTime.Total - (SafetyStopTime.Minutes * 60);
2735 2745
2736 TimeoutTime.Total = settingsGetPointer()->timeoutDiveReachedZeroDepth - stateUsed->lifeData.counterSecondsShallowDepth; 2746 TimeoutTime.Total = pSettings->timeoutDiveReachedZeroDepth - stateUsed->lifeData.counterSecondsShallowDepth;
2737 if(TimeoutTime.Total > settingsGetPointer()->timeoutDiveReachedZeroDepth) 2747 if(TimeoutTime.Total > pSettings->timeoutDiveReachedZeroDepth)
2738 { 2748 {
2739 TimeoutTime.Total = 0; 2749 TimeoutTime.Total = 0;
2740 } 2750 }
2741 TimeoutTime.Minutes = TimeoutTime.Total / 60; 2751 TimeoutTime.Minutes = TimeoutTime.Total / 60;
2742 TimeoutTime.Seconds = TimeoutTime.Total - (TimeoutTime.Minutes * 60); 2752 TimeoutTime.Seconds = TimeoutTime.Total - (TimeoutTime.Minutes * 60);
2750 { 2760 {
2751 nextstopDepthMeter = 0; 2761 nextstopDepthMeter = 0;
2752 nextstopLengthSeconds = 0; 2762 nextstopLengthSeconds = 0;
2753 } 2763 }
2754 2764
2765
2766 /* max depth */
2767 snprintf(TextL2,TEXTSIZE,"\032\f%c",TXT_MaxDepth);
2768 GFX_write_string(&FontT42,&t7l2,TextL2,0);
2769
2770 if(unit_depth_float(stateUsed->lifeData.max_depth_meter) < 100)
2771 snprintf(TextL2,TEXTSIZE,"\020%01.1f",unit_depth_float(stateUsed->lifeData.max_depth_meter));
2772 else
2773 snprintf(TextL2,TEXTSIZE,"\020%01.0f",unit_depth_float(stateUsed->lifeData.max_depth_meter));
2774
2775 Gfx_colorsscheme_mod(TextL2, 0);
2776 GFX_write_string(&FontT105,&t7l2,TextL2,1);
2777
2778 /* ascent rate graph */
2779
2780 if((pSettings->slowExitTime != 0) && (stateUsed->lifeData.depth_meter < pSettings->last_stop_depth_meter))
2781 {
2782 color = t7_drawSlowExitGraph();
2783 }
2784 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 */
2785 {
2786 color = drawingColor_from_ascentspeed(stateUsed->lifeData.ascent_rate_meter_per_min);
2787 t7_drawAcentGraph(color);
2788 }
2789
2790
2755 /* depth */ 2791 /* depth */
2756 float depth = unit_depth_float(stateUsed->lifeData.depth_meter); 2792 float depth = unit_depth_float(stateUsed->lifeData.depth_meter);
2757 2793
2758 if(depth <= 0.3f) 2794 if(depth <= 0.3f)
2759 depth = 0; 2795 depth = 0;
2760 2796
2761 if(settingsGetPointer()->nonMetricalSystem) 2797 if(settingsGetPointer()->nonMetricalSystem)
2762 snprintf(TextL1,TEXTSIZE,"\032\f[feet]"); 2798 snprintf(TextL1,TEXTSIZE,"\032\f[feet]");
2763 else 2799 else
2764 snprintf(TextL1,TEXTSIZE,"\032\f%c",TXT_Depth); 2800 snprintf(TextL1,TEXTSIZE,"\032\f%c",TXT_Depth);
2765
2766 color = drawingColor_from_ascentspeed(stateUsed->lifeData.ascent_rate_meter_per_min);
2767
2768 2801
2769 GFX_write_string(&FontT24,&t7l1,TextL1,0); 2802 GFX_write_string(&FontT24,&t7l1,TextL1,0);
2770 2803
2771 if((stateUsed->lifeData.ascent_rate_meter_per_min > 8) || (stateUsed->lifeData.ascent_rate_meter_per_min < -10)) 2804 if((stateUsed->lifeData.ascent_rate_meter_per_min > 8) || (stateUsed->lifeData.ascent_rate_meter_per_min < -10))
2772 { 2805 {
2783 else 2816 else
2784 snprintf(TextL1,TEXTSIZE,"\020%01.0f",depth); 2817 snprintf(TextL1,TEXTSIZE,"\020%01.0f",depth);
2785 2818
2786 Gfx_colorsscheme_mod(TextL1, color); 2819 Gfx_colorsscheme_mod(TextL1, color);
2787 2820
2788
2789
2790 GFX_write_string(&FontT144,&t7l1,TextL1,0); 2821 GFX_write_string(&FontT144,&t7l1,TextL1,0);
2791 2822
2792 /* max depth */ 2823
2793 snprintf(TextL2,TEXTSIZE,"\032\f%c",TXT_MaxDepth); 2824
2794 GFX_write_string(&FontT42,&t7l2,TextL2,0); 2825 /* divetime */
2795
2796 if(unit_depth_float(stateUsed->lifeData.max_depth_meter) < 100)
2797 snprintf(TextL2,TEXTSIZE,"\020%01.1f",unit_depth_float(stateUsed->lifeData.max_depth_meter));
2798 else
2799 snprintf(TextL2,TEXTSIZE,"\020%01.0f",unit_depth_float(stateUsed->lifeData.max_depth_meter));
2800
2801 Gfx_colorsscheme_mod(TextL2, 0);
2802 GFX_write_string(&FontT105,&t7l2,TextL2,1);
2803
2804 /* ascent rate graph */
2805 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 */
2806 {
2807 if(!pSettings->FlipDisplay)
2808 {
2809 start.y = t7l1.WindowY0 - 1;
2810 }
2811 else
2812 {
2813 start.y = t7l3.WindowY0 - 25;
2814 }
2815
2816 for(int i = 0; i<4;i++)
2817 {
2818 start.y += 5*6;
2819 stop.y = start.y;
2820 start.x = CUSTOMBOX_LINE_LEFT - 1;
2821 stop.x = start.x - 17;
2822 GFX_draw_line(&t7screen, start, stop, 0);
2823 // start.x = CUSTOMBOX_LINE_RIGHT + 2; old right too
2824 // stop.x = start.x + 17;
2825 // GFX_draw_line(&t7screen, start, stop, 0);
2826 }
2827 // new thick bar design Sept. 2015
2828 start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 3 - 5;
2829 stop.x = start.x;
2830 if(!pSettings->FlipDisplay)
2831 {
2832 start.y = t7l1.WindowY0 - 1;
2833 }
2834 else
2835 {
2836 start.y = t7l3.WindowY0 - 25;
2837 }
2838 stop.y = start.y + (uint16_t)(stateUsed->lifeData.ascent_rate_meter_per_min * 6);
2839 stop.y -= 3; // wegen der Liniendicke von 12 anstelle von 9
2840 if(stop.y >= 470)
2841 stop.y = 470;
2842 start.y += 7; // starte etwas weiter oben
2843 if(color == 0)
2844 {
2845 color = CLUT_EverythingOkayGreen; /* do not use white color for drawing graph */
2846 }
2847
2848 GFX_draw_thick_line(12,&t7screen, start, stop, color);
2849 }
2850 //snprintf(TextL2,TEXTSIZE,"\f%.1f m/min",stateUsed->lifeData.ascent_rate_meter_per_min);
2851
2852 /* divetime */
2853 if(stateUsed->lifeData.counterSecondsShallowDepth) 2826 if(stateUsed->lifeData.counterSecondsShallowDepth)
2854 { 2827 {
2855 snprintf(TextR1,TEXTSIZE,"\f\002\136 %u:%02u",TimeoutTime.Minutes, TimeoutTime.Seconds); 2828 snprintf(TextR1,TEXTSIZE,"\f\002\136 %u:%02u",TimeoutTime.Minutes, TimeoutTime.Seconds);
2856 GFX_write_string(&FontT42,&t7r1,TextR1,0); 2829 GFX_write_string(&FontT42,&t7r1,TextR1,0);
2857 } 2830 }
4669 bool t7_isCompassShowing(void) 4642 bool t7_isCompassShowing(void)
4670 { 4643 {
4671 return selection_customview == CVIEW_Compass || selection_custom_field == LLC_Compass; 4644 return selection_customview == CVIEW_Compass || selection_custom_field == LLC_Compass;
4672 } 4645 }
4673 4646
4674 4647 void t7_drawAcentGraph(uint8_t color)
4648 {
4649 point_t start, stop;
4650
4651 SSettings* pSettings;
4652 pSettings = settingsGetPointer();
4653
4654
4655 if(!pSettings->FlipDisplay)
4656 {
4657 start.y = t7l1.WindowY0 - 1;
4658 }
4659 else
4660 {
4661 start.y = t7l3.WindowY0 - 25;
4662 }
4663
4664 for(int i = 0; i<4;i++)
4665 {
4666 start.y += 5*6;
4667 stop.y = start.y;
4668 start.x = CUSTOMBOX_LINE_LEFT - 1;
4669 stop.x = start.x - 17;
4670 GFX_draw_line(&t7screen, start, stop, 0);
4671 // start.x = CUSTOMBOX_LINE_RIGHT + 2; old right too
4672 // stop.x = start.x + 17;
4673 // GFX_draw_line(&t7screen, start, stop, 0);
4674 }
4675 // new thick bar design Sept. 2015
4676 start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 3 - 5;
4677 stop.x = start.x;
4678 if(!pSettings->FlipDisplay)
4679 {
4680 start.y = t7l1.WindowY0 - 1;
4681 }
4682 else
4683 {
4684 start.y = t7l3.WindowY0 - 25;
4685 }
4686 stop.y = start.y + (uint16_t)(stateUsed->lifeData.ascent_rate_meter_per_min * 6);
4687 stop.y -= 3; // wegen der Liniendicke von 12 anstelle von 9
4688 if(stop.y >= 470)
4689 stop.y = 470;
4690 start.y += 7; // starte etwas weiter oben
4691 if(color == 0)
4692 {
4693 color = CLUT_EverythingOkayGreen; /* do not use white color for drawing graph */
4694 }
4695
4696 GFX_draw_thick_line(12,&t7screen, start, stop, color);
4697 }
4698
4699 #define ASCENT_GRAPH_YPIXEL 120
4700
4701 uint8_t t7_drawSlowExitGraph()
4702 {
4703 static SSlowExitState slowExitState = SE_END;
4704 static uint16_t countDownSec = 0;
4705 static uint8_t drawingMeterStep;
4706 static float exitDepthMeter = 0.0;
4707 static uint32_t exitSecTick = 0;
4708
4709 uint8_t index = 0;
4710 static uint8_t color = 0;
4711 point_t start, stop;
4712
4713 SSettings* pSettings;
4714 pSettings = settingsGetPointer();
4715
4716 if(stateUsed->lifeData.max_depth_meter < pSettings->last_stop_depth_meter) /* start of dive => reinit timer */
4717 {
4718 if(slowExitState != SE_INIT)
4719 {
4720 //stepPerSecond = pSettings->last_stop_depth_meter / pSettings->slowExitTime;
4721 countDownSec = pSettings->slowExitTime * 60;
4722 drawingMeterStep = ASCENT_GRAPH_YPIXEL / pSettings->last_stop_depth_meter; /* based on 120 / 4 = 30 of standard ascent graph */
4723 slowExitState = SE_INIT;
4724 exitDepthMeter = pSettings->last_stop_depth_meter;
4725 color = 0;
4726 }
4727 }
4728 else
4729 {
4730 if(slowExitState != SE_END)
4731 {
4732 if(slowExitState == SE_INIT)
4733 {
4734 slowExitState = SE_ACTIVE;
4735 exitSecTick = HAL_GetTick();
4736 }
4737 if(time_elapsed_ms(exitSecTick, HAL_GetTick()) > 1000)
4738 {
4739 exitSecTick = HAL_GetTick();
4740
4741 /* select depth digit color */
4742 if(fabsf(stateUsed->lifeData.depth_meter - exitDepthMeter) < 0.5 )
4743 {
4744 color = CLUT_NiceGreen;
4745 }
4746 else if(fabsf(stateUsed->lifeData.depth_meter - exitDepthMeter) <= 1.5)
4747 {
4748 color = CLUT_WarningYellow;
4749 }
4750 else if(stateUsed->lifeData.depth_meter - exitDepthMeter < -1.5 )
4751 {
4752 color = CLUT_WarningRed;
4753 }
4754 else
4755 {
4756 color = 0;
4757 }
4758
4759 if((fabsf(stateUsed->lifeData.depth_meter - exitDepthMeter) <= 1.6 ) /* only decrease counter if diver is close to target depth */
4760 || (color == CLUT_WarningRed)) /* or if diver is far ahead */
4761 {
4762 countDownSec--;
4763 if(countDownSec == 0)
4764 {
4765 slowExitState = SE_END;
4766 color = 0;
4767 }
4768 exitDepthMeter -= (pSettings->last_stop_depth_meter / (float)(pSettings->slowExitTime * 60));
4769 }
4770 }
4771 if(!pSettings->FlipDisplay)
4772 {
4773 start.y = t7l1.WindowY0 - 1;
4774 }
4775 else
4776 {
4777 start.y = t7l3.WindowY0 - 25;
4778 }
4779
4780 for(index = 0; index < pSettings->last_stop_depth_meter; index++) /* draw meter indicators */
4781 {
4782 start.y += drawingMeterStep;
4783 stop.y = start.y;
4784 start.x = CUSTOMBOX_LINE_LEFT - 1;
4785 stop.x = start.x - 40;
4786 GFX_draw_line(&t7screen, start, stop, 0);
4787 }
4788
4789 start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 20;
4790 stop.x = start.x;
4791 if(!pSettings->FlipDisplay)
4792 {
4793 start.y = t7l1.WindowY0 + ASCENT_GRAPH_YPIXEL;
4794 }
4795 else
4796 {
4797 start.y = t7l3.WindowY0 - 25;
4798 }
4799 stop.y = start.y - countDownSec * (ASCENT_GRAPH_YPIXEL / (float)(pSettings->slowExitTime * 60.0));
4800 if(stop.y >= 470)
4801 stop.y = 470;
4802
4803 GFX_draw_thick_line(15,&t7screen, start, stop, 3);
4804 /* mark diver depth */
4805 start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 25;
4806 stop.x = start.x + 15;
4807
4808 start.y = start.y - (stateUsed->lifeData.depth_meter *120 / pSettings->last_stop_depth_meter);
4809 stop.y = start.y;
4810 GFX_draw_thick_line(10,&t7screen, start, stop, 9);
4811 //GFX_draw_line(&t7screen, start, stop, 2);
4812 }
4813 }
4814 return color;
4815 }
4675 void t7_tick(void) 4816 void t7_tick(void)
4676 { 4817 {
4677 SSettings *settings = settingsGetPointer(); 4818 SSettings *settings = settingsGetPointer();
4678 4819
4679 int nowS = current_second(); 4820 int nowS = current_second();