Individual O2 sensor readings

Jef Driesen jef at libdivecomputer.org
Thu Sep 3 05:58:48 PDT 2015


On 2015-08-26 23:24, Anton Lundin wrote:
> Sorry for not getting around to comment on this. Lots of random things
> came in the way, but now i finally have some time to write you a anser.
> 
> On 01 July, 2015 - Jef Driesen wrote:
> 
>> On 2015-06-27 12:41, Anton Lundin wrote:
>> >On 26 June, 2015 - Jef Driesen wrote:
>> For the long term solution, I certainly agree a custom struct is the
>> way to go. But what I would like to avoid is that we now add a new
>> DC_SAMPLE_PPO2_SENSOR in order to not break backwards compatibility.
>> But once v0.5 is out, I would like to start cleaning up mistake like
>> this one. So it's not unlikely we'll be removing
>> DC_SAMPLE_PPO2_SENSOR again and use our new struct in combination
>> with the original DC_SAMPLE_PPO2 type. (Before you started this
>> discussion, I planned to simply replace the single ppo2 field with a
>> struct after the v0.5 release. That's why I didn't apply the ostc
>> patch yet.)
> 
> I saw that you pushed ppo2 code for the OSTC's. I don't really think
> thats the best way to do it, and ill try to explain why i think so.
> 
> I think mixing the voted/consensus/average/real ppo2 with values from
> individual sensors are confusing at best, and plain wrong at worst.
> 
> Eg. subsurface would currently grab and store the last callback value 
> of
> DC_SAMPLE_PPO2.
> 
> Think about the case where sensor 1 gives you 1.30 bar, sensor 2 gives
> you 1.32 bar and sensor 3 whould say 0.40 bar.
> 
> In that case the voting would clearly say that sensor 3 is faulty, and
> the true ppo2 would be calculated to be 1.31 bar, but the current code
> whould trick subsurface into storing the last value, 0.40 bar, which is
> plain wrong.

Yes, you are absolutely right. The current OSTC implementation was only 
intended as a temporary solution, until we have a better way to deal 
with multiple O2 sensors (with a proper struct).

>> Just out of curiosity, how do people use the millivolt value? That's
>> something that depends on the sensor, which means you can't compare
>> between different dive computers, right? I would expect that it's
>> the ppo2 value you're interested in, because that's what you're
>> really trying to measure. The fact that this corresponds to a
>> certain millivolt value seems like some internal detail. Just like I
>> want depth in meters (or millibar) and not some meaningless voltage.
>> But I'm not a rebreather diver :-)
> 
> Those sensors are galvanic and give you a millivolt value as their
> response to oxygen. With the calibration data that value is converted
> into a ppo2 value, and the response in mV for certain ppo2 of o2 will
> differ between sensors, even sensors who are from the same batch and
> spent their hole life together in the same rebreather.
> 
> 
> The mV value for a certan ppo2 will drop over time, as the cell grows
> older. My grand plan was to play with some statistics once i had the
> data to see of one could predict when a censor is about to fail, when
> you have lots of samples from it over time.

That certainly sounds like an interesting research project, but what I'm 
trying to figure out is whether the average CCR diver would be 
interested in the mV values or not. The main target of libdivecomputer 
are logbook applications, not scientific research projects. That's why 
we return depths in meter, and not whatever value the underlying depth 
sensor gives you. So my question is: why should O2 sensors be treated 
different in this regard?

Just to be clear, this doesn't mean we can't include the mV values along 
with the ppO2 value. I'm just trying to get a better understanding of 
the need for this info.

>> >That way we keep backwards compability, and let the double ppo2
>> >represent the calculated/voted "true" ppo2, and let the struct
>> >o2_sensor represent the individual sensors.
>> 
>> Having two different ways to represent two types of ppo2 might be
>> confusing. How about using a special id (e.g. DC_SENSOR_NONE) for
>> the calculated/voted ppo2? That way way we don't need a different
>> struct, and there is no ambiguity in interpretation:
>> 
>> <sample>
>>    <ppo2 sensor="0">xxx</ppo2>
>>    <ppo2 sensor="1">xxx</ppo2>
>>    <ppo2 sensor="2">xxx</ppo2>
>>    <ppo2 sensor="none">xxx</ppo2>
>> <sample>
>> 
>> BTW, we already do that for tanks with the special DC_GASMIX_UNKNOWN 
>> id.
> 
> I'd say that the concepts are so far apart that it would just be
> confusing to mix them. Let the calculated/voted "true" ppo2 just be and
> handle the individual sensors on the side.

The idea behind my proposal was that in both cases we are dealing with 
ppO2. Only the source of the value is different: a value measured by an 
O2 sensor (CC), a voted value over the available sensors (CC), or even a 
calculated value based on depth and active gasmix (OC). Hence the use of 
the same type, but with an indicator for the source.

But I also understand that you want to make a very clear distinction 
between the measured values, and the calculated/voted value used for 
decompression calculations.

If you look at the existing DC_SAMPLE_XXX types, you can divide them 
into two distinct categories: data in the first group is obtained from a 
real sensor (e.g. depth, pressure, temperature, etc), while data in the 
second group is calculated by the dive computer (e.g. setpoint, cns, 
deco, etc). Originally, the DC_SAMPLE_PPO2 type was intended for sensor 
data.

> Most times you wouldn't care about the real sensors, its just when 
> trying
> to do sensor analytics they become interesting.

Are you referring to the mV values here, or the measured ppO2 in 
general?

I assumed the primary use case for having the individual sensor values 
was mainly to be able to spot defective sensors. An occasional outlier, 
is probably not a big deal. That's what the voting is for. But if one 
sensor is wrong too often, that's probably a good indication to replace 
it. Is that what you mean with sensor analytics? Or are you referring to 
the research about the degradation of the sensor over time?

>> The mapping won't be lost. Because the order and number of the
>> DC_SAMPLE_PPO2 values per sample will always be the same, the sensor
>> id is equivalent to the index of the DC_SAMPLE_PPO2 value. So on the
>> application side you can do something like this:
>> 
>> switch (type) {
>> case DC_SAMPLE_TIME:
>>     nsensors = 0; /⁠* New sample, reset the counter. */⁠
>>     break;
>> case DC_SAMPLE_PPO2:
>>     fprintf (sampledata->fp, "   <ppo2 sensor=\"%u\">%.2f</ppo2>\n",
>> nsensors, value.ppo2);
>>     nsensors++;
>>     break;
>> }
>> 
> 
> Doesn't look that clean to my eyes. I'd prefer different types, and 
> that
> also introduces the possibility to return mV values.

Well, I never said this was pretty :-) But as I said above, this was 
something for a temporary solution.

> Eh, doesn't the OSTC3 store both its "true" ppo2 and sensor data?
> 
> After reading the docco i think you're right. Wierd that they don't
> store the ppo2 they used for their calculations anywhere.

Unlike other manufacturers, we have access to the firmware source code, 
so we can always do the voting ourselves :-)

> Hmm.. ppo2 values for OC dives are only intresting if you plan to run
> your own deco model on the dive, and if you have a deco model that can
> run on dc data, you can probably calculate that ppo2 yourself. Thats
> what subsurface does.
> 
> I see no sane reason for exposing that ppo2 value on OC dives.

You could also say that for sample values like CNS and DECO. If you have 
your own deco model, you can easily calculate those yourself. But isn't 
the point here that you want to show the data reported by the dive 
computer? Because the deco model of the dive computer will not necessary 
be the same. On the other hand, calculating ppO2 is maybe not going to 
produce very different results. After all it's just: ppO2 = Pabs * fO2. 
That's something worth checking. If the value reported by the dive 
computer is always identical to the calculated value, then there is 
indeed very little reason to keep it.

> In firmware v29 they introduced a two sensor mode. I wonder how they
> represent that.

I assume they just leave the third sensor to zero or 0xFFFF.

Jef


More information about the devel mailing list