comparison Discovery/Src/tInfoPreDive.c @ 845:17d9d6eddd8d Evo_2_23

Added new PreDiveCheck info page: In case a DiveO2 sensor is connected to the OSTC than the values of the DiveO2 internal pressure and temperature sensors may be used for predive checks. The pressure sensors is used for over / under pressure test and the values are visualized using a graph to make it easier to check if the pressure keeps stable. The temperature measurement gives an indication if the scrubber is getting active. This view is highly dependend on the surface temperature but may be useful e.g. for diving in european area. In addition the values ofthe connected sensors are shown.
author Ideenmodellierer
date Sun, 21 Jan 2024 22:24:36 +0100
parents
children fce639612464
comparison
equal deleted inserted replaced
844:e04d7dd199fb 845:17d9d6eddd8d
1 ///////////////////////////////////////////////////////////////////////////////
2 /// -*- coding: UTF-8 -*-
3 ///
4 /// \file Discovery/Src/tInfoPredive.c
5 /// \brief Show information which might be of interest during predive checks
6 /// \author heinrichs weikamp gmbh
7 /// \date 23-Feb-2015
8 ///
9 /// \details
10 ///
11 /// $Id$
12 ///////////////////////////////////////////////////////////////////////////////
13 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh
14 ///
15 /// This program is free software: you can redistribute it and/or modify
16 /// it under the terms of the GNU General Public License as published by
17 /// the Free Software Foundation, either version 3 of the License, or
18 /// (at your option) any later version.
19 ///
20 /// This program is distributed in the hope that it will be useful,
21 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
22 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 /// GNU General Public License for more details.
24 ///
25 /// You should have received a copy of the GNU General Public License
26 /// along with this program. If not, see <http://www.gnu.org/licenses/>.
27 //////////////////////////////////////////////////////////////////////////////
28
29 /* Includes ------------------------------------------------------------------*/
30
31 #include "gfx_engine.h"
32 #include "gfx_fonts.h"
33 #include "tHome.h"
34 #include "tInfo.h"
35 #include "tInfoPreDive.h"
36 #include "tMenuEdit.h"
37 #include "data_exchange_main.h"
38
39 #include <string.h>
40 #include <inttypes.h>
41
42 #define MEASURE_INTERVALL (10u) /* refresh function should be called every 100ms => one second interval */
43 #define HISTORY_BUF_SIZE (240u) /* store 240 entries a one second */
44 #define INVALID_PRESSURE_VALUE (0xFFFF)
45 #define DELTA_SHIFT (50) /* the graph printers do not support negative values => shift data into positiv area (assumes pressure range +- 300mBar) */
46
47 /* Private variables ---------------------------------------------------------*/
48 static uint16_t surfacePressureStart = INVALID_PRESSURE_VALUE;
49 static uint16_t surfaceTemperatureStart = 0;
50 static uint16_t pressureHistory[HISTORY_BUF_SIZE];
51 static uint8_t pressureHistoryIndex = 0;
52 static uint16_t temperatureHistory[HISTORY_BUF_SIZE];
53 static uint8_t temperatureHistoryIndex = 0;
54 static uint8_t measureCnt = MEASURE_INTERVALL;
55 static uint8_t referenceSensor = 0xff;
56
57 /* Exported functions --------------------------------------------------------*/
58
59
60
61 static void storePressureValue(int16_t deltapressure_mBar)
62 {
63 uint16_t newValue = DELTA_SHIFT - deltapressure_mBar; /* invert value because graph is drawing larger values to bottom direction */
64 if(pressureHistoryIndex + 2 < HISTORY_BUF_SIZE)
65 {
66 pressureHistoryIndex++;
67 pressureHistory[pressureHistoryIndex] = newValue;
68 pressureHistoryIndex++;
69 pressureHistory[pressureHistoryIndex] = newValue;
70 }
71 else
72 {
73 memcpy (&pressureHistory[0],&pressureHistory[2],sizeof(pressureHistory) - 2);
74 pressureHistory[pressureHistoryIndex] = newValue;
75 }
76 }
77
78 static void storeTemperatureValue(uint16_t temperature)
79 {
80 uint16_t newValue = temperature; /* todo: consider negativ temperature */
81 if(temperatureHistoryIndex + 2 < HISTORY_BUF_SIZE)
82 {
83 temperatureHistoryIndex++;
84 temperatureHistory[temperatureHistoryIndex] = newValue;
85 temperatureHistoryIndex++;
86 temperatureHistory[temperatureHistoryIndex] = newValue;
87 }
88 else
89 {
90 memcpy (&temperatureHistory[0],&temperatureHistory[2],sizeof(temperatureHistory) - 2);
91 temperatureHistory[temperatureHistoryIndex] = newValue;
92 }
93 }
94
95 void openInfo_PreDive()
96 {
97 const SDiveState *pStateReal = stateRealGetPointer();
98 uint8_t index = 0;
99 SSensorDataDiveO2* pDiveO2Data = NULL;
100 SSettings *pSettings = settingsGetPointer();
101 set_globalState(StIPREDIVE);
102
103 surfacePressureStart = 0;
104 pressureHistoryIndex = 0;
105 referenceSensor = 0xff;
106
107 for(index = 0; index < EXT_INTERFACE_MUX_OFFSET; index++)
108 {
109 if((pSettings->ext_sensor_map[index] == SENSOR_DIGO2M) && pStateReal->lifeData.ppO2Sensor_bar[index] != 0)
110 {
111 referenceSensor = index;
112 pDiveO2Data = (SSensorDataDiveO2*)stateRealGetPointer()->lifeData.extIf_sensor_data[index];
113 if(pDiveO2Data->pressure != 0)
114 {
115 surfacePressureStart = pDiveO2Data->pressure / 1000;
116 surfaceTemperatureStart = pDiveO2Data->temperature;
117 }
118 break;
119 }
120 }
121 for(index = 0; index < HISTORY_BUF_SIZE; index++)
122 {
123 pressureHistory[index] = DELTA_SHIFT;
124 temperatureHistory[index] = 0;
125 }
126 }
127
128 void refreshInfo_PreDive(GFX_DrawCfgScreen s)
129 {
130 const SDiveState *pStateReal = stateRealGetPointer();
131 static int16_t deltaPressure = 0;
132 static uint16_t temperature = 0;
133 SSettings *pSettings = settingsGetPointer();
134 uint8_t index = 0;
135 char text[31];
136 SSensorDataDiveO2* pDiveO2Data = NULL;
137 point_t start, stop;
138
139 SWindowGimpStyle wintempppO2;
140 SWindowGimpStyle wintemptemp;
141
142 if(--measureCnt == 0)
143 {
144 measureCnt = MEASURE_INTERVALL;
145 pDiveO2Data = (SSensorDataDiveO2*)stateRealGetPointer()->lifeData.extIf_sensor_data[referenceSensor];
146 if(pDiveO2Data->pressure != 0)
147 {
148 if(surfacePressureStart == 0)
149 {
150 surfacePressureStart = pDiveO2Data->pressure / 1000;
151 surfaceTemperatureStart = pDiveO2Data->temperature;
152 }
153 deltaPressure = (pDiveO2Data->pressure / 1000) - surfacePressureStart;
154 storePressureValue(deltaPressure);
155 temperature = pDiveO2Data->temperature;
156 storeTemperatureValue(temperature);
157 }
158 }
159
160 text[0] = '\001';
161 text[1] = TXT_PreDive;
162 text[2] = 0;
163 tInfo_write_content_simple( 30, 770, ME_Y_LINE_BASE, &FontT48, text, CLUT_MenuPageHardware);
164
165 for(index = 0; index < EXT_INTERFACE_MUX_OFFSET; index++)
166 {
167 if(pSettings->ext_sensor_map[index] == SENSOR_DIGO2M)
168 {
169 snprintf(text,32,"%c%c%d: %01.2f", TXT_2BYTE, TXT2BYTE_Sensor, index, pStateReal->lifeData.ppO2Sensor_bar[index]);
170 tInfo_write_content_simple( 30, 200, ME_Y_LINE1 + (index * ME_Y_LINE_STEP), &FontT48, text, CLUT_Font020);
171 }
172 else if(pSettings->ext_sensor_map[index] == SENSOR_CO2M)
173 {
174 snprintf(text,32,"CO2: %4ld", pStateReal->lifeData.CO2_data.CO2_ppm);
175 tInfo_write_content_simple( 30, 200, ME_Y_LINE5, &FontT48, text, CLUT_Font020);
176 }
177 }
178
179 wintempppO2.left = 350;
180 wintempppO2.right = 590;
181
182 wintemptemp.left = 350;
183 wintemptemp.right = 590;
184
185 if(!pSettings->FlipDisplay)
186 {
187 wintempppO2.top = ME_Y_LINE3;
188 wintempppO2.bottom = wintempppO2.top + DELTA_SHIFT * 2;
189 wintemptemp.top = ME_Y_LINE5;
190 wintemptemp.bottom = wintemptemp.top + DELTA_SHIFT * 2;
191 }
192 else
193 {
194 wintempppO2.top = 470; /* TODO: consider flip display */
195 wintempppO2.bottom = wintempppO2.top + 100;
196 }
197 GFX_graph_print(&s, &wintempppO2, 1,1,0, DELTA_SHIFT * 2, pressureHistory, HISTORY_BUF_SIZE, CLUT_Font030, NULL);
198
199 GFX_graph_print(&s, &wintemptemp, 1,1, surfaceTemperatureStart - 2000, surfaceTemperatureStart + 10000, temperatureHistory, HISTORY_BUF_SIZE, CLUT_Font030, NULL);
200
201 start.x = wintempppO2.left - 5;
202 start.y = 480 - wintemptemp.bottom - 5;
203 stop.x = wintempppO2.right- start.x + 5;
204 stop.y = DELTA_SHIFT * 2 + 10;
205 GFX_draw_box(&s, start, stop,1, CLUT_Font020);
206
207 start.y = 480 - wintempppO2.bottom - 5;
208 GFX_draw_box(&s, start, stop,1, CLUT_Font020);
209
210 /* Graph labeling */
211 snprintf(text,32,"%c%c", TXT_2BYTE, TXT2BYTE_CounterLung);
212 tInfo_write_content_simple( 350, 780, ME_Y_LINE2, &FontT48, text, CLUT_Font020);
213
214 snprintf(text,32,"\002\016\016%c%c", TXT_2BYTE, TXT2BYTE_Pressure);
215 tInfo_write_content_simple( 600, 780, ME_Y_LINE3, &FontT48, text, CLUT_Font020);
216 snprintf(text,32,"\002%d",deltaPressure);
217 tInfo_write_content_simple( 600, 780, ME_Y_LINE4, &FontT48, text, CLUT_Font020);
218 snprintf(text,32,"\002\016\016%c",TXT_Temperature);
219 tInfo_write_content_simple( 600, 780, ME_Y_LINE5, &FontT48, text, CLUT_Font020);
220 snprintf(text,32,"\002%2.2f",(temperature / 1000.0));
221 tInfo_write_content_simple( 600, 780, ME_Y_LINE6, &FontT48, text, CLUT_Font020);
222 }
223
224 void sendActionToInfoPreDive(uint8_t sendAction)
225 {
226 switch(sendAction)
227 {
228 case ACTION_BUTTON_BACK:
229 // exitInfo();
230 exitMenuEdit_to_Menu_with_Menu_Update();
231 break;
232
233 case ACTION_BUTTON_ENTER:
234 break;
235 case ACTION_BUTTON_NEXT:
236 break;
237 case ACTION_TIMEOUT:
238 case ACTION_MODE_CHANGE:
239 case ACTION_IDLE_TICK:
240 case ACTION_IDLE_SECOND:
241 default:
242 break;
243 }
244 }
245