O2 sensor monitor

Greetings all.

Please forgive me as I know very little about Arduino ( or any other microprocessor) but I know a little about electronics and have a project in mind that the Arduino seems well suited for.

What I would like to build is a device that monitors 3 oxygen sensors and then displays their value via LED's and maybe also via LCD display.
This is for use on a scuba diving rebreather system where you need to know the Partial Pressure of Oxygen (PPO) at all times. This needs to read from a PPO of 0.00 up to 1.60 in 0.01 steps. The LEDs will be a Heads Up Display(HUD) while the LCD will be in a separate case.

So step one would be to read the millivolt from the sensor. These are generally 8-13mv in air but in pure oxygen under pressure need to read up to 10 times that or 130mv. Although this maximum could be reduced too 100 millivolt if I had too with anything greater being displayed as over load. Minimum resolution would have to be 1mv but 0.1mv would be much better.
Lets say 0.0mv=0 and 102.3mv=1023
Can the Arduino read voltages in this range or will the voltage have to be increased?

There would also be a calibration process. This would require putting pure O2 across the sensors at a pressure of 1bar ( sea level pressure). This would generate a voltage of 40-65 millivolt and this would then be assigned a valve of 1.00(PPO) for each O2 sensor. This calibration process would have to be done at the start of every dive day or trip.

Step Two would be to display the 3 PPO values from the 3 sensors on the LCD ( if used) and then also convert the 3 PPO values into flashes of LED's For example a similar system has a single LED per sensor. When the PPO= 0.95-1.05 the LED is orange. For every 0.1 above 1.0 the LED flashes green once then pauses and for every 0.1 bellow 1.0 it flashes red.
So a value of 0.5 would be RRRRR----- while a value of 1.0 would be O-------- and a value or 1.3 would be GGG-----. These flashes repeat every 4 or 5 seconds so I guess reading the sensor every 4 seconds is enough.
Another available system that only reads 2 sensors has 3 LED's The Green is lit if the PPO is between 0.5 and 1.4 and the red flashes faster the higher the PPO is above 1.25 while the orange flashes faster the lower the PPO is from 1.25. After about 4 seconds it displays the PPO value from the second sensor.

This process of reading the sensor and displaying the PPO value repeats until the unit is turned off.

Other thoughts.

There has to be a way to turn the unit on and off and also activate the calibration process.
This will be either a momentary reed switch or a piezo switch.
The calibration process should not be able to be activated while diving. So perhaps only with in the first 30 seconds of turning on.
The unit should not be able to be turned off while diving so perhaps if the PPO is above 0.7 it will not turn off at all and if the PPO is below 0.4 then auto off will activate after 5 minutes.
Other sensors may also be intergrated such as temp, depth ( pressure) and perhaps ambient light levels to adjust brightness of LED's in the HUD and brightness of LCD display.
I'd like to run it off a single 3.6v Li Ion battery(14500) but being able to run it off a single AA 1.5v would be great in an emergency.

Any input would be appreciated.

I don't see anything especially tough to implement, arguably the hardest part may well be waterproofing the Arduino and such.

The part that worries me is that scuba diving of all sorts is a dangerous activity, you're entering an actively hostile environment and your life support systems are very nearly as crucial as they are on a space suit.
As such, I would have a very hard time trusting my life to something I soldered together and programmed, the risk is huge. Even if you're just using the Arduino to display PPO2 status and not having the Arduino do any of the active oxygen level adjustments it can still kill you easily. All it takes is the Arduino getting wet and deciding to drive the o2 sensor output HIGH or LOW. Either one will freak the rebreather computer out badly (hell, 5v may simply fry it), leaving you with rather large issues!

If you really want to add your own monitoring I would buy a fourth o2 sensor and put that into your breather loop, let the Arduino play with that one. If it kills it, you lose your monitoring but don't suddenly find yourself slowly running out of oxygen without realizing it (breathing reflex is triggered on co2, which will still be scrubbed out. The majority of rebreather failures that I have read about the diver never notices the lack of oxygen.

Thanks for your input.

Keeping the HUD dry is not that hard ( I build plenty of dive lights that keep dry) and even if it does the HUD will be isolated from any other electronics so a failure of one will not effect the other.
Also it is meant as a secondary display unit and not a primary and as such will not be relied upon.

More than anything I guess I am doing this as a learning experience on the Anduino. If it works I will replace my rEvo dream PPO HUD. If it does not I will reprogram it to make toasted crumpets.

Oh, I have decided on a Arduino Mini 3.3v board due to its size and voltage requirements.
Any code for any of the steps would be appreciated.

EDIT: you do raise a valid point Bob, steps will have to be taken to make sure the software is stable and reliable with failsafes the stop things like mid dive calibrations or locking up from occurring.

How do you plan to get the signal from the rebreather to the HUD? I'd imagine that any sort of electrical interconnects are going to be exceptionally tricky? I know there are wireless pressure senders but not sure about O2?

As has been said before - I probably wouldn't go into something deeper than a puddle with anything I'd soldered/coded.

You're not an "aplinist" are you?!

No Im not an Alpinist. 8)

Here is the Shearwater version of what I want to build.
You can clearly see the box the electronics are mounted in and a cable heading off to the HUD and another cable that goes into the internals of the rebreather and connects to the O2 cells.

The rEvo Dream that I currently use is the same except it has a LCD display on the electronics box.

Other systems are pretty much the same.

I'm not to concerned about using a DIY PPO meter after all I have built my own rebreather ( not currently in use) and plenty of dive lights

The part that worries me is that scuba diving of all sorts is a dangerous activity

No, SCUBA diving is "hazardous", not dangerous.
But no, I wouldn't trust my dive safety solely to an Arduino.

My diving experience is strictly in the rum drenched tourist camp but I figure that if you have the capability to build your own rebreather and understand that (and I think everyone on here will back me up on this) an Arduino is not a suitable platform for safety critical applications.....

It is not a critical application. it is simply a redundant monitor.

The primary monitor is a Shearwater Predator computer that displays the PPO of 3 cells.

Currently I use the Shearwater and a rEvo dream HUD and also a DIY 2 channel PPO meter that simply uses 2 digital panel meters to show the voltage of the cells calibrated to PPO.

I am interested in why you dont think its suitable though.
DO these things crash regularly?

Of course I would be very distrusting if it at first and would probably be referencing it against the rEvo HUD and the Shearwater for a fair number of dives.

It's less that they crash a lot than that the parts and methods used to build arduinoy things aren't designed to have the kind of 99.999(etc.)% reliability required for life support applications.
If you've already built you own entire breathing apparatus, you know the risks and level of accuracy required for this sort of thing.

For the pedantic, a dangerous activity is one involving danger, tell me scuba diving has no danger when you suddenly have no air 100' down!

If you want to look at it like that then driving a car is an even more dangerous activity. Imagine all your tires going flat at 100kph, or your headlights suddenly failing in the dark at 100kph or your brakes locking up or failing to work.........
No, scuba diving is not dangerous relatively speaking , it just has hazards that are mangable. Diving a rebreather has more hazards but these are easily managed. Running out of air at 100ft is not a major problem at all. More of an inconvenience. Running out of oxygen is a little more of a concern but no real biggie. Now if you were to run out of air and oxygen.... chances are its still not going to kill you even if you were not diving with a buddy who could have passed gas off to you.

Anyway once again this project is not a critical item in the rebreather. It controls nothing, the absolute worst thing it could do is display a PPO of 1.0-1.3 constantly while the actual PPO is higher or lower. In this situation it may mean I look at my primary computer and PPO meter less often. But I honestly think that failure mode is unlikely and if it was to happen would be picked up on soon enough.
If someone can suggest another platform that would be more suited to this project that is as easy to work with I am willing to listen.

Now first problem I see is the ADC of the O2 cells. I would like to reference the input against 102.3mv or perhaps 204.8mv. This will give me a resolution of 0.1 or 0.2mv.
Can I simply put a voltage diver resistor on the aref pin with 102.3mv ( or 204.7mv)? Are there any problems with a reference voltage this low?
Will this mean any other sensor ( temp/depth) I use will have to referenced against 102.3mv or can I use code to switch it back to an internal reference?

OK I have written my first bit of code. Its far from complete and I am sure it is full of noobie errors but here it is.

It seems a bit repetitive and I am sure there is a better way to do it but I am unsure on how to do it. Any suggestions would be appreciated.

Basically the PPO loops from 0-180 in steps of 10. A single bi coloured LED will flash out a code to respond to the PPO value. If its 100 then it will flash for .25 of a second then wait for 3.75 seconds.
If the PPO is less than 100 then the Red LED will flash once for every 10 units less than 100
If the PPO is more than 100 then the green LED will flash once for every 10 units above 100

Eventually the PPO value will be set by the millivolt of the O2 sensor and there will be 3 bi colors LED's one for each O2 sensor.

I also need to flash the bi coloured LED orange for a PPO value of 100-110.

int ledonegreen = 11; // select the pin for the LED 11 high and 12 low = green=
int ledonered = 12;
int ppo = 0;
void setup() {pinMode(ledonegreen, OUTPUT);pinMode(ledonered, OUTPUT);}
void loop() {
;ppo +=10;if (ppo==180) ppo=0;

if (ppo<30) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); } //If PPO=0.70 to 0.79 then flash eight red

if (ppo<40) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); delay(500);} //If PPO=0.70 to 0.79 then flash seven red

if (ppo<50) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW);delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); delay(1000);} //If PPO=0.70 to 0.79 then flash six red

if (ppo<60) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); delay(1500);} //If PPO=0.70 to 0.79 then flash five red

if (ppo<70) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW);delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); delay(2000); } //If PPO=0.70 to 0.79 then flash four red

if (ppo<80) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW);delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); delay(2500); } //If PPO=0.70 to 0.79 then flash three red

if (ppo<90) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW); delay(250); digitalWrite(ledonered, LOW);delay(250);
digitalWrite(ledonered,HIGH); delay(250); digitalWrite(ledonered, LOW);delay(250); delay(3000) ;} //If PPO=0.80 to 0.89 then flash two red

if (ppo<100) { digitalWrite(ledonered,HIGH); digitalWrite(ledonegreen, LOW); delay(250); digitalWrite(ledonered, LOW);delay(250) ;
delay(3000) ;} //If PPO=0.80 to 0.89 then flash one red

if (ppo< 110) { digitalWrite(ledonegreen, HIGH);digitalWrite(ledonered, LOW);
delay(250); digitalWrite(ledonegreen, LOW); delay(250); delay(3500); }//If PPO=1.00 to 1.09 then flash one green // needs to be modified to flash orange!!

if (ppo< 120) { digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
delay(3000); } //If PPO=1.10 to 1.19 then flash one green

if (ppo< 130) { digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH);delay(250); digitalWrite(ledonegreen, LOW);delay(250); delay(3000); } //If PPO=1.20 to 1.29 then flash two green

if (ppo< 1540) {digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW);delay(250);digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250); delay(2500);} //If PPO=1.30 to 1.39 then flash three green

if (ppo< 150) {digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW);delay(250);digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250); delay(2000);} //If PPO=1.40 to 1.49 then flash four green

if (ppo< 160) { digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250); delay(1500);} //If PPO=1.50 to 1.59 then flash five green

if (ppo< 170) { digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250); delay(1500);} //If PPO=1.60 to 1.69 then flash six green

else { digitalWrite(ledonegreen,HIGH); digitalWrite(ledonered, LOW); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);
digitalWrite(ledonegreen,HIGH); delay(250); digitalWrite(ledonegreen, LOW);delay(250);delay(500);} //If PPO.1.6 then flash seven green

}

Needs more semicolon.
It is polite to at least try to compile code before posting.

tell me scuba diving has no danger when you suddenly have no air 100' down!

That's why we dive with others, and carry spares.

Fair call, I havent actually got my Arduino board yet. And I know think I have ordered the wrong one.

EDIT. Oh I see what you mean by compiling. ( warned you I was a noobie)

There seems to be no aref pin on the mini so I am unsure if I can reference to a voltage of 102.3mv???

Fair call, I havent actually got my Arduino board yet

You don't need a board to compile, just the IDE.

Thanks.

I have now got rid of any compiling errors and edited my previous code post.

You might need a function to shorten your code and keep it more readable

(partial code , will not compile)

void blinkRed(int nr, int wait)  // nr of blinks followed by delay
{
  digitalWrite(ledonegreen, LOW); 
  for (int i=0; i< nr; i++)
  {
    digitalWrite(ledonered,HIGH); 
    delay(250); 
    digitalWrite(ledonered, LOW);
    delay(250); 
  }
  delay(wait)
}


void loop()
{
   ppo +=10;
   if (ppo==180)  ppo=0;

   if (ppo<30) blinkRed(8,0);  //If PPO=0.70 to 0.79 then flash eight red
   if (ppo<40) blinkRed(8, 500);  //If PPO=0.70 to 0.79 then flash seven red
   if (ppo<50) blinkRed(8, 1000);} //If PPO=0.70 to 0.79 then flash six red
   if (ppo<60) blinkRed(8, 1500); //If PPO=0.70 to 0.79 then flash five red
   if (ppo<70) blinkRed(8, 2000);  //If PPO=0.70 to 0.79 then flash four red
   if (ppo<80) blinkRed(8, 2500); } //If PPO=0.70 to 0.79 then flash three red
   if (ppo<90) blinkRed(8, 3000) ;} //If PPO=0.80 to 0.89 then flash two red 
   if (ppo<100) blinkRed(8, 3000) ;} //If PPO=0.80 to 0.89 then flash one red

etc

Now you should be able to write the blinkGreen() function and shorten the second halve

And please use the [ code] tags iso quote when posting code. Use the # button for this

(time to recompile again :wink:

I've never had to read voltages that low so will bow down the superior knowledge of others but I think you might be better off with a op amp solution. Perhaps a MAX4194 with a 1k gain resistor?

Thanks robtillaart.
Its getting late here and my mind is slowing down.
Tomorrow I will try and understand the code you posted.
I have already figured out that my code will not allow me to run 3 O2 cells and 3 LED's

Daveg360: The thought of using an Op amp has occurred to me. Will prefer to avoid if I can but realise it may be needed.

May I suggest the LM324 op amp for this. Low power, ground sense, etc.
http://www.national.com/mpf/LM/LM324.html#Overview

And since it is a quad op amp, it will handle 4 sensors. :slight_smile:

My opinion: GO FOR IT! I will bet that nobody here that has responded so far uses a dive computer. Do you think that the first dive computer was a perfect model looking like it was straight from the store?

The more safety equipment I can carry, the safer I feel.

I will bet that nobody here that has responded so far uses a dive computer.

Pay up - I use two; different models, different manufacturers.
I'm not an early adopter though :wink:

Edit: make that three - I think my first Mosquito still works, though I don't think I'd dive with all three - I'd look like a Christmas tree!