comparison Small_CPU/Src/pressure.c @ 331:b4c578caaafb I2C_Improvment

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
author ideenmodellierer
date Wed, 17 Jul 2019 22:43:51 +0200
parents 8e9c502c0b06
children c11ce8c885d3
comparison
equal deleted inserted replaced
330:2defc8cd93ce 331:b4c578caaafb
26 26
27 /* surface time 27 /* surface time
28 the last 30 minutes will be saved once per minute in a endless loop 28 the last 30 minutes will be saved once per minute in a endless loop
29 at the beginning of a dive the oldest value will be used 29 at the beginning of a dive the oldest value will be used
30 */ 30 */
31 31 #include "math.h"
32 #include "scheduler.h" 32 #include "scheduler.h"
33 #include "pressure.h" 33 #include "pressure.h"
34 #include "i2c.h" 34 #include "i2c.h"
35 #include "rtc.h" 35 #include "rtc.h"
36 36
44 #define CMD_ADC_1024 0x04 // ADC OSR=1024 44 #define CMD_ADC_1024 0x04 // ADC OSR=1024
45 #define CMD_ADC_2048 0x06 // ADC OSR=2056 45 #define CMD_ADC_2048 0x06 // ADC OSR=2056
46 #define CMD_ADC_4096 0x08 // ADC OSR=4096 46 #define CMD_ADC_4096 0x08 // ADC OSR=4096
47 #define CMD_PROM_RD 0xA0 // Prom read command 47 #define CMD_PROM_RD 0xA0 // Prom read command
48 48
49 #define PRESSURE_HISTORY_SIZE (8u)
50 #define PRESSURE_JUMP_VALID_MBAR (500.0f) /* values are measure several times a second => jumps > 5m very unlikely */
51
49 static uint16_t get_ci_by_coef_num(uint8_t coef_num); 52 static uint16_t get_ci_by_coef_num(uint8_t coef_num);
50 //void pressure_calculation_new(void); 53 //void pressure_calculation_new(void);
51 //void pressure_calculation_old(void); 54 //void pressure_calculation_old(void);
52 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void); 55 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void);
53 static uint8_t crc4(uint16_t n_prom[]); 56 static uint8_t crc4(uint16_t n_prom[]);
72 short UT1 = -1; 75 short UT1 = -1;
73 short C6plus100 = -1; 76 short C6plus100 = -1;
74 */ 77 */
75 78
76 static float ambient_temperature = 0; 79 static float ambient_temperature = 0;
77 static float ambient_pressure_mbar = 0; 80 static float ambient_pressure_mbar = 1000.0;
78 static float surface_pressure_mbar = 1000; 81 static float surface_pressure_mbar = 1000.0;
79 static float surface_ring_mbar[31] = { 0 }; 82 static float surface_ring_mbar[31] = { 0 };
83
84 static float pressure_history_mbar[PRESSURE_HISTORY_SIZE];
80 85
81 uint8_t secondCounterSurfaceRing = 0; 86 uint8_t secondCounterSurfaceRing = 0;
82 87
83 float get_temperature(void) 88 float get_temperature(void)
84 { 89 {
102 for(int i=1; i<31; i++) 107 for(int i=1; i<31; i++)
103 surface_ring_mbar[i] = ambient_pressure_mbar; 108 surface_ring_mbar[i] = ambient_pressure_mbar;
104 surface_pressure_mbar = ambient_pressure_mbar; 109 surface_pressure_mbar = ambient_pressure_mbar;
105 } 110 }
106 111
112 void init_pressure_history(void)
113 {
114 for(int i=0; i<PRESSURE_HISTORY_SIZE; i++)
115 {
116 pressure_history_mbar[i] = 1000.0;
117 }
118 }
107 119
108 /* the ring has one place with 0 120 /* the ring has one place with 0
109 * after that comes the oldest value 121 * after that comes the oldest value
110 * the new pressure is written in this hole 122 * the new pressure is written in this hole
111 * the oldest value is read and then the new hole 123 * the oldest value is read and then the new hole
117 if(secondCounterSurfaceRing < 60) 129 if(secondCounterSurfaceRing < 60)
118 return; 130 return;
119 131
120 secondCounterSurfaceRing = 0; 132 secondCounterSurfaceRing = 0;
121 133
122 int hole; 134 if(is_init_pressure_done())
123 for(hole=30;hole>0;hole--) 135 {
124 if(surface_ring_mbar[hole] == 0) { break; } 136 int hole;
125 137 for(hole=30;hole>0;hole--)
126 surface_ring_mbar[hole] = ambient_pressure_mbar; 138 if(surface_ring_mbar[hole] == 0) { break; }
127 139
128 hole++; 140 surface_ring_mbar[hole] = ambient_pressure_mbar;
129 if(hole > 30) 141
130 hole = 0; 142 hole++;
131 surface_pressure_mbar = surface_ring_mbar[hole]; 143 if(hole > 30)
132 surface_ring_mbar[hole] = 0; 144 hole = 0;
145 surface_pressure_mbar = surface_ring_mbar[hole];
146 surface_ring_mbar[hole] = 0;
147 }
133 } 148 }
134 149
135 #ifdef DEMOMODE 150 #ifdef DEMOMODE
136 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface) 151 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface)
137 { 152 {
207 return 0; 222 return 0;
208 } 223 }
209 } 224 }
210 #endif 225 #endif
211 226
212 227 uint8_t is_init_pressure_done(void)
213 /* called just once on power on */ 228 {
214 /* TBD old DR5 code? */ 229 return pressureSensorInitSuccess;
215 void init_pressure_DRx(void) 230 }
216 { 231
217 uint8_t resetCommand[1] = {0x1E}; 232 uint8_t init_pressure(void)
218 233 {
219 I2C_Master_Transmit( DEVICE_PRESSURE, resetCommand, 1); 234 uint8_t buffer[1];
235 buffer[0] = 0x1e;
236 uint8_t retValue = 0xFF;
237
238 pressureSensorInitSuccess = false;
239 init_pressure_history();
240
241 /* Send reset request to pressure sensor */
242 retValue = I2C_Master_Transmit( DEVICE_PRESSURE, buffer, 1);
243 if(retValue != HAL_OK)
244 {
245 return (HAL_StatusTypeDef)retValue;
246 }
220 HAL_Delay(3); 247 HAL_Delay(3);
221 248
222 C[1] = get_ci_by_coef_num(0x02); 249 for(uint8_t i=0;i<8;i++)
223 C[2] = get_ci_by_coef_num(0x04); 250 {
224 C[3] = get_ci_by_coef_num(0x06); 251 C[i] = get_ci_by_coef_num(i);
225 C[4] = get_ci_by_coef_num(0x08); 252 }
226 C[5] = get_ci_by_coef_num(0x0A); 253 n_crc = crc4(C); // no evaluation at the moment hw 151026
227 C[6] = get_ci_by_coef_num(0x0C); 254
228
229 C5_x_2p8 = C[5] * 256; 255 C5_x_2p8 = C[5] * 256;
230 C2_x_2p16 = C[2] * 65536; 256 C2_x_2p16 = C[2] * 65536;
231 C1_x_2p15 = C[1] * 32768; 257 C1_x_2p15 = C[1] * 32768;
232 pressure_update();
233 }
234
235 uint8_t is_init_pressure_done(void)
236 {
237 return pressureSensorInitSuccess;
238 }
239
240 uint8_t init_pressure(void)
241 {
242 uint8_t buffer[1];
243 buffer[0] = 0x1e;
244 uint8_t retValue = 0xFF;
245
246
247 retValue = I2C_Master_Transmit( DEVICE_PRESSURE, buffer, 1);
248 if(retValue != HAL_OK)
249 {
250 return (HAL_StatusTypeDef)retValue;
251 }
252 HAL_Delay(3);
253
254 for(uint8_t i=0;i<8;i++)
255 {
256 C[i] = get_ci_by_coef_num(i);
257 }
258 n_crc = crc4(C); // no evaluation at the moment hw 151026
259
260 C5_x_2p8 = C[5] * 256;
261 C2_x_2p16 = C[2] * 65536;
262 C1_x_2p15 = C[1] * 32768;
263 258
264 if(global.I2C_SystemStatus == HAL_OK) 259 if(global.I2C_SystemStatus == HAL_OK)
265 { 260 {
266 pressureSensorInitSuccess = 1; 261 pressureSensorInitSuccess = 1;
267 } 262 retValue = pressure_update();
268 return pressure_update(); 263
264 }
265 return retValue;
269 } 266 }
270 267
271 268
272 static uint32_t get_adc(void) 269 static uint32_t get_adc(void)
273 { 270 {
414 return; 411 return;
415 412
416 pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(); 413 pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015();
417 } 414 }
418 415
416 static uint8_t pressure_plausible(float pressurevalue)
417 {
418 static uint8_t pressurewriteindex = 0;
419 uint8_t retval = 0;
420 uint8_t index;
421 float pressure_average = 0;
422
423 for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
424 {
425 pressure_average += pressure_history_mbar[index];
426 }
427 pressure_average /= PRESSURE_HISTORY_SIZE;
428 if(pressure_average == 1000.0) /* first pressure calculation */
429 {
430 if(fabs(pressurevalue - pressure_average) < 11000.0) /* just in case a reset occure during dive assume value equal < 100m as valid */
431 {
432 for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
433 {
434 pressure_history_mbar[index] = pressurevalue; /* set history to current value */
435 retval = 1;
436 }
437 }
438 }
439 else
440 {
441 if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR)
442 pressure_history_mbar[pressurewriteindex++] = pressurevalue;
443 pressurewriteindex &= 0x7; /* wrap around if necessary */
444 retval = 1;
445 }
446
447 return retval;
448 }
449
419 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) 450 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void)
420 { 451 {
421 uint32_t local_D1; // ADC value of the pressure conversion 452 uint32_t local_D1; // ADC value of the pressure conversion
422 uint32_t local_D2; // ADC value of the temperature conversion 453 uint32_t local_D2; // ADC value of the temperature conversion
423 int32_t local_Px10; // compensated pressure value 454 int32_t local_Px10; // compensated pressure value
424 int32_t local_Tx100; // compensated temperature value 455 int32_t local_Tx100; // compensated temperature value
425 int64_t local_dT; // int32_t, difference between actual and measured temperature 456 int64_t local_dT; // int32_t, difference between actual and measured temperature
426 int64_t local_OFF; // offset at actual temperature 457 int64_t local_OFF; // offset at actual temperature
427 int64_t local_SENS; // sensitivity at actual temperature 458 int64_t local_SENS; // sensitivity at actual temperature
459
460 float calc_pressure;
428 461
429 int64_t T2; 462 int64_t T2;
430 int64_t OFF2; 463 int64_t OFF2;
431 int64_t SENS2; 464 int64_t SENS2;
432 465
477 local_Px10 = (int32_t)( 510 local_Px10 = (int32_t)(
478 (((int64_t)((local_D1 * local_SENS) / 2097152)) - local_OFF) 511 (((int64_t)((local_D1 * local_SENS) / 2097152)) - local_OFF)
479 / 8192 );// )) / 10; // pow(2,21), pow(2,13) 512 / 8192 );// )) / 10; // pow(2,21), pow(2,13)
480 513
481 ambient_temperature = ((float)local_Tx100) / 100; 514 ambient_temperature = ((float)local_Tx100) / 100;
482 ambient_pressure_mbar = ((float)local_Px10) / 10; 515
516 calc_pressure = ((float)local_Px10) / 10;
517 if(pressure_plausible(calc_pressure))
518 {
519 ambient_pressure_mbar = calc_pressure;
520 }
483 } 521 }
484 522
485 523
486 /* 524 /*
487 void pressure_calculation_new(void) 525 void pressure_calculation_new(void)