Mercurial > public > ostc4
comparison 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 |
comparison
equal
deleted
inserted
replaced
371:fca370f847f8 | 372:75eedde05ff6 |
---|---|
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_SURFACE_MAX_MBAR (1070.0f) /* It is very unlikely that pressure at surface is greater than this value => clip to it */ | |
49 #define PRESSURE_HISTORY_SIZE (8u) | 50 #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 #define PRESSURE_JUMP_VALID_MBAR (500.0f) /* values are measure several times a second => jumps > 5m very unlikely */ |
52 | |
53 #define PRESSURE_SURFACE_QUE (30u) /* history buffer [minutes] for past pressure measurements */ | |
51 | 54 |
52 static uint16_t get_ci_by_coef_num(uint8_t coef_num); | 55 static uint16_t get_ci_by_coef_num(uint8_t coef_num); |
53 //void pressure_calculation_new(void); | 56 //void pressure_calculation_new(void); |
54 //void pressure_calculation_old(void); | 57 //void pressure_calculation_old(void); |
55 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void); | 58 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void); |
73 short C3plus200 = -1; | 76 short C3plus200 = -1; |
74 short C4minus250 = -1; | 77 short C4minus250 = -1; |
75 short UT1 = -1; | 78 short UT1 = -1; |
76 short C6plus100 = -1; | 79 short C6plus100 = -1; |
77 */ | 80 */ |
81 static float pressure_offset = 0.0; /* Offset value which may be specified by the user via PC Software */ | |
82 static float temperature_offset = 0.0; /* Offset value which may be specified by the user via PC Software */ | |
78 | 83 |
79 static float ambient_temperature = 0; | 84 static float ambient_temperature = 0; |
80 static float ambient_pressure_mbar = 1000.0; | 85 static float ambient_pressure_mbar = 1000.0; |
81 static float surface_pressure_mbar = 1000.0; | 86 static float surface_pressure_mbar = 1000.0; |
82 static float surface_ring_mbar[31] = { 0 }; | 87 static float surface_ring_mbar[PRESSURE_SURFACE_QUE] = { 0 }; |
83 | 88 |
84 static float pressure_history_mbar[PRESSURE_HISTORY_SIZE]; | 89 static float pressure_history_mbar[PRESSURE_HISTORY_SIZE]; |
85 | 90 |
86 uint8_t secondCounterSurfaceRing = 0; | 91 static uint8_t secondCounterSurfaceRing = 0; |
92 static uint8_t avgCount = 0; | |
93 static float runningAvg = 0; | |
87 | 94 |
88 float get_temperature(void) | 95 float get_temperature(void) |
89 { | 96 { |
90 return ambient_temperature; | 97 return ambient_temperature; |
91 } | 98 } |
99 { | 106 { |
100 return surface_pressure_mbar; | 107 return surface_pressure_mbar; |
101 } | 108 } |
102 | 109 |
103 | 110 |
104 void init_surface_ring(void) | 111 void init_surface_ring(uint8_t force) |
105 { | 112 { |
106 surface_ring_mbar[0] = 0; | 113 if((surface_ring_mbar[0] == 0) || (force)) /* only initialize once. Keep value in place in case of an i2c recovery */ |
107 for(int i=1; i<31; i++) | 114 { |
108 surface_ring_mbar[i] = ambient_pressure_mbar; | 115 secondCounterSurfaceRing = 0; /* restart calculation */ |
109 surface_pressure_mbar = ambient_pressure_mbar; | 116 avgCount = 0; |
117 runningAvg = 0; | |
118 | |
119 for(int i=0; i<PRESSURE_SURFACE_QUE; i++) | |
120 surface_ring_mbar[i] = ambient_pressure_mbar; | |
121 surface_pressure_mbar = ambient_pressure_mbar; | |
122 } | |
110 } | 123 } |
111 | 124 |
112 void init_pressure_history(void) | 125 void init_pressure_history(void) |
113 { | 126 { |
114 for(int i=0; i<PRESSURE_HISTORY_SIZE; i++) | 127 for(int i=0; i<PRESSURE_HISTORY_SIZE; i++) |
115 { | 128 { |
116 pressure_history_mbar[i] = 1000.0; | 129 pressure_history_mbar[i] = 1000.0; |
117 } | 130 } |
118 } | 131 } |
119 | 132 |
120 /* the ring has one place with 0 | 133 |
121 * after that comes the oldest value | |
122 * the new pressure is written in this hole | |
123 * the oldest value is read and then the new hole | |
124 */ | |
125 void update_surface_pressure(uint8_t call_rhythm_seconds) | 134 void update_surface_pressure(uint8_t call_rhythm_seconds) |
126 { | 135 { |
127 secondCounterSurfaceRing += call_rhythm_seconds; | 136 static uint8_t writeIndex = 0; /* Reinitialization will reset all entries to the same value => no need to reinit write index */ |
128 | 137 |
129 if(secondCounterSurfaceRing < 60) | 138 |
130 return; | |
131 | |
132 secondCounterSurfaceRing = 0; | |
133 | |
134 if(is_init_pressure_done()) | 139 if(is_init_pressure_done()) |
135 { | 140 { |
136 int hole; | 141 runningAvg = (runningAvg * avgCount + ambient_pressure_mbar) / (avgCount +1); |
137 for(hole=30;hole>0;hole--) | 142 avgCount++; |
138 if(surface_ring_mbar[hole] == 0) { break; } | 143 secondCounterSurfaceRing += call_rhythm_seconds; |
139 | 144 |
140 surface_ring_mbar[hole] = ambient_pressure_mbar; | 145 if(secondCounterSurfaceRing >= 60) |
141 | 146 { |
142 hole++; | 147 if(runningAvg < PRESSURE_SURFACE_MAX_MBAR) |
143 if(hole > 30) | 148 { |
144 hole = 0; | 149 surface_ring_mbar[writeIndex] = runningAvg; |
145 surface_pressure_mbar = surface_ring_mbar[hole]; | 150 } |
146 surface_ring_mbar[hole] = 0; | 151 else |
152 { | |
153 surface_ring_mbar[writeIndex] = PRESSURE_SURFACE_MAX_MBAR; | |
154 } | |
155 writeIndex++; /* the write index is now pointing to the oldest value in the buffer which will be overwritten next time */ | |
156 | |
157 if(writeIndex == PRESSURE_SURFACE_QUE) | |
158 { | |
159 writeIndex = 0; | |
160 } | |
161 | |
162 surface_pressure_mbar = surface_ring_mbar[writeIndex]; /* 30 minutes old measurement */ | |
163 | |
164 secondCounterSurfaceRing = 0; | |
165 avgCount = 1; /* use the current value as starting point but restart the weight decrement of the measurements */ | |
166 } | |
147 } | 167 } |
148 } | 168 } |
149 | 169 |
150 #ifdef DEMOMODE | 170 #ifdef DEMOMODE |
151 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface) | 171 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface) |
425 pressure_average += pressure_history_mbar[index]; | 445 pressure_average += pressure_history_mbar[index]; |
426 } | 446 } |
427 pressure_average /= PRESSURE_HISTORY_SIZE; | 447 pressure_average /= PRESSURE_HISTORY_SIZE; |
428 if(pressure_average == 1000.0) /* first pressure calculation */ | 448 if(pressure_average == 1000.0) /* first pressure calculation */ |
429 { | 449 { |
430 if(fabs(pressurevalue - pressure_average) < 11000.0) /* just in case a reset occure during dive assume value equal < 100m as valid */ | 450 if(fabs(pressurevalue - pressure_average) < 11000.0) /* just in case a reset occur during dive assume value equal < 100m as valid */ |
431 { | 451 { |
432 for(index = 0; index < PRESSURE_HISTORY_SIZE; index++) | 452 for(index = 0; index < PRESSURE_HISTORY_SIZE; index++) |
433 { | 453 { |
434 pressure_history_mbar[index] = pressurevalue; /* set history to current value */ | 454 pressure_history_mbar[index] = pressurevalue; /* set history to current value */ |
435 retval = 1; | 455 retval = 1; |
437 } | 457 } |
438 } | 458 } |
439 else | 459 else |
440 { | 460 { |
441 if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR) | 461 if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR) |
442 pressure_history_mbar[pressurewriteindex++] = pressurevalue; | 462 { |
443 pressurewriteindex &= 0x7; /* wrap around if necessary */ | 463 pressure_history_mbar[pressurewriteindex++] = pressurevalue; |
444 retval = 1; | 464 pressurewriteindex &= 0x7; /* wrap around if necessary */ |
465 retval = 1; | |
466 } | |
445 } | 467 } |
446 | 468 |
447 return retval; | 469 return retval; |
448 } | 470 } |
449 | 471 |
450 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) | 472 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) |
451 { | 473 { |
474 static float runningAvg = 0; | |
475 static uint8_t avgCnt = 0; | |
476 | |
452 uint32_t local_D1; // ADC value of the pressure conversion | 477 uint32_t local_D1; // ADC value of the pressure conversion |
453 uint32_t local_D2; // ADC value of the temperature conversion | 478 uint32_t local_D2; // ADC value of the temperature conversion |
454 int32_t local_Px10; // compensated pressure value | 479 int32_t local_Px10; // compensated pressure value |
455 int32_t local_Tx100; // compensated temperature value | 480 int32_t local_Tx100; // compensated temperature value |
456 int64_t local_dT; // int32_t, difference between actual and measured temperature | 481 int64_t local_dT; // int32_t, difference between actual and measured temperature |
509 | 534 |
510 local_Px10 = (int32_t)( | 535 local_Px10 = (int32_t)( |
511 (((int64_t)((local_D1 * local_SENS) / 2097152)) - local_OFF) | 536 (((int64_t)((local_D1 * local_SENS) / 2097152)) - local_OFF) |
512 / 8192 );// )) / 10; // pow(2,21), pow(2,13) | 537 / 8192 );// )) / 10; // pow(2,21), pow(2,13) |
513 | 538 |
514 ambient_temperature = ((float)local_Tx100) / 100; | 539 ambient_temperature = ((float)local_Tx100) / 100; |
540 ambient_temperature += temperature_offset; | |
515 | 541 |
516 calc_pressure = ((float)local_Px10) / 10; | 542 calc_pressure = ((float)local_Px10) / 10; |
543 calc_pressure += pressure_offset; | |
544 | |
517 if(pressure_plausible(calc_pressure)) | 545 if(pressure_plausible(calc_pressure)) |
518 { | 546 { |
519 ambient_pressure_mbar = calc_pressure; | 547 runningAvg = (avgCnt * runningAvg + calc_pressure) / (avgCnt + 1); |
548 if (avgCnt < 10) /* build an average considering the last measurements to have a weight "1 of 10" */ | |
549 { /* Main reason for this is the jitter of up to +-10 HPa in surface mode which is caused */ | |
550 avgCnt++; /* by the measurement range of the sensor which is focused on under water pressure measurement */ | |
551 } | |
552 ambient_pressure_mbar = runningAvg; | |
520 } | 553 } |
521 } | 554 } |
522 | 555 |
523 | 556 |
524 /* | 557 /* |
719 D1 = 4944364; | 752 D1 = 4944364; |
720 D2 = 8198974; | 753 D2 = 8198974; |
721 pressure_calculation() ; | 754 pressure_calculation() ; |
722 }; | 755 }; |
723 */ | 756 */ |
724 | 757 void pressure_set_offset (float pressureOffset, float temperatureOffset) |
758 { | |
759 if(pressure_offset != pressureOffset) /* we received a new value => reinit surface que */ | |
760 { | |
761 ambient_pressure_mbar -= pressure_offset; /* revert old value */ | |
762 ambient_pressure_mbar += pressureOffset; /* apply new offset */ | |
763 init_surface_ring(1); | |
764 } | |
765 | |
766 pressure_offset = pressureOffset; | |
767 temperature_offset = temperatureOffset; | |
768 } | |
769 | |
770 |