changeset 634:7c73f066cd16

Enable sensor check for Analog PPO2 mode: Checks which may trigger a fallback warning were not activated in previous versions. Beside enabling the checks the test logic has been changed. Before the change an avarage was build automatically using the remaining both sensors if one sensor failed. The scenario that also one of the remaining sensors may be out of bounds was not covered. The new implementation allows an out of bounds detection for all sensors in parallel. In that special case the last valid value will be used until the diver takes action (Fallback warning)
author Ideenmodellierer
date Wed, 24 Feb 2021 19:18:26 +0100
parents 68d95049f11a
children 66c8a4ff9fc4
files Discovery/Src/check_warning.c Discovery/Src/tCCR.c
diffstat 2 files changed, 52 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/Discovery/Src/check_warning.c	Tue Feb 23 21:58:18 2021 +0100
+++ b/Discovery/Src/check_warning.c	Wed Feb 24 19:18:26 2021 +0100
@@ -184,8 +184,8 @@
 				if(!get_HUD_battery_voltage_V())
 					pDiveState->warnings.sensorLinkLost = 1;
 			}
-			test_O2_sensor_values_outOfBounds(&pDiveState->warnings.sensorOutOfBounds[0], &pDiveState->warnings.sensorOutOfBounds[1], &pDiveState->warnings.sensorOutOfBounds[2]);
 		}
+	test_O2_sensor_values_outOfBounds(&pDiveState->warnings.sensorOutOfBounds[0], &pDiveState->warnings.sensorOutOfBounds[1], &pDiveState->warnings.sensorOutOfBounds[2]);
 	return 		pDiveState->warnings.sensorLinkLost
 					+ pDiveState->warnings.sensorOutOfBounds[0]
 					+ pDiveState->warnings.sensorOutOfBounds[1]
--- a/Discovery/Src/tCCR.c	Tue Feb 23 21:58:18 2021 +0100
+++ b/Discovery/Src/tCCR.c	Wed Feb 24 19:18:26 2021 +0100
@@ -34,6 +34,7 @@
 #include "data_exchange.h"
 #include "check_warning.h"
 #include "configuration.h"
+#include <math.h>
 
 /* Private types -------------------------------------------------------------*/
 typedef struct
@@ -47,6 +48,14 @@
     uint16_t checksum;
 } 	SIrLink;
 
+typedef enum
+{
+	sensorOK = 0,
+	sensorSuspect,
+	SensorOutOfBounds
+} sensorTrustState_t;
+
+
 #define HUD_BABBLING_IDIOT			(30u)		/* 30 Bytes received without break */
 #define HUD_RX_FRAME_LENGTH			(15u)		/* Length of a HUD data frame */
 #define HUD_RX_FRAME_BREAK_MS		(100u)		/* Time used to detect a gap between two byte receptions => frame start */
@@ -55,6 +64,8 @@
 
 #define BOTTLE_SENSOR_TIMEOUT		(6000u)     /* signal pressure budget as not received after 10 minutes (6000 * 100ms) */
 
+#define MAX_SENSOR_COMPARE_DEVIATION (0.15f)	/* max deviation between two sensors allowed before their results are rated as suspect */
+
 /* Private variables ---------------------------------------------------------*/
 static SIrLink receiveHUD[2];
 static uint8_t boolHUDdata = 0;
@@ -132,6 +143,9 @@
 {
     uint8_t sensorNotActiveBinary;
     uint8_t sensorActive[3];
+    sensorTrustState_t sensorState[3];
+    uint8_t index;
+
 
     // test1: user deactivation
     sensorNotActiveBinary = stateUsed->diveSettings.ppo2sensors_deactivated;
@@ -154,6 +168,8 @@
     // test2: mV of remaining sensors
     for(int i=0;i<3;i++)
     {
+    	sensorState[i] = sensorOK;
+
         if(sensorActive[i])
         {
             if(	(stateUsed->lifeData.sensorVoltage_mV[i] < 8) ||
@@ -196,78 +212,50 @@
     }
     else
     {
-        uint8_t sensor_id_ordered[3];
-        float difference[2];
-
-        if((stateUsed->lifeData.ppO2Sensor_bar[1] > stateUsed->lifeData.ppO2Sensor_bar[0]))
-        {
-            sensor_id_ordered[0] = 0;
-            sensor_id_ordered[1] = 1;
-        }
-        else
-        {
-            sensor_id_ordered[0] = 1;
-            sensor_id_ordered[1] = 0;
-        }
-        if(stateUsed->lifeData.ppO2Sensor_bar[2] > stateUsed->lifeData.ppO2Sensor_bar[sensor_id_ordered[1]])
+    	/* Check two or more of Three */
+        /* compare every sensor with each other. If there is only one mismatch the value might be OK. In case both comparisons fail the sensor is out of bounds */
+        if(fabsf(stateUsed->lifeData.ppO2Sensor_bar[0] - stateUsed->lifeData.ppO2Sensor_bar[1]) > MAX_SENSOR_COMPARE_DEVIATION)
         {
-            sensor_id_ordered[2] = 2;
+        	sensorState[0]++;
+        	sensorState[1]++;
         }
-        else
+        if(fabsf(stateUsed->lifeData.ppO2Sensor_bar[0] - stateUsed->lifeData.ppO2Sensor_bar[2]) > MAX_SENSOR_COMPARE_DEVIATION)
         {
-            sensor_id_ordered[2] = sensor_id_ordered[1];
-            if(stateUsed->lifeData.ppO2Sensor_bar[2] > stateUsed->lifeData.ppO2Sensor_bar[sensor_id_ordered[0]])
-            {
-                sensor_id_ordered[1] = 2;
-            }
-            else
-            {
-                sensor_id_ordered[1] = sensor_id_ordered[0];
-                sensor_id_ordered[0] = 2;
-            }
+        	sensorState[0]++;
+        	sensorState[2]++;
+        }
+        if(fabsf(stateUsed->lifeData.ppO2Sensor_bar[1] - stateUsed->lifeData.ppO2Sensor_bar[2]) > MAX_SENSOR_COMPARE_DEVIATION)
+        {
+        	sensorState[1]++;
+        	sensorState[2]++;
         }
-
-        difference[0] = stateUsed->lifeData.ppO2Sensor_bar[sensor_id_ordered[1]]- stateUsed->lifeData.ppO2Sensor_bar[sensor_id_ordered[0]];
-        difference[1] = stateUsed->lifeData.ppO2Sensor_bar[sensor_id_ordered[2]]- stateUsed->lifeData.ppO2Sensor_bar[sensor_id_ordered[1]];
-
-        if((difference[0] > difference[1]) && (difference[0] > 0.15))		/* was 15cBar ==> 0.15 bar */
+        for(index = 0; index < 3; index++)
         {
-            switch(sensor_id_ordered[0])
-            {
-            case 0:
-                *outOfBouds1 = 1;
-            break;
-            case 1:
-                *outOfBouds2 = 1;
-            break;
-            case 2:
-                *outOfBouds3 = 1;
-            break;
-            }
-        }
-        else
-        if((difference[0] < difference[1]) && (difference[1] > 0.15))
-        {
-            switch(sensor_id_ordered[2])
-            {
-            case 0:
-                *outOfBouds1 = 1;
-            break;
-            case 1:
-                *outOfBouds2 = 1;
-            break;
-            case 2:
-                *outOfBouds3 = 1;
-            break;
-            }
+        	if(sensorState[index] == SensorOutOfBounds)
+        	{
+				switch(index)
+				{
+					case 0:
+						*outOfBouds1 = 1;
+						break;
+					case 1:
+						*outOfBouds2 = 1;
+						break;
+					case 2:
+						*outOfBouds3 = 1;
+						break;
+					default:
+						break;
+				}
+        	}
         }
     }
-
 }
 
 
 uint8_t get_ppO2SensorWeightedResult_cbar(void)
 {
+	static uint8_t lastValidValue = 0;
     int8_t sensorOutOfBound[3];
     uint16_t result = 0;
     uint8_t count = 0;
@@ -283,13 +271,15 @@
             count++;
         }
     }
-    if(count == 0) // all sensors out of bounds!
+    if(count == 0) /* all sensors out of bounds! => return last valid value as workaround till diver takes action */
     {
     	set_warning_fallback();
+    	retVal = lastValidValue;
     }
     else
     {
        retVal = (uint8_t)(result / count);
+       lastValidValue = retVal;
     }
     return retVal;
 }