On 2017-12-02 22:39, Anton Lundin wrote:
On 02 December, 2017 - Anton Lundin wrote:
I saw something odd looking at that data. There's another calibration
value in the data, which we never figured out the meaning of.

In all other sample data its bin zero or low values like 2. In your data
its 255.

I assume you are talking about the ADC offset field?

The thing is also that if i "correct" your mV values by about -8, the
data lines up pretty nicely, so there's some correcting needing to be
done.

Can you save the same dive from Shearwater Desktop so I can take a look
at the mV values they report there, so see of they are out by about -8
or so?

The sensor millivolt values in the xml export and the raw data seems to be identical. At least for the few I checked. So I don't think we have to look there.

What I've guest previously, is that the unknown parameter there is
related to O2 Offsets.

Some related material on the subject is from when a production mis
caused them to be left as zero:
https://www.shearwater.com/wp-content/uploads/2016/07/O2-Offsets-Public-Notice-RevA.pdf

Why your's are max value 255 (signed -127), I don't know but they might
be just that.

What we never knew earlier was the unit of the offset value, or if it
was already applied to the value stored in the log.

Just a minor correction: When interpreted as a signed 8 bit number, the value 255 is -1, not -127.


Anyway, I analyzed all the data I have available and listed the calibration values stored in the dive header. The results are shown below.

The numbers are respectively:
 * sensor voting status bit (at offset 16)
 * calibration status bit (at offset 86)
 * calibration value (at offset 87-92)
 * adc offset (at offset 93-95)

perdixai.jongross
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

perdixai.linustorvalds
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

perdix.alvaroaguilera
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

perdix.timmassey
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

petrel.davidedb.310d20b4 (CCR, extppo2)
Sensor 0: 1 1 2100 -1
Sensor 1: 1 1 2100 -1
Sensor 2: 1 1 2100 -1

petrel.davidedb.39117da9 (CCR, extppo2)
Sensor 0: 0 1 2100 -1
Sensor 0: 1 1 2100 -1
Sensor 1: 0 1 2100 -1
Sensor 1: 1 1 2100 -1
Sensor 2: 0 1 2100 -1
Sensor 2: 1 1 2100 -1

petrel.henrikaronsen
Sensor 0: 0 0 0 -5
Sensor 0: 0 0 2100 -5
Sensor 1: 0 0 2100 -27
Sensor 1: 0 0 2148 -27
Sensor 2: 0 0 0 -9
Sensor 2: 0 0 2100 -9

petrel.jimpiavis
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

petrel.nickshore
Sensor 0: 0 0 2100 13
Sensor 1: 0 0 2100 11
Sensor 2: 0 0 2100 -23

petrel.stevewilliams (CCR, extppo2)
Sensor 0: 0 0 2100 2
Sensor 0: 0 1 1986 2
Sensor 0: 1 1 1769 2
Sensor 0: 1 1 1793 2
Sensor 0: 1 1 1826 2
Sensor 0: 1 1 1879 2
Sensor 0: 1 1 1935 2
Sensor 1: 0 0 2100 16
Sensor 1: 0 1 1970 16
Sensor 1: 0 1 2229 16
Sensor 1: 1 1 2227 16
Sensor 1: 1 1 2229 16
Sensor 1: 1 1 2263 16
Sensor 1: 1 1 2269 16
Sensor 1: 1 1 2533 16
Sensor 2: 0 0 0 4
Sensor 2: 0 0 2100 4
Sensor 2: 0 1 1986 4
Sensor 2: 1 1 1689 4
Sensor 2: 1 1 1817 4
Sensor 2: 1 1 1931 4
Sensor 2: 1 1 1974 4

petrel.45df0631
Sensor 0: 0 0 2100 13
Sensor 1: 0 0 2100 11
Sensor 2: 0 0 2100 -23

petrel.d3ea0432
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

petrel.larrybainbridge (CCR)
Sensor 0: 0 1 2045 44
Sensor 1: 0 1 2025 -9
Sensor 2: 0 1 2045 51

petrel.marklee (CCR)
Sensor 0: 0 0 2100 -1
Sensor 1: 0 0 2100 -1
Sensor 2: 0 0 2100 -1

petrel.rainer (CCR, extppo2)
Sensor 0: 0 1 1990 0
Sensor 0: 0 1 2034 0
Sensor 0: 1 1 1671 0
Sensor 0: 1 1 1990 0
Sensor 0: 1 1 2034 0
Sensor 0: 1 1 2038 0
Sensor 0: 1 1 2112 0
Sensor 1: 0 1 1810 39
Sensor 1: 1 1 1810 39
Sensor 1: 1 1 1929 39
Sensor 1: 1 1 2007 39
Sensor 1: 1 1 2068 39
Sensor 1: 1 1 2326 39
Sensor 2: 1 1 1621 2
Sensor 2: 1 1 1866 2
Sensor 2: 1 1 1939 2
Sensor 2: 1 1 2010 2
Sensor 2: 1 1 2108 2

predator.janschubert (CCR, extppo2)
Sensor 0: 1 1 859 -16
Sensor 0: 1 1 866 -16
Sensor 0: 1 1 867 -16
Sensor 0: 1 1 868 -16
Sensor 0: 1 1 878 -16
Sensor 0: 1 1 879 -16
Sensor 0: 1 1 881 -16
Sensor 0: 1 1 888 -16
Sensor 0: 1 1 890 -16
Sensor 0: 1 1 892 -16
Sensor 0: 1 1 895 -16
Sensor 1: 1 1 812 -24
Sensor 1: 1 1 814 -24
Sensor 1: 1 1 819 -24
Sensor 1: 1 1 828 -24
Sensor 1: 1 1 829 -24
Sensor 1: 1 1 834 -24
Sensor 1: 1 1 839 -24
Sensor 1: 1 1 843 -24
Sensor 2: 1 1 827 -11
Sensor 2: 1 1 831 -11
Sensor 2: 1 1 832 -11
Sensor 2: 1 1 836 -11
Sensor 2: 1 1 837 -11
Sensor 2: 1 1 839 -11
Sensor 2: 1 1 841 -11
Sensor 2: 1 1 844 -11
Sensor 2: 1 1 845 -11
Sensor 2: 1 1 856 -11

predator.kasrafaghihi
Sensor 0: 0 0 0 0
Sensor 1: 0 0 0 0
Sensor 2: 0 0 0 0

predator.marklee (CCR, extppo2)
Sensor 0: 1 1 1069 -41
Sensor 0: 1 1 885 -41
Sensor 0: 1 1 904 -41
Sensor 0: 1 1 982 -41
Sensor 1: 1 1 1000 -39
Sensor 1: 1 1 1016 -39
Sensor 1: 1 1 989 -39
Sensor 1: 1 1 996 -39
Sensor 2: 1 1 1179 -5
Sensor 2: 1 1 1228 -5
Sensor 2: 1 1 1261 -5
Sensor 2: 1 1 1376 -5

As you can see, the ADC offset never changes! Only the calibration value changes, which is of course expected. The ADC offset values are not always close to zero (e.g. ranging from -41 to 51). And last but not least, the ADC offset value -1 is quite common. I suspect that this might be models which do not support external O2 sensors. In that case it makes sense to record the special value -1 to indicate "not available". The corresponding calibration value is always 2100, so I guess that's the factory default value.

Davide's data is the exception to the rule. It's the only dataset with CCR dives present, and an ADC offset of -1. I'm not sure what's going on there. The -1 could be a valid value here, but it would be really coincidence if all three sensors have the same ADC offset. All other datasets with CCR dives have different values for each sensor.

I suspect the millivolt values already take into account the ADC value. Because if that's not the case, then I would expect to see large deltas between the stored average ppO2 and the manually calculated ppO2 after doing the millivolt conversion. The larger the ADC offset (absolute value), the larger the delta. But the cases where I see a delta larger than 0.02 seems to be cases where one sensor is an outlier and was most likely voted out. But again Davide's dataset seems to be the exception here.

Jef
diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c
index 8abd0f9..aa05405 100644
--- a/src/shearwater_predator_parser.c
+++ b/src/shearwater_predator_parser.c
@@ -20,6 +20,7 @@
  */
 
 #include <stdlib.h>
+#include <math.h>
 
 #include <libdivecomputer/units.h>
 
@@ -298,6 +299,16 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
 		offset += parser->samplesize;
 	}
 
+	message("Sensors: %u\n", data[44]);
+	for (unsigned int i = 0; i < 3; ++i) {
+		unsigned int bit = 1 << i;
+		unsigned int voted = (data[16] & bit) != 0;
+		unsigned int calibrated = (data[86] & bit) != 0;
+		unsigned int calibration = array_uint16_be(data + 87 + i * 2);
+		signed int adc = (signed char) data[93 + i];
+		message("Sensor %u: %u %u %u %i\n", i, voted, calibrated, calibration, adc);
+	}
+
 	// Cache sensor calibration for later use
 	parser->calibration[0] = array_uint16_be(data + 87) / 100000.0;
 	parser->calibration[1] = array_uint16_be(data + 89) / 100000.0;
@@ -391,6 +402,54 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
 	return DC_STATUS_SUCCESS;
 }
 
+static void
+analyze(shearwater_predator_parser_t *parser, const unsigned char data[], unsigned int offset)
+{
+	unsigned int mv[3] = {0};
+	double ppo2[3] = {0};
+
+	double sum = 0;
+	unsigned int count = 0;
+	for (unsigned int i = 0; i < 3; ++i) {
+		unsigned int bit = 1 << i;
+		unsigned int voted = (data[16] & bit) != 0;
+		unsigned int calibrated = (data[86] & bit) != 0;
+		unsigned int calibration = array_uint16_be(data + 87 + i * 2);
+		signed int adc = (signed char) data[93 + i];
+
+		unsigned int idx = 12 + (i == 0 ? i : i + 1);
+		unsigned int millivolt = data[offset + idx];
+
+		mv[i] = millivolt;
+		if (parser->model == PREDATOR) {
+			ppo2[i] = millivolt * (calibration * 2.2) / 100000.0 * 100.0;
+		} else {
+			ppo2[i] = millivolt * (calibration) / 100000.0 * 100.0;
+		}
+
+		if (calibrated) {
+			sum += ppo2[i];
+			count++;
+		}
+	}
+
+	unsigned int avg_dev = data[offset + 6];
+	double avg_calc = sum / (double) count;
+	double delta = fabs(avg_calc - avg_dev);
+
+
+	message ("mV: %u %u %u\n",
+		mv[0], mv[1], mv[2]);
+	message ("ppO2: %u %.1f %.3f %.1f %.1f %.1f\n",
+		avg_dev, avg_calc, delta, ppo2[0], ppo2[1], ppo2[2]);
+
+	if (delta > 2.0) {
+		message ("Voting: %u %.1f %.3f %.1f %.1f %.1f\n",
+			avg_dev, avg_calc, delta, ppo2[0], ppo2[1], ppo2[2]);
+	}
+}
+
+
 
 static dc_status_t
 shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
@@ -453,6 +512,19 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
 
 		// Status flags.
 		unsigned int status = data[offset + 11];
+		unsigned int gasswitch = (status     ) & 0x01;
+		unsigned int extppo2   = (status >> 1) & 0x01;
+		unsigned int setpoint  = (status >> 2) & 0x01;
+		unsigned int sc        = (status >> 3) & 0x01;
+		unsigned int oc        = (status >> 4) & 0x01;
+		message("Status %02x: gasswitch=%u extppo2=%u setpoint=%u sc=%u oc=%u\n",
+			status, gasswitch, extppo2, setpoint, sc, oc);
+
+#if 0
+		// PPO2
+		sample.ppo2 = data[offset + 6] / 100.0;
+		if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
+#endif
 
 		if ((status & OC) == 0) {
 			// PPO2
@@ -470,6 +542,8 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
 				sample.ppo2 = data[offset + 15] * parser->calibration[2];
 				if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata);
 #endif
+
+				analyze(parser, data, offset);
 			}
 
 			// Setpoint
_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to