Add the sensor index to the ppO2 sample

Rebreathers typically support multiple ppO2 sensors as a safety measure
in case a sensor fails during the dive. The current api can already
report multiple ppO2 values per sample, but it does not provide any
information about which sensor the measurement is from.

The new sensor index provides this info, and can also be used to
distinguish between the average/voted ppO2 value using the special value
DC_SENSOR_NONE.
This commit is contained in:
Jef Driesen 2021-04-22 20:33:54 +02:00
parent bca8f9e2d2
commit b1ff2c6a8e
7 changed files with 31 additions and 15 deletions

View File

@ -157,7 +157,11 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
fprintf (sampledata->ostream, " <setpoint>%.2f</setpoint>\n", value.setpoint); fprintf (sampledata->ostream, " <setpoint>%.2f</setpoint>\n", value.setpoint);
break; break;
case DC_SAMPLE_PPO2: case DC_SAMPLE_PPO2:
fprintf (sampledata->ostream, " <ppo2>%.2f</ppo2>\n", value.ppo2); if (value.ppo2.sensor != DC_SENSOR_NONE) {
fprintf (sampledata->ostream, " <ppo2 sensor=\"%u\">%.2f</ppo2>\n", value.ppo2.sensor, value.ppo2.value);
} else {
fprintf (sampledata->ostream, " <ppo2>%.2f</ppo2>\n", value.ppo2.value);
}
break; break;
case DC_SAMPLE_CNS: case DC_SAMPLE_CNS:
fprintf (sampledata->ostream, " <cns>%.1f</cns>\n", value.cns * 100.0); fprintf (sampledata->ostream, " <cns>%.1f</cns>\n", value.cns * 100.0);

View File

@ -147,6 +147,7 @@ typedef struct dc_gasmix_t {
double nitrogen; double nitrogen;
} dc_gasmix_t; } dc_gasmix_t;
#define DC_SENSOR_NONE 0xFFFFFFFF
#define DC_GASMIX_UNKNOWN 0xFFFFFFFF #define DC_GASMIX_UNKNOWN 0xFFFFFFFF
typedef enum dc_tankvolume_t { typedef enum dc_tankvolume_t {
@ -247,7 +248,10 @@ typedef union dc_sample_value_t {
const void *data; const void *data;
} vendor; } vendor;
double setpoint; double setpoint;
double ppo2; struct {
unsigned int sensor;
double value;
} ppo2;
double cns; double cns;
struct { struct {
unsigned int type; unsigned int type;

View File

@ -293,7 +293,8 @@ diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
if (offset + 1 > size) if (offset + 1 > size)
return DC_STATUS_DATAFORMAT; return DC_STATUS_DATAFORMAT;
unsigned int ppo2 = data[offset]; unsigned int ppo2 = data[offset];
sample.ppo2 = ppo2 / 100.0; sample.ppo2.sensor = DC_SENSOR_NONE;
sample.ppo2.value = ppo2 / 100.0;
if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
offset++; offset++;
} }

View File

@ -946,7 +946,8 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata); if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata);
if (ppo2) { if (ppo2) {
sample.ppo2 = ppo2 * 10.0 / BAR; sample.ppo2.sensor = DC_SENSOR_NONE;
sample.ppo2.value = ppo2 * 10.0 / BAR;
if (callback) callback(DC_SAMPLE_PPO2, sample, userdata); if (callback) callback(DC_SAMPLE_PPO2, sample, userdata);
} }
@ -1045,7 +1046,8 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
unsigned int ppo2 = array_uint16_le (data + offset + 4 + i * 2); unsigned int ppo2 = array_uint16_le (data + offset + 4 + i * 2);
if (ppo2 == 0 || ppo2 == 0xFFFF) if (ppo2 == 0 || ppo2 == 0xFFFF)
continue; continue;
sample.ppo2 = ppo2 * 10.0 / BAR; sample.ppo2.sensor = i;
sample.ppo2.value = ppo2 * 10.0 / BAR;
if (callback) callback(DC_SAMPLE_PPO2, sample, userdata); if (callback) callback(DC_SAMPLE_PPO2, sample, userdata);
} }
} else if (id == MEASURE_ID_OXYGEN_MV) { } else if (id == MEASURE_ID_OXYGEN_MV) {
@ -1055,7 +1057,8 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
if (!parser->calibrated || state == SENSTAT_UNCALIBRATED || if (!parser->calibrated || state == SENSTAT_UNCALIBRATED ||
state == SENSTAT_NOT_EXIST) state == SENSTAT_NOT_EXIST)
continue; continue;
sample.ppo2 = value / 100.0 * parser->calibration[i] / BAR; sample.ppo2.sensor = i;
sample.ppo2.value = value / 100.0 * parser->calibration[i] / BAR;
if (callback) callback(DC_SAMPLE_PPO2, sample, userdata); if (callback) callback(DC_SAMPLE_PPO2, sample, userdata);
} }
} }

View File

@ -1067,7 +1067,8 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
} }
if (count) { if (count) {
for (unsigned int j = 0; j < 3; ++j) { for (unsigned int j = 0; j < 3; ++j) {
sample.ppo2 = ppo2[j] / 100.0; sample.ppo2.sensor = i;
sample.ppo2.value = ppo2[j] / 100.0;
if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
} }
} }

View File

@ -927,19 +927,21 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
if (ccr) { if (ccr) {
// PPO2 // PPO2
if ((status & PPO2_EXTERNAL) == 0) { if ((status & PPO2_EXTERNAL) == 0) {
#ifdef SENSOR_AVERAGE sample.ppo2.sensor = DC_SENSOR_NONE;
sample.ppo2 = data[offset + pnf + 6] / 100.0; sample.ppo2.value = data[offset + pnf + 6] / 100.0;
if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
#else
sample.ppo2 = data[offset + pnf + 12] * parser->calibration[0]; sample.ppo2.sensor = 0;
sample.ppo2.value = data[offset + pnf + 12] * parser->calibration[0];
if (callback && (parser->calibrated & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback && (parser->calibrated & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata);
sample.ppo2 = data[offset + pnf + 14] * parser->calibration[1]; sample.ppo2.sensor = 1;
sample.ppo2.value = data[offset + pnf + 14] * parser->calibration[1];
if (callback && (parser->calibrated & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback && (parser->calibrated & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata);
sample.ppo2 = data[offset + pnf + 15] * parser->calibration[2]; sample.ppo2.sensor = 2;
sample.ppo2.value = data[offset + pnf + 15] * parser->calibration[2];
if (callback && (parser->calibrated & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback && (parser->calibrated & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata);
#endif
} }
// Setpoint // Setpoint

View File

@ -174,7 +174,8 @@ tecdiving_divecomputereu_parser_samples_foreach (dc_parser_t *abstract, dc_sampl
// ppO2 // ppO2
unsigned int ppo2 = data[offset + 1]; unsigned int ppo2 = data[offset + 1];
sample.ppo2 = ppo2 / 10.0; sample.ppo2.sensor = DC_SENSOR_NONE;
sample.ppo2.value = ppo2 / 10.0;
if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
// Setpoint // Setpoint