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