@@ -163,6 +163,12 @@ struct shearwater_predator_parser_t {
163163 struct dc_field_cache cache ;
164164};
165165
166+ struct dc_parser_sensor_calibration_t {
167+ double sum_ppo2 ;
168+ double sum_calculated_ppo2 ;
169+ unsigned int ppo2_sample_count ;
170+ };
171+
166172static dc_status_t shearwater_predator_parser_get_datetime (dc_parser_t * abstract , dc_datetime_t * datetime );
167173static dc_status_t shearwater_predator_parser_get_field (dc_parser_t * abstract , dc_field_type_t type , unsigned int flags , void * value );
168174static 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
417423 }
418424}
419425
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+
420440static dc_status_t
421441shearwater_predator_parser_cache (shearwater_predator_parser_t * parser )
422442{
@@ -777,16 +797,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
777797
778798 if (calibration_count > 0 ) {
779799 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 );
790801 } else {
791802 // All calibrated sensors report the default calibration value
792803 // so this could be a DiveCAN controller, where the calibration values
@@ -883,8 +894,26 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
883894 break ;
884895 }
885896
897+ dc_status_t rc = DC_STATUS_SUCCESS ;
886898 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+ double calibration = data .sum_calculated_ppo2 / data .sum_ppo2 ;
904+ if (calibration < 0.95 || calibration > 1.05 ) {
905+ // The calibration scaling is significant, use it.
906+ calibration *= SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
907+ parser -> calibration [0 ] = calibration ;
908+ parser -> calibration [1 ] = calibration ;
909+ parser -> calibration [2 ] = calibration ;
910+
911+ dc_field_add_string_fmt (& parser -> cache , "Estimated (DiveCAN?) sensor calibration [bar / V]" , "%.2f" , calibration * 1000 );
912+ } else {
913+ print_calibration (parser );
914+ }
915+
916+ parser -> needs_divecan_calibration_estimate = false;
888917 }
889918
890919 return DC_STATUS_SUCCESS ;
@@ -1073,37 +1102,30 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
10731102 double calculated_ppo2 = data [offset + pnf + 6 ] / 100.0 ;
10741103
10751104 if (parser -> needs_divecan_calibration_estimate ) {
1105+ struct dc_parser_sensor_calibration_t * out = (struct dc_parser_sensor_calibration_t * )userdata ;
1106+
10761107 double ppo2_sum = 0.0 ;
10771108 unsigned int ppo2_count = 0 ;
10781109 if (parser -> calibrated & 0x01 ) {
1079- ppo2_sum += data [offset + pnf + 12 ] * SENSOR_CALIBRATION_DEFAULT ;
1110+ ppo2_sum += data [offset + pnf + 12 ] * SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
10801111 ppo2_count ++ ;
10811112 }
10821113
10831114 if (parser -> calibrated & 0x02 ) {
1084- ppo2_sum += data [offset + pnf + 14 ] * SENSOR_CALIBRATION_DEFAULT ;
1115+ ppo2_sum += data [offset + pnf + 14 ] * SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
10851116 ppo2_count ++ ;
10861117 }
10871118
10881119 if (parser -> calibrated & 0x04 ) {
1089- ppo2_sum += data [offset + pnf + 15 ] * SENSOR_CALIBRATION_DEFAULT ;
1120+ ppo2_sum += data [offset + pnf + 15 ] * SENSOR_CALIBRATION_DEFAULT / 100000.0 ;
10901121 ppo2_count ++ ;
10911122 }
10921123
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 );
1124+ double ppo2 = ppo2_sum / ppo2_count ;
11051125
1106- parser -> needs_divecan_calibration_estimate = false;
1126+ out -> sum_ppo2 += ppo2 ;
1127+ out -> sum_calculated_ppo2 += calculated_ppo2 ;
1128+ out -> ppo2_sample_count ++ ;
11071129 }
11081130
11091131 if (callback ) {
0 commit comments