From 588e7e7ab459b5df181d7600b891adc7458d9902 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 6 Feb 2015 09:56:21 -0800 Subject: [PATCH 1/5] Predator: don't report PPO2 unless in CC mode Sending this in OC mode is redundant and might confuse applications that assume they only get PPO2 data in CC mode. Signed-off-by: Dirk Hohndel --- src/shearwater_predator_parser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 039926f..c71c9d7 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -422,11 +422,11 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal // Status flags. unsigned int status = data[offset + 11]; - // PPO2 - sample.ppo2 = data[offset + 6] / 100.0; - if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); - if ((status & OC) == 0) { + // PPO2 + sample.ppo2 = data[offset + 6] / 100.0; + if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); + // Setpoint if (parser->petrel) { sample.setpoint = data[offset + 18] / 100.0; From d3ca3e87bd92bce7a59818998825652e025e341f Mon Sep 17 00:00:00 2001 From: Anton Lundin Date: Wed, 14 Oct 2015 19:49:25 +0200 Subject: [PATCH 2/5] shearwater: Report individual sensor values This reads the reported mV values from the sensors, and based on the calibration values converts it into a ppo2 value to report. Signed-off-by: Anton Lundin --- src/shearwater_predator_parser.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index c71c9d7..7c36651 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -61,6 +61,7 @@ struct shearwater_predator_parser_t { unsigned int ngasmixes; unsigned int oxygen[NGASMIXES]; unsigned int helium[NGASMIXES]; + unsigned int calibration[3]; dc_divemode_t mode; }; @@ -281,6 +282,18 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) offset += parser->samplesize; } + // Cache sensor calibration for later use + parser->calibration[0] = array_uint16_be(data + 87); + parser->calibration[1] = array_uint16_be(data + 89); + parser->calibration[2] = array_uint16_be(data + 91); + // The Predator expects the mV output of the cells to be within 30mV + // to 70mV in 100% O2 at 1 atmosphere. + // If we add 1024 (1000?) to the calibration value, then the sensors + // lines up and matches the average. + parser->calibration[0] += 1024; + parser->calibration[1] += 1024; + parser->calibration[2] += 1024; + // Cache the data for later use. parser->headersize = headersize; parser->footersize = footersize; @@ -424,8 +437,19 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal if ((status & OC) == 0) { // PPO2 +#ifdef SENSOR_AVERAGE sample.ppo2 = data[offset + 6] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); +#else + sample.ppo2 = data[offset + 12] * parser->calibration[0] / 100000.0; + if (callback && (data[86] & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); + + sample.ppo2 = data[offset + 14] * parser->calibration[1] / 100000.0; + if (callback && (data[86] & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); + + sample.ppo2 = data[offset + 15] * parser->calibration[2] / 100000.0; + if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); +#endif // Setpoint if (parser->petrel) { From fe2d128b4453903ffb61feb0c10cbc69e9f3b81e Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 13 Apr 2017 21:26:56 +0200 Subject: [PATCH 3/5] Apply the calibration correction only for the Predator The calibration values for the Petrel are typically in the range 1600 to 2400, while for Predator they are much smaller, with values in the range 800 to 1400. The consequence is that the calculated ppO2 values are too low for the Predator. Adding a constant offset of about 1000 changes the calibration value to be in approximately the same range as the Petrel, and hence more reasonable ppO2 values. But this correction should only be applied for the Predator, and not the Petrel. Reviewed-by: Anton Lundin --- src/parser.c | 4 ++-- src/shearwater_petrel.h | 2 +- src/shearwater_predator.h | 2 +- src/shearwater_predator_parser.c | 23 +++++++++++++++-------- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/parser.c b/src/parser.c index 98d2c89..9fdb1a9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -149,10 +149,10 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa rc = atomics_cobalt_parser_create (&parser, context); break; case DC_FAMILY_SHEARWATER_PREDATOR: - rc = shearwater_predator_parser_create (&parser, context); + rc = shearwater_predator_parser_create (&parser, context, model); break; case DC_FAMILY_SHEARWATER_PETREL: - rc = shearwater_petrel_parser_create (&parser, context); + rc = shearwater_petrel_parser_create (&parser, context, model); break; case DC_FAMILY_DIVERITE_NITEKQ: rc = diverite_nitekq_parser_create (&parser, context); diff --git a/src/shearwater_petrel.h b/src/shearwater_petrel.h index 8b927d6..c23bb74 100644 --- a/src/shearwater_petrel.h +++ b/src/shearwater_petrel.h @@ -34,7 +34,7 @@ dc_status_t shearwater_petrel_device_open (dc_device_t **device, dc_context_t *context, const char *name); dc_status_t -shearwater_petrel_parser_create (dc_parser_t **parser, dc_context_t *context); +shearwater_petrel_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model); #ifdef __cplusplus } diff --git a/src/shearwater_predator.h b/src/shearwater_predator.h index f21d445..4665f80 100644 --- a/src/shearwater_predator.h +++ b/src/shearwater_predator.h @@ -34,7 +34,7 @@ dc_status_t shearwater_predator_device_open (dc_device_t **device, dc_context_t *context, const char *name); dc_status_t -shearwater_predator_parser_create (dc_parser_t **parser, dc_context_t *context); +shearwater_predator_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model); #ifdef __cplusplus } diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 7c36651..58d1704 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -48,10 +48,14 @@ #define NGASMIXES 10 +#define PREDATOR 2 +#define PETREL 3 + typedef struct shearwater_predator_parser_t shearwater_predator_parser_t; struct shearwater_predator_parser_t { dc_parser_t base; + unsigned int model; unsigned int petrel; unsigned int samplesize; // Cached fields. @@ -106,7 +110,7 @@ shearwater_predator_find_gasmix (shearwater_predator_parser_t *parser, unsigned static dc_status_t -shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int petrel) +shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int petrel) { shearwater_predator_parser_t *parser = NULL; const dc_parser_vtable_t *vtable = NULL; @@ -131,6 +135,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig } // Set the default values. + parser->model = model; parser->petrel = petrel; parser->samplesize = samplesize; parser->cached = 0; @@ -150,16 +155,16 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig dc_status_t -shearwater_predator_parser_create (dc_parser_t **out, dc_context_t *context) +shearwater_predator_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model) { - return shearwater_common_parser_create (out, context, 0); + return shearwater_common_parser_create (out, context, model, 0); } dc_status_t -shearwater_petrel_parser_create (dc_parser_t **out, dc_context_t *context) +shearwater_petrel_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model) { - return shearwater_common_parser_create (out, context, 1); + return shearwater_common_parser_create (out, context, model, 1); } @@ -290,9 +295,11 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) // to 70mV in 100% O2 at 1 atmosphere. // If we add 1024 (1000?) to the calibration value, then the sensors // lines up and matches the average. - parser->calibration[0] += 1024; - parser->calibration[1] += 1024; - parser->calibration[2] += 1024; + if (parser->model == PREDATOR) { + parser->calibration[0] += 1024; + parser->calibration[1] += 1024; + parser->calibration[2] += 1024; + } // Cache the data for later use. parser->headersize = headersize; From 7e7cbd55b1c2b619a9f39a663bccc81c688b01b3 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 13 Apr 2017 21:26:56 +0200 Subject: [PATCH 4/5] Replace the constant offset with a scaling factor Correcting the Predator calibration value with a scaling factor produces even more reasonable ppO2 values compared to using a constant offset. The scaling factor of 2.2 is based on a linear regression between the average ppO2 reported by the dive computer, and the average ppO2 calculated over all (calibrated) sensors using the raw calibration value. Reviewed-by: Anton Lundin --- src/shearwater_predator_parser.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 58d1704..3e5fcbf 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -65,7 +65,7 @@ struct shearwater_predator_parser_t { unsigned int ngasmixes; unsigned int oxygen[NGASMIXES]; unsigned int helium[NGASMIXES]; - unsigned int calibration[3]; + double calibration[3]; dc_divemode_t mode; }; @@ -288,17 +288,17 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) } // Cache sensor calibration for later use - parser->calibration[0] = array_uint16_be(data + 87); - parser->calibration[1] = array_uint16_be(data + 89); - parser->calibration[2] = array_uint16_be(data + 91); + parser->calibration[0] = array_uint16_be(data + 87) / 100000.0; + parser->calibration[1] = array_uint16_be(data + 89) / 100000.0; + parser->calibration[2] = array_uint16_be(data + 91) / 100000.0; // The Predator expects the mV output of the cells to be within 30mV // to 70mV in 100% O2 at 1 atmosphere. - // If we add 1024 (1000?) to the calibration value, then the sensors - // lines up and matches the average. + // If the calibration value is scaled with a factor 2.2, then the + // sensors lines up and matches the average. if (parser->model == PREDATOR) { - parser->calibration[0] += 1024; - parser->calibration[1] += 1024; - parser->calibration[2] += 1024; + for (size_t i = 0; i < 3; ++i) { + parser->calibration[i] *= 2.2; + } } // Cache the data for later use. @@ -448,14 +448,15 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal sample.ppo2 = data[offset + 6] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); #else - sample.ppo2 = data[offset + 12] * parser->calibration[0] / 100000.0; + sample.ppo2 = data[offset + 12] * parser->calibration[0]; if (callback && (data[86] & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); - sample.ppo2 = data[offset + 14] * parser->calibration[1] / 100000.0; + sample.ppo2 = data[offset + 14] * parser->calibration[1]; if (callback && (data[86] & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); - sample.ppo2 = data[offset + 15] * parser->calibration[2] / 100000.0; + sample.ppo2 = data[offset + 15] * parser->calibration[2]; if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); + } #endif // Setpoint From d6806ab494459b6ffc6897bddbf2622783743bec Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 8 May 2017 19:24:32 +0200 Subject: [PATCH 5/5] Report the ppO2 in external O2 sensor mode only The O2 sensor millivolt values are only valid if external O2 sensor monitoring is enabled. Note that the interpretation of the PPO2 status bit appears to be reversed (0=external and 1=internal). Reviewed-by: Anton Lundin --- src/shearwater_predator_parser.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 3e5fcbf..e922220 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -448,14 +448,15 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal sample.ppo2 = data[offset + 6] / 100.0; if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); #else - sample.ppo2 = data[offset + 12] * parser->calibration[0]; - if (callback && (data[86] & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); + if ((status & PPO2_EXTERNAL) == 0) { + sample.ppo2 = data[offset + 12] * parser->calibration[0]; + if (callback && (data[86] & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); - sample.ppo2 = data[offset + 14] * parser->calibration[1]; - if (callback && (data[86] & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); + sample.ppo2 = data[offset + 14] * parser->calibration[1]; + if (callback && (data[86] & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); - sample.ppo2 = data[offset + 15] * parser->calibration[2]; - if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); + sample.ppo2 = data[offset + 15] * parser->calibration[2]; + if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); } #endif