changeset 340:0756013e43b3

Merged in Ideenmodellierer/ostc4/PressureMeasure_Improvment (pull request #31) PressureMeasure Improvment
author heinrichsweikamp <bitbucket@heinrichsweikamp.com>
date Mon, 19 Aug 2019 11:42:31 +0000
parents 143fe85f82a2 (current diff) 37f45300bc2e (diff)
children 591c03a1e68d ea3fda8eb93e 607099140a41 75eedde05ff6
files
diffstat 7 files changed, 126 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/Common/Inc/settings.h	Sun Aug 04 11:01:06 2019 +0200
+++ b/Common/Inc/settings.h	Mon Aug 19 11:42:31 2019 +0000
@@ -66,6 +66,8 @@
 #define DDMMYY 1
 #define YYMMDD 2
 
+#define PRESSURE_OFFSET_LIMIT_MBAR	50
+
 /*	2015 Jan 30, hw, deco and travel added for MenuEditGas
 	* can be used for buehlmann, vpm, etc. later but be carefull
 	*	with current implemenation */
--- a/Discovery/Src/settings.c	Sun Aug 04 11:01:06 2019 +0200
+++ b/Discovery/Src/settings.c	Mon Aug 19 11:42:31 2019 +0000
@@ -1219,8 +1219,8 @@
 
 /*	int8_t offsetPressure_mbar;
  */
-    if((Settings.offsetPressure_mbar > 20) ||
-         (Settings.offsetPressure_mbar < -20))
+    if((Settings.offsetPressure_mbar > PRESSURE_OFFSET_LIMIT_MBAR) ||
+         (Settings.offsetPressure_mbar < -1 * PRESSURE_OFFSET_LIMIT_MBAR))
     {
         Settings.offsetPressure_mbar = 0;
         corrections++;
@@ -1730,13 +1730,13 @@
                 if(data[1] & 0x80)
                 {
                     data[1] = ~(data[1]);
-                    if(!checkValue(data[1],0,20))
+                    if(!checkValue(data[1],0,PRESSURE_OFFSET_LIMIT_MBAR))
                             return ERROR_;
                     Settings.offsetPressure_mbar = 0 - data[1];
                 }
                 else
                 {
-                    if(!checkValue(data[1],0,20))
+                    if(!checkValue(data[1],0,PRESSURE_OFFSET_LIMIT_MBAR))
                             return ERROR_;
                     Settings.offsetPressure_mbar = data[1];
                 }
@@ -2094,12 +2094,12 @@
 
     case 0x35:
         data[datacounter++] =  PARAM_SINT;
-        data[datacounter++] = (uint8_t)(256 - 20); // == -20
+        data[datacounter++] = (uint8_t)(256 - PRESSURE_OFFSET_LIMIT_MBAR); // == -20
         if(settingsGetPointerStandard()->offsetPressure_mbar < 0)
             data[datacounter++] = (uint8_t)(127 - settingsGetPointerStandard()->offsetPressure_mbar);
         else
             data[datacounter++] = settingsGetPointerStandard()->offsetPressure_mbar;
-        data[datacounter++] = 20;
+        data[datacounter++] = PRESSURE_OFFSET_LIMIT_MBAR;
         break;
 
     case 0x36:
--- a/Discovery/Src/t7.c	Sun Aug 04 11:01:06 2019 +0200
+++ b/Discovery/Src/t7.c	Mon Aug 19 11:42:31 2019 +0000
@@ -158,6 +158,9 @@
 #define CUSTOMBOX_SPACE_INSIDE (CUSTOMBOX_LINE_RIGHT + 1 - (CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET + CUSTOMBOX_INSIDE_OFFSET))
 #define TOP_LINE_HIGHT (25)
 
+#define SHOW_AMBIENTE_SURFACE_DELTA		(0.02f)
+#define SHOW_AMBIENTE_DEBOUNCE			(0.003f)
+
 /* Exported functions --------------------------------------------------------*/
 
 void t7_init(void)
@@ -661,6 +664,7 @@
 
 void t7_refresh_surface(void)
 {
+	static float debounceAmbientPressure = 0;
     char text[256];
     uint8_t date[3], year,month,day;
     uint32_t color;
@@ -905,7 +909,19 @@
     /* surface pressure  and temperature */
     if(stateUsed->sensorErrorsRTE == 0)
     {
-        snprintf(text,30,"%01.0f\022\016\016 %s", stateUsed->lifeData.pressure_surface_bar * 1000.0f,TEXT_PRESSURE_UNIT);
+    	if(fabs(stateUsed->lifeData.pressure_surface_bar - stateUsed->lifeData.pressure_ambient_bar) < SHOW_AMBIENTE_SURFACE_DELTA)	/* show ambient pressure if difference to surface is significant*/
+    	{
+    		snprintf(text,30,"%01.0f\022\016\016 %s", stateUsed->lifeData.pressure_surface_bar * 1000.0f,TEXT_PRESSURE_UNIT);
+    	}
+    	else
+    	{
+    		if(fabsf(debounceAmbientPressure - stateUsed->lifeData.pressure_ambient_bar) > SHOW_AMBIENTE_DEBOUNCE)   /* there might be a jitter ~+-1 HPa on the pressure signal => update only if delta is bigger */
+    		{
+    			debounceAmbientPressure = stateUsed->lifeData.pressure_ambient_bar;
+    		}
+    		snprintf(text,30,"%01.0f\022\016\016 %s", debounceAmbientPressure * 1000.0f,TEXT_PRESSURE_UNIT);
+    	}
+
         GFX_write_string(&FontT48,&t7surfaceL,text,3);
 
         if(settingsGetPointer()->nonMetricalSystem)
@@ -1223,7 +1239,7 @@
     else
     if(DataEX_lost_connection_count())
     {
-        snprintf(TextL1,TEXTSIZE,"\002%i",DataEX_lost_connection_count());
+        snprintf(TextL1,TEXTSIZE,"\002%ld",DataEX_lost_connection_count());
         Gfx_write_label_var(&t7screen,  600,800, 45,&FontT48,CLUT_Font020,TextL1);
     }
 
@@ -1288,7 +1304,7 @@
 
 extern uint32_t base_tempLightLevel;
 
-    snprintf(TextL1,TEXTSIZE,"# %u (%u)",stateUsed->lifeData.ambient_light_level, base_tempLightLevel);
+    snprintf(TextL1,TEXTSIZE,"# %u (%ld)",stateUsed->lifeData.ambient_light_level, base_tempLightLevel);
     Gfx_write_label_var(&t7screen,  401,600,310,&FontT42,CLUT_DiveMainLabel,"Light");
     Gfx_write_label_var(&t7screen,  401,800,355,&FontT48,CLUT_Font020,TextL1);
 
--- a/Small_CPU/Inc/pressure.h	Sun Aug 04 11:01:06 2019 +0200
+++ b/Small_CPU/Inc/pressure.h	Mon Aug 19 11:42:31 2019 +0000
@@ -5,6 +5,8 @@
 #include <stdint.h>
 
 uint8_t init_pressure(void);
+void pressure_set_offset (float pressureOffset, float temperatureOffset);
+
 uint8_t pressure_update(void);
 void pressure_update_alternating(void);
 
@@ -18,7 +20,7 @@
 float get_pressure_mbar(void);
 float get_surface_mbar(void);
 
-void init_surface_ring(void);
+void init_surface_ring(uint8_t force);
 void update_surface_pressure(uint8_t call_rhythm_seconds);
 
 uint32_t demo_modify_temperature_and_pressure(int32_t divetime_in_seconds, uint8_t subseconds, float ceiling_mbar);
--- a/Small_CPU/Src/baseCPU2.c	Sun Aug 04 11:01:06 2019 +0200
+++ b/Small_CPU/Src/baseCPU2.c	Mon Aug 19 11:42:31 2019 +0000
@@ -334,7 +334,7 @@
 
 	if(is_init_pressure_done())
 	{
-		init_surface_ring();
+		init_surface_ring(0);
 	}
 	init_battery_gas_gauge();
 	HAL_Delay(10);
@@ -363,7 +363,7 @@
 	global.mode = MODE_POWERUP;
 #else
 	init_pressure();
-	init_surface_ring();
+	init_surface_ring(0);
 
 	ADCx_Init();
 	GPIO_Power_MainCPU_Init();
--- a/Small_CPU/Src/pressure.c	Sun Aug 04 11:01:06 2019 +0200
+++ b/Small_CPU/Src/pressure.c	Mon Aug 19 11:42:31 2019 +0000
@@ -46,9 +46,12 @@
 #define CMD_ADC_4096 0x08 // ADC OSR=4096
 #define CMD_PROM_RD 0xA0 // Prom read command
 
+#define PRESSURE_SURFACE_MAX_MBAR		(1070.0f)		/* It is very unlikely that pressure at surface is greater than this value => clip to it */
 #define PRESSURE_HISTORY_SIZE			(8u)
 #define PRESSURE_JUMP_VALID_MBAR	    (500.0f)		/* values are measure several times a second => jumps > 5m very unlikely */
 
+#define PRESSURE_SURFACE_QUE			(30u)			/* history buffer [minutes] for past pressure measurements */
+
 static uint16_t get_ci_by_coef_num(uint8_t coef_num);
 //void pressure_calculation_new(void);
 //void pressure_calculation_old(void);
@@ -75,15 +78,19 @@
 short UT1 = -1;
 short C6plus100 = -1;
 */
+static float pressure_offset = 0.0;		/* Offset value which may be specified by the user via PC Software */
+static float temperature_offset = 0.0;	/* Offset value which may be specified by the user via PC Software */
 
 static float ambient_temperature = 0;
 static float ambient_pressure_mbar = 1000.0;
 static float surface_pressure_mbar = 1000.0;
-static float surface_ring_mbar[31] = { 0 };
+static float surface_ring_mbar[PRESSURE_SURFACE_QUE] = { 0 };
 
 static float pressure_history_mbar[PRESSURE_HISTORY_SIZE];
 
-uint8_t secondCounterSurfaceRing = 0;
+static uint8_t secondCounterSurfaceRing = 0;
+static uint8_t avgCount = 0;
+static float runningAvg = 0;
 
 float get_temperature(void)
 {
@@ -101,12 +108,18 @@
 }
 
 
-void init_surface_ring(void)
+void init_surface_ring(uint8_t force)
 {
-	surface_ring_mbar[0] = 0;
-	for(int i=1; i<31; i++)
-		surface_ring_mbar[i] = ambient_pressure_mbar;
-	surface_pressure_mbar = ambient_pressure_mbar;
+	if((surface_ring_mbar[0] == 0) || (force))		/* only initialize once. Keep value in place in case of an i2c recovery */
+	{
+		secondCounterSurfaceRing = 0;				/* restart calculation */
+		avgCount = 0;
+		runningAvg = 0;
+
+		for(int i=0; i<PRESSURE_SURFACE_QUE; i++)
+			surface_ring_mbar[i] = ambient_pressure_mbar;
+		surface_pressure_mbar = ambient_pressure_mbar;
+	}
 }
 
 void init_pressure_history(void)
@@ -117,33 +130,40 @@
 	}
 }
 
-/* the ring has one place with 0
- * after that comes the oldest value
- * the new pressure is written in this hole
- * the oldest value is read and then the new hole
-*/
+
 void update_surface_pressure(uint8_t call_rhythm_seconds)
 {
-	secondCounterSurfaceRing += call_rhythm_seconds;
-	
-	if(secondCounterSurfaceRing < 60)
-		return;
-	
-	secondCounterSurfaceRing = 0;
-	
+	static uint8_t writeIndex = 0;		/* Reinitialization will reset all entries to the same value => no need to reinit write index */
+
+
 	if(is_init_pressure_done())
 	{
-		int hole;
-		for(hole=30;hole>0;hole--)
-			if(surface_ring_mbar[hole] == 0) { break; }
-
-		surface_ring_mbar[hole] = ambient_pressure_mbar;
+		runningAvg = (runningAvg * avgCount + ambient_pressure_mbar) / (avgCount +1);
+		avgCount++;
+		secondCounterSurfaceRing += call_rhythm_seconds;
 
-		hole++;
-		if(hole > 30)
-			hole = 0;
-		surface_pressure_mbar = surface_ring_mbar[hole];
-		surface_ring_mbar[hole] = 0;
+		if(secondCounterSurfaceRing >= 60)
+		{
+			if(runningAvg < PRESSURE_SURFACE_MAX_MBAR)
+			{
+				surface_ring_mbar[writeIndex] = runningAvg;
+			}
+			else
+			{
+				surface_ring_mbar[writeIndex] =	PRESSURE_SURFACE_MAX_MBAR;
+			}
+			writeIndex++; /* the write index is now pointing to the oldest value in the buffer which will be overwritten next time */
+
+			if(writeIndex == PRESSURE_SURFACE_QUE)
+			{
+				writeIndex = 0;
+			}
+
+			surface_pressure_mbar = surface_ring_mbar[writeIndex]; /* 30 minutes old measurement */
+
+			secondCounterSurfaceRing = 0;
+			avgCount = 1;	/* use the current value as starting point but restart the weight decrement of the measurements */
+		}
 	}
 }
 
@@ -427,7 +447,7 @@
 	pressure_average /= PRESSURE_HISTORY_SIZE;
 	if(pressure_average == 1000.0) /* first pressure calculation */
 	{
-		if(fabs(pressurevalue - pressure_average) < 11000.0)  /* just in case a reset occure during dive assume value equal < 100m as valid */
+		if(fabs(pressurevalue - pressure_average) < 11000.0)  /* just in case a reset occur during dive assume value equal < 100m as valid */
 		{
 			for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
 			{
@@ -439,9 +459,11 @@
 	else
 	{
 		if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR)
-		pressure_history_mbar[pressurewriteindex++] = pressurevalue;
-		pressurewriteindex &= 0x7;	/* wrap around if necessary */
-		retval = 1;
+		{
+			pressure_history_mbar[pressurewriteindex++] = pressurevalue;
+			pressurewriteindex &= 0x7;	/* wrap around if necessary */
+			retval = 1;
+		}
 	}
 
 	return retval;
@@ -449,6 +471,9 @@
 
 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void)
 {
+	static float runningAvg = 0;
+	static uint8_t avgCnt = 0;
+
 	uint32_t local_D1; // ADC value of the pressure conversion
 	uint32_t local_D2; // ADC value of the temperature conversion
 	int32_t local_Px10; // compensated pressure value
@@ -511,12 +536,20 @@
 							(((int64_t)((local_D1 * local_SENS) / 2097152)) - local_OFF)
 								/  8192 );//     )) / 10; // pow(2,21), pow(2,13)
 
-	ambient_temperature 	= ((float)local_Tx100) / 100;
+	ambient_temperature = ((float)local_Tx100) / 100;
+	ambient_temperature	+= temperature_offset;
 
 	calc_pressure = ((float)local_Px10) / 10;
+	calc_pressure += pressure_offset;
+
 	if(pressure_plausible(calc_pressure))
 	{
-		ambient_pressure_mbar = calc_pressure;
+		runningAvg = (avgCnt * runningAvg + calc_pressure) / (avgCnt + 1);
+		if (avgCnt < 10)	/* build an average considering the last measurements to have a weight "1 of 10" */
+		{					/* Main reason for this is the jitter of up to +-10 HPa in surface mode which is caused */
+			avgCnt++;		/* by the measurement range of the sensor which is focused on under water pressure measurement */
+		}
+		ambient_pressure_mbar = runningAvg;
 	}
 }
 
@@ -721,4 +754,17 @@
 		pressure_calculation() ;
 };
 */
+void pressure_set_offset (float pressureOffset, float temperatureOffset)
+{
+	if(pressure_offset != pressureOffset)				/* we received a new value => reinit surface que */
+	{
+		ambient_pressure_mbar -= pressure_offset;		/* revert old value */
+		ambient_pressure_mbar += pressureOffset;		/* apply new offset */
+		init_surface_ring(1);
+	}
 
+	pressure_offset = pressureOffset;
+	temperature_offset = temperatureOffset;
+}
+
+
--- a/Small_CPU/Src/scheduler.c	Sun Aug 04 11:01:06 2019 +0200
+++ b/Small_CPU/Src/scheduler.c	Mon Aug 19 11:42:31 2019 +0000
@@ -43,7 +43,9 @@
 #include "tm_stm32f4_otp.h"
 
 
-#define INVALID_PREASURE_VALUE (100.0F)
+#define INVALID_PREASURE_VALUE 			(100.0f)
+#define START_DIVE_MOUNTAIN_MODE_BAR	(0.88f)
+#define START_DIVE_IMMEDIATLY_BAR		(1.16f)
 
 /* Private types -------------------------------------------------------------*/
 const SGas Air = {79,0,0,0,0};
@@ -279,6 +281,10 @@
 	/* for simulation / testing */
 	global.ceiling_from_main_CPU_mbar	= global.dataSendToSlave.data.ambient_pressure_mbar_ceiling;
 	
+	/* Set pressure and temperature offsets */
+	pressure_set_offset (global.dataSendToSlave.data.offsetPressureSensor_mbar, global.dataSendToSlave.data.offsetTemperatureSensor_centiDegree);
+
+
 	/* for device data updates */
 	deviceDataFlashValid = 0;
 	memcpy(&DeviceDataFlash, &global.dataSendToSlave.data.DeviceData, sizeof(SDevice));
@@ -853,7 +859,7 @@
 					init_pressure();
 					if(is_init_pressure_done())		/* Init surface data with initial measurement */
 					{
-						init_surface_ring();
+						init_surface_ring(0);
 					}
 
 					if(!battery_gas_gauge_CheckConfigOK())
@@ -1045,9 +1051,11 @@
 			}
 		}
 
-		if (!is_ambient_pressure_close_to_surface(&global.lifeData))
+		if (((!is_ambient_pressure_close_to_surface(&global.lifeData)) && (global.lifeData.pressure_surface_bar > START_DIVE_MOUNTAIN_MODE_BAR ))
+				|| (global.lifeData.pressure_ambient_bar > START_DIVE_IMMEDIATLY_BAR))
+		{
 			global.mode = MODE_BOOT;
-
+		}
 		scheduleUpdateLifeData(2000);
 	}
 	while(global.mode == MODE_SLEEP);
@@ -1583,7 +1591,7 @@
 	{
 		return true;
 	}
-	if (lifeData->pressure_ambient_bar > 1.16)
+	if (lifeData->pressure_ambient_bar > START_DIVE_IMMEDIATLY_BAR)
 		return false;
 	else if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.1f)) // hw 161121 now 1 mter, before 0.04f
 		return true;