# HG changeset patch # User ideenmodellierer # Date 1563396231 -7200 # Node ID b4c578caaafbca55e9799dc9ede1fdac252490cb # Parent 2defc8cd93ce992d4d13760ee6101e2059d09d6f Added plausibility check for pressure values In case of I2C communication problems at startup the dc jumped into dive mode with depth up to 300m. As no CRC is applied a bit flip may also occure during normal operation without detection => added a plausibility check if last measured value fits to the last measurements diff -r 2defc8cd93ce -r b4c578caaafb Small_CPU/Src/pressure.c --- a/Small_CPU/Src/pressure.c Wed Jul 17 22:43:16 2019 +0200 +++ b/Small_CPU/Src/pressure.c Wed Jul 17 22:43:51 2019 +0200 @@ -28,7 +28,7 @@ the last 30 minutes will be saved once per minute in a endless loop at the beginning of a dive the oldest value will be used */ - +#include "math.h" #include "scheduler.h" #include "pressure.h" #include "i2c.h" @@ -46,6 +46,9 @@ #define CMD_ADC_4096 0x08 // ADC OSR=4096 #define CMD_PROM_RD 0xA0 // Prom read command +#define PRESSURE_HISTORY_SIZE (8u) +#define PRESSURE_JUMP_VALID_MBAR (500.0f) /* values are measure several times a second => jumps > 5m very unlikely */ + static uint16_t get_ci_by_coef_num(uint8_t coef_num); //void pressure_calculation_new(void); //void pressure_calculation_old(void); @@ -74,10 +77,12 @@ */ static float ambient_temperature = 0; -static float ambient_pressure_mbar = 0; -static float surface_pressure_mbar = 1000; +static float ambient_pressure_mbar = 1000.0; +static float surface_pressure_mbar = 1000.0; static float surface_ring_mbar[31] = { 0 }; +static float pressure_history_mbar[PRESSURE_HISTORY_SIZE]; + uint8_t secondCounterSurfaceRing = 0; float get_temperature(void) @@ -104,6 +109,13 @@ surface_pressure_mbar = ambient_pressure_mbar; } +void init_pressure_history(void) +{ + for(int i=0; i0;hole--) - if(surface_ring_mbar[hole] == 0) { break; } - - surface_ring_mbar[hole] = ambient_pressure_mbar; + if(is_init_pressure_done()) + { + int hole; + for(hole=30;hole>0;hole--) + if(surface_ring_mbar[hole] == 0) { break; } - hole++; - if(hole > 30) - hole = 0; - surface_pressure_mbar = surface_ring_mbar[hole]; - surface_ring_mbar[hole] = 0; + surface_ring_mbar[hole] = ambient_pressure_mbar; + + hole++; + if(hole > 30) + hole = 0; + surface_pressure_mbar = surface_ring_mbar[hole]; + surface_ring_mbar[hole] = 0; + } } #ifdef DEMOMODE @@ -209,29 +224,6 @@ } #endif - -/* called just once on power on */ -/* TBD old DR5 code? */ -void init_pressure_DRx(void) -{ - uint8_t resetCommand[1] = {0x1E}; - - I2C_Master_Transmit( DEVICE_PRESSURE, resetCommand, 1); - HAL_Delay(3); - - C[1] = get_ci_by_coef_num(0x02); - C[2] = get_ci_by_coef_num(0x04); - C[3] = get_ci_by_coef_num(0x06); - C[4] = get_ci_by_coef_num(0x08); - C[5] = get_ci_by_coef_num(0x0A); - C[6] = get_ci_by_coef_num(0x0C); - - C5_x_2p8 = C[5] * 256; - C2_x_2p16 = C[2] * 65536; - C1_x_2p15 = C[1] * 32768; - pressure_update(); -} - uint8_t is_init_pressure_done(void) { return pressureSensorInitSuccess; @@ -243,7 +235,10 @@ buffer[0] = 0x1e; uint8_t retValue = 0xFF; - + pressureSensorInitSuccess = false; + init_pressure_history(); + +/* Send reset request to pressure sensor */ retValue = I2C_Master_Transmit( DEVICE_PRESSURE, buffer, 1); if(retValue != HAL_OK) { @@ -264,8 +259,10 @@ if(global.I2C_SystemStatus == HAL_OK) { pressureSensorInitSuccess = 1; + retValue = pressure_update(); + } - return pressure_update(); + return retValue; } @@ -416,6 +413,40 @@ pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(); } +static uint8_t pressure_plausible(float pressurevalue) +{ + static uint8_t pressurewriteindex = 0; + uint8_t retval = 0; + uint8_t index; + float pressure_average = 0; + + for(index = 0; index < PRESSURE_HISTORY_SIZE; index++) + { + pressure_average += pressure_history_mbar[index]; + } + 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 */ + { + for(index = 0; index < PRESSURE_HISTORY_SIZE; index++) + { + pressure_history_mbar[index] = pressurevalue; /* set history to current value */ + retval = 1; + } + } + } + else + { + if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR) + pressure_history_mbar[pressurewriteindex++] = pressurevalue; + pressurewriteindex &= 0x7; /* wrap around if necessary */ + retval = 1; + } + + return retval; +} + static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) { uint32_t local_D1; // ADC value of the pressure conversion @@ -426,6 +457,8 @@ int64_t local_OFF; // offset at actual temperature int64_t local_SENS; // sensitivity at actual temperature + float calc_pressure; + int64_t T2; int64_t OFF2; int64_t SENS2; @@ -479,7 +512,12 @@ / 8192 );// )) / 10; // pow(2,21), pow(2,13) ambient_temperature = ((float)local_Tx100) / 100; - ambient_pressure_mbar = ((float)local_Px10) / 10; + + calc_pressure = ((float)local_Px10) / 10; + if(pressure_plausible(calc_pressure)) + { + ambient_pressure_mbar = calc_pressure; + } } diff -r 2defc8cd93ce -r b4c578caaafb Small_CPU/Src/scheduler.c --- a/Small_CPU/Src/scheduler.c Wed Jul 17 22:43:16 2019 +0200 +++ b/Small_CPU/Src/scheduler.c Wed Jul 17 22:43:51 2019 +0200 @@ -617,10 +617,7 @@ { MX_I2C1_TestAndClear(); MX_I2C1_Init(); - if(!is_init_pressure_done()) - { - init_pressure(); - } + init_pressure(); } } if(ticksdiff >= 1000) @@ -846,14 +843,23 @@ copyBatteryData(); copyDeviceData(); - // new hw 170523 +/* check if I2C is not up an running and try to reactivate if necessary. Also do initialization if problem occured during startup */ if(global.I2C_SystemStatus != HAL_OK) { MX_I2C1_TestAndClear(); MX_I2C1_Init(); - if(!is_init_pressure_done()) + if(global.I2C_SystemStatus == HAL_OK) { init_pressure(); + if(is_init_pressure_done()) /* Init surface data with initial measurement */ + { + init_surface_ring(); + } + + if(!battery_gas_gauge_CheckConfigOK()) + { + init_battery_gas_gauge(); + } } } } @@ -997,6 +1003,17 @@ MX_I2C1_Init(); pressure_sensor_get_pressure_raw(); +/* check if I2C is not up an running and try to reactivate if necessary. Also do initialization if problem occured during startup */ + if(global.I2C_SystemStatus != HAL_OK) + { + MX_I2C1_TestAndClear(); + MX_I2C1_Init(); + if(global.I2C_SystemStatus == HAL_OK) + { + init_pressure(); + } + } + if(secondsCount >= 30) { pressure_sensor_get_temperature_raw(); @@ -1562,6 +1579,10 @@ /* same as in data_central.c */ _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData) { + if(lifeData->pressure_ambient_bar == INVALID_PREASURE_VALUE) /* as long as no valid data is available expect we are close to surface */ + { + return true; + } if (lifeData->pressure_ambient_bar > 1.16) return false; else if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.1f)) // hw 161121 now 1 mter, before 0.04f