Mercurial > public > ostc4
comparison Small_CPU/Src/pressure.c @ 335:c11ce8c885d3 PressureMeasure_Improvment
Use average calculation for pressure: precondition was that pressure values jittered +- 10 HPa from one capture (once a second) to the other. Basically pressure is measured several times a second => using these values in an additional history calculation reduces the jitter down to +-1 per second
Additionaly a similar function has been added to the surface pressure capture to further reduce the jitter in long therm measurements (once a minute)
author | ideenmodellierer |
---|---|
date | Tue, 13 Aug 2019 21:46:26 +0200 |
parents | b4c578caaafb |
children | 37f45300bc2e |
comparison
equal
deleted
inserted
replaced
334:143fe85f82a2 | 335:c11ce8c885d3 |
---|---|
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) | 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 */ | 50 #define PRESSURE_JUMP_VALID_MBAR (500.0f) /* values are measure several times a second => jumps > 5m very unlikely */ |
51 | 51 |
52 #define PRESSURE_SURFACE_QUE (30u) /* history buffer [minutes] for past pressure measurements */ | |
53 | |
52 static uint16_t get_ci_by_coef_num(uint8_t coef_num); | 54 static uint16_t get_ci_by_coef_num(uint8_t coef_num); |
53 //void pressure_calculation_new(void); | 55 //void pressure_calculation_new(void); |
54 //void pressure_calculation_old(void); | 56 //void pressure_calculation_old(void); |
55 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void); | 57 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void); |
56 static uint8_t crc4(uint16_t n_prom[]); | 58 static uint8_t crc4(uint16_t n_prom[]); |
77 */ | 79 */ |
78 | 80 |
79 static float ambient_temperature = 0; | 81 static float ambient_temperature = 0; |
80 static float ambient_pressure_mbar = 1000.0; | 82 static float ambient_pressure_mbar = 1000.0; |
81 static float surface_pressure_mbar = 1000.0; | 83 static float surface_pressure_mbar = 1000.0; |
82 static float surface_ring_mbar[31] = { 0 }; | 84 static float surface_ring_mbar[PRESSURE_SURFACE_QUE] = { 0 }; |
83 | 85 |
84 static float pressure_history_mbar[PRESSURE_HISTORY_SIZE]; | 86 static float pressure_history_mbar[PRESSURE_HISTORY_SIZE]; |
85 | 87 |
86 uint8_t secondCounterSurfaceRing = 0; | 88 uint8_t secondCounterSurfaceRing = 0; |
87 | 89 |
101 } | 103 } |
102 | 104 |
103 | 105 |
104 void init_surface_ring(void) | 106 void init_surface_ring(void) |
105 { | 107 { |
106 surface_ring_mbar[0] = 0; | 108 if(surface_ring_mbar[0] == 0) /* only initialize once. Keep value in place in case of an i2c recovery */ |
107 for(int i=1; i<31; i++) | 109 { |
108 surface_ring_mbar[i] = ambient_pressure_mbar; | 110 for(int i=0; i<PRESSURE_SURFACE_QUE; i++) |
109 surface_pressure_mbar = ambient_pressure_mbar; | 111 surface_ring_mbar[i] = ambient_pressure_mbar; |
112 surface_pressure_mbar = ambient_pressure_mbar; | |
113 } | |
110 } | 114 } |
111 | 115 |
112 void init_pressure_history(void) | 116 void init_pressure_history(void) |
113 { | 117 { |
114 for(int i=0; i<PRESSURE_HISTORY_SIZE; i++) | 118 for(int i=0; i<PRESSURE_HISTORY_SIZE; i++) |
115 { | 119 { |
116 pressure_history_mbar[i] = 1000.0; | 120 pressure_history_mbar[i] = 1000.0; |
117 } | 121 } |
118 } | 122 } |
119 | 123 |
120 /* the ring has one place with 0 | 124 |
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) | 125 void update_surface_pressure(uint8_t call_rhythm_seconds) |
126 { | 126 { |
127 secondCounterSurfaceRing += call_rhythm_seconds; | 127 static uint8_t writeIndex = 0; /* Reinitialization will reset all entries to the same value => no need to reinit write index */ |
128 | 128 static uint8_t avgCount = 0; |
129 if(secondCounterSurfaceRing < 60) | 129 static float runningAvg = 0; |
130 return; | 130 |
131 | |
132 secondCounterSurfaceRing = 0; | |
133 | |
134 if(is_init_pressure_done()) | 131 if(is_init_pressure_done()) |
135 { | 132 { |
136 int hole; | 133 runningAvg = (runningAvg * avgCount + ambient_pressure_mbar) / (avgCount +1); |
137 for(hole=30;hole>0;hole--) | 134 avgCount++; |
138 if(surface_ring_mbar[hole] == 0) { break; } | 135 secondCounterSurfaceRing += call_rhythm_seconds; |
139 | 136 |
140 surface_ring_mbar[hole] = ambient_pressure_mbar; | 137 if(secondCounterSurfaceRing >= 60) |
141 | 138 { |
142 hole++; | 139 surface_ring_mbar[writeIndex] = runningAvg; |
143 if(hole > 30) | 140 writeIndex++; /* the write index is now pointing to the oldest value in the buffer which will be overwritten next time */ |
144 hole = 0; | 141 |
145 surface_pressure_mbar = surface_ring_mbar[hole]; | 142 if(writeIndex == PRESSURE_SURFACE_QUE) |
146 surface_ring_mbar[hole] = 0; | 143 { |
144 writeIndex = 0; | |
145 } | |
146 | |
147 surface_pressure_mbar = surface_ring_mbar[writeIndex]; /* 30 minutes old measurement */ | |
148 | |
149 secondCounterSurfaceRing = 0; | |
150 avgCount = 1; /* use the current value as starting point but restart the weight decrement of the measurements */ | |
151 } | |
147 } | 152 } |
148 } | 153 } |
149 | 154 |
150 #ifdef DEMOMODE | 155 #ifdef DEMOMODE |
151 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface) | 156 float demo_modify_temperature_helper(float bottom_mbar_diff_to_surface) |
447 return retval; | 452 return retval; |
448 } | 453 } |
449 | 454 |
450 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) | 455 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void) |
451 { | 456 { |
457 static float runningAvg = 0; | |
458 static uint8_t avgCnt = 0; | |
459 | |
452 uint32_t local_D1; // ADC value of the pressure conversion | 460 uint32_t local_D1; // ADC value of the pressure conversion |
453 uint32_t local_D2; // ADC value of the temperature conversion | 461 uint32_t local_D2; // ADC value of the temperature conversion |
454 int32_t local_Px10; // compensated pressure value | 462 int32_t local_Px10; // compensated pressure value |
455 int32_t local_Tx100; // compensated temperature value | 463 int32_t local_Tx100; // compensated temperature value |
456 int64_t local_dT; // int32_t, difference between actual and measured temperature | 464 int64_t local_dT; // int32_t, difference between actual and measured temperature |
514 ambient_temperature = ((float)local_Tx100) / 100; | 522 ambient_temperature = ((float)local_Tx100) / 100; |
515 | 523 |
516 calc_pressure = ((float)local_Px10) / 10; | 524 calc_pressure = ((float)local_Px10) / 10; |
517 if(pressure_plausible(calc_pressure)) | 525 if(pressure_plausible(calc_pressure)) |
518 { | 526 { |
519 ambient_pressure_mbar = calc_pressure; | 527 runningAvg = (avgCnt * runningAvg + calc_pressure) / (avgCnt + 1); |
528 if (avgCnt < 10) /* build an average considering the last measurements to a a weight "1 of 10" */ | |
529 { /* Main reason for this is the jitter of up to +-10 HPa in surface mode which is caused */ | |
530 avgCnt++; /* by the measurement range of the sensor which is focused on under water pressure measurement */ | |
531 } | |
532 ambient_pressure_mbar = runningAvg; | |
520 } | 533 } |
521 } | 534 } |
522 | 535 |
523 | 536 |
524 /* | 537 /* |