diff Small_CPU/Src/pressure.c @ 372:75eedde05ff6 MotionDetection

merged default into MotionDetection
author Ideenmodellierer
date Mon, 19 Aug 2019 17:50:55 +0200
parents 37f45300bc2e
children 591c03a1e68d 4093ac18b25c
line wrap: on
line diff
--- a/Small_CPU/Src/pressure.c	Mon Aug 19 17:39:47 2019 +0200
+++ b/Small_CPU/Src/pressure.c	Mon Aug 19 17:50:55 2019 +0200
@@ -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;
+}
+
+