Skip to content

Commit 8c52ffd

Browse files
committed
Switch to average for sensor calibration estimate.
Signed-off-by: Michael Keller <[email protected]>
1 parent 482b546 commit 8c52ffd

File tree

1 file changed

+56
-27
lines changed

1 file changed

+56
-27
lines changed

src/shearwater_predator_parser.c

Lines changed: 56 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,33 @@ 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+
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;
888924
}
889925

890926
return DC_STATUS_SUCCESS;
@@ -1073,37 +1109,30 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
10731109
double calculated_ppo2 = data[offset + pnf + 6] / 100.0;
10741110

10751111
if (parser->needs_divecan_calibration_estimate) {
1112+
struct dc_parser_sensor_calibration_t *out = (struct dc_parser_sensor_calibration_t *)userdata;
1113+
10761114
double ppo2_sum = 0.0;
10771115
unsigned int ppo2_count = 0;
10781116
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;
10801118
ppo2_count++;
10811119
}
10821120

10831121
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;
10851123
ppo2_count++;
10861124
}
10871125

10881126
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;
10901128
ppo2_count++;
10911129
}
10921130

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;
11051132

1106-
parser->needs_divecan_calibration_estimate = false;
1133+
out->sum_ppo2 += ppo2;
1134+
out->sum_calculated_ppo2 += calculated_ppo2;
1135+
out->ppo2_sample_count++;
11071136
}
11081137

11091138
if (callback) {

0 commit comments

Comments
 (0)