@@ -163,6 +163,12 @@ struct shearwater_predator_parser_t {
163
163
struct dc_field_cache cache ;
164
164
};
165
165
166
+ struct dc_parser_sensor_calibration_t {
167
+ double sum_ppo2 ;
168
+ double sum_calculated_ppo2 ;
169
+ unsigned int ppo2_sample_count ;
170
+ };
171
+
166
172
static dc_status_t shearwater_predator_parser_get_datetime (dc_parser_t * abstract , dc_datetime_t * datetime );
167
173
static dc_status_t shearwater_predator_parser_get_field (dc_parser_t * abstract , dc_field_type_t type , unsigned int flags , void * value );
168
174
static dc_status_t shearwater_predator_parser_samples_foreach (dc_parser_t * abstract , dc_sample_callback_t callback , void * userdata );
@@ -417,6 +423,20 @@ add_battery_type(shearwater_predator_parser_t *parser, const unsigned char *data
417
423
}
418
424
}
419
425
426
+ static void print_calibration (shearwater_predator_parser_t * parser )
427
+ {
428
+ for (size_t i = 0 ; i < 3 ; ++ i ) {
429
+ if (parser -> calibrated & (1 << i )) {
430
+ static const char * name [] = {
431
+ "Sensor 1 calibration [bar / V]" ,
432
+ "Sensor 2 calibration [bar / V]" ,
433
+ "Sensor 3 calibration [bar / V]" ,
434
+ };
435
+ dc_field_add_string_fmt (& parser -> cache , name [i ], "%.2f" , parser -> calibration [i ] * 1000 );
436
+ }
437
+ }
438
+ }
439
+
420
440
static dc_status_t
421
441
shearwater_predator_parser_cache (shearwater_predator_parser_t * parser )
422
442
{
@@ -777,16 +797,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
777
797
778
798
if (calibration_count > 0 ) {
779
799
if (calibration_default_count < calibration_count ) {
780
- for (size_t i = 0 ; i < 3 ; ++ i ) {
781
- if (parser -> calibrated & (1 << i )) {
782
- static const char * name [] = {
783
- "Sensor 1 calibration [bar / V]" ,
784
- "Sensor 2 calibration [bar / V]" ,
785
- "Sensor 3 calibration [bar / V]" ,
786
- };
787
- dc_field_add_string_fmt (& parser -> cache , name [i ], "%.2f" , parser -> calibration [i ] * 1000 );
788
- }
789
- }
800
+ print_calibration (parser );
790
801
} else {
791
802
// All calibrated sensors report the default calibration value
792
803
// so this could be a DiveCAN controller, where the calibration values
@@ -883,8 +894,33 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
883
894
break ;
884
895
}
885
896
897
+ dc_status_t rc = DC_STATUS_SUCCESS ;
886
898
if (parser -> needs_divecan_calibration_estimate ) {
887
- return shearwater_predator_parser_samples_foreach (abstract , NULL , NULL );
899
+ struct dc_parser_sensor_calibration_t data = { 0 };
900
+
901
+ rc = shearwater_predator_parser_samples_foreach (abstract , NULL , (void * )& data );
902
+
903
+ bool calibrated = false;
904
+ if (data .sum_ppo2 != 0 ) {
905
+ double calibration = data .sum_calculated_ppo2 / data .sum_ppo2 ;
906
+ if (calibration < 0.98 || calibration > 1.02 ) {
907
+ // The calibration scaling is significant, use it.
908
+ calibration *= SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
909
+ parser -> calibration [0 ] = calibration ;
910
+ parser -> calibration [1 ] = calibration ;
911
+ parser -> calibration [2 ] = calibration ;
912
+
913
+ dc_field_add_string_fmt (& parser -> cache , "Estimated (DiveCAN?) sensor calibration [bar / V]" , "%.2f" , calibration * 1000 );
914
+
915
+ calibrated = true;
916
+ }
917
+ }
918
+
919
+ if (!calibrated ) {
920
+ print_calibration (parser );
921
+ }
922
+
923
+ parser -> needs_divecan_calibration_estimate = false;
888
924
}
889
925
890
926
return DC_STATUS_SUCCESS ;
@@ -1073,37 +1109,30 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
1073
1109
double calculated_ppo2 = data [offset + pnf + 6 ] / 100.0 ;
1074
1110
1075
1111
if (parser -> needs_divecan_calibration_estimate ) {
1112
+ struct dc_parser_sensor_calibration_t * out = (struct dc_parser_sensor_calibration_t * )userdata ;
1113
+
1076
1114
double ppo2_sum = 0.0 ;
1077
1115
unsigned int ppo2_count = 0 ;
1078
1116
if (parser -> calibrated & 0x01 ) {
1079
- ppo2_sum += data [offset + pnf + 12 ] * SENSOR_CALIBRATION_DEFAULT ;
1117
+ ppo2_sum += data [offset + pnf + 12 ] * SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
1080
1118
ppo2_count ++ ;
1081
1119
}
1082
1120
1083
1121
if (parser -> calibrated & 0x02 ) {
1084
- ppo2_sum += data [offset + pnf + 14 ] * SENSOR_CALIBRATION_DEFAULT ;
1122
+ ppo2_sum += data [offset + pnf + 14 ] * SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
1085
1123
ppo2_count ++ ;
1086
1124
}
1087
1125
1088
1126
if (parser -> calibrated & 0x04 ) {
1089
- ppo2_sum += data [offset + pnf + 15 ] * SENSOR_CALIBRATION_DEFAULT ;
1127
+ ppo2_sum += data [offset + pnf + 15 ] * SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
1090
1128
ppo2_count ++ ;
1091
1129
}
1092
1130
1093
- double calibration = SENSOR_CALIBRATION_DEFAULT ;
1094
- double calibration_scaling_factor = calculated_ppo2 / (ppo2_sum / ppo2_count );
1095
- if (calibration_scaling_factor < 0.95 || calibration_scaling_factor > 1.05 ) {
1096
- // The calibration scaling is significant, use it.
1097
- calibration *= calibration_scaling_factor ;
1098
- }
1099
-
1100
- parser -> calibration [0 ] = calibration ;
1101
- parser -> calibration [1 ] = calibration ;
1102
- parser -> calibration [2 ] = calibration ;
1103
-
1104
- dc_field_add_string_fmt (& parser -> cache , "Estimated DiveCAN calibration [bar / V]" , "%.2f" , calibration * 1000 );
1131
+ double ppo2 = ppo2_sum / ppo2_count ;
1105
1132
1106
- parser -> needs_divecan_calibration_estimate = false;
1133
+ out -> sum_ppo2 += ppo2 ;
1134
+ out -> sum_calculated_ppo2 += calculated_ppo2 ;
1135
+ out -> ppo2_sample_count ++ ;
1107
1136
}
1108
1137
1109
1138
if (callback ) {
0 commit comments