Skip to content

Commit d1be4bb

Browse files
committed
Switch to average for sensor calibration estimate.
Signed-off-by: Michael Keller <github@ike.ch>
1 parent 482b546 commit d1be4bb

File tree

1 file changed

+49
-27
lines changed

1 file changed

+49
-27
lines changed

src/shearwater_predator_parser.c

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
166172
static dc_status_t shearwater_predator_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
167173
static dc_status_t shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
168174
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
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+
420440
static dc_status_t
421441
shearwater_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

Comments
 (0)