Mercurial > public > ostc4
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) |