A code to drive a 3sensor reading unit for monitoring the operation opf a closed circuit rebreather (CCR) with 3 electrogalvanic sensors. Also uses a DS1307 for realtime clock and an MPX5700 to read the depth (mounted inside the breathing loop to keep it 'dry'). circuit diagrams available on rebreather world.

Dependencies:   DS1307 TextOLED mbed

Revision:
5:35417986539a
Parent:
4:74df6d31ee0a
Child:
6:ab2d7d0a9b07
--- a/Rebmon_main.cpp	Fri Aug 03 14:19:44 2012 +0000
+++ b/Rebmon_main.cpp	Tue Aug 07 11:33:03 2012 +0000
@@ -1,7 +1,7 @@
 //lpc1124lcddemo
 #include "ds1307.h"
 #include "mbed.h"
-#include "TextLCD.h"
+#include "TextOLED.h"
 
 
 #define METRE 0.02 // change in DEPin for 1m depth
@@ -23,7 +23,9 @@
 
 // switches and buttons - these are pulled up by resistors so are active low
 DigitalIn CAL(p36);
-DigitalIn SW1(p35);
+DigitalIn SW1(p35); // reed switch in display unit
+DigitalIn SW2(p10); // reed switch in dispaly unit
+DigitalIn MODE(p11);// a switchn on the mbed pcb to select between SCR and CCR modes for the LEDs
 
 // log data storage
 LocalFileSystem local("local");
@@ -81,7 +83,7 @@
         31,19,21,21,21,21,19,31,  // diving symbol        4 inverse D
         6,6,6,6,6,0,0,6,             // warning symbol    5
         31,17,23,17,29,17,31,0, // surface symbol         6 inverse S
-        0,0,17,17,0,17,14,0 // happy symbol                 7
+        2,6,2,2,2,2,23 // defined to handle dec point in depth          7
     };
     int i=0;
 // do stuff here to set cstom chars
@@ -126,7 +128,7 @@
 // sub to test if a variable is an even number
 int iseven(int g) {
     int test=0;
-    if(g%2 ==0) test=1;
+    if (g%2 ==0) test=1;
     return(test);
 }
 
@@ -135,6 +137,8 @@
     if (state==0) {
         g_lcd.character(9,0,5); // warning icon until 1 min up
         g_lcd.character(8,0,6); // surface icon
+    } else {
+        g_lcd.character(9,0,32);
     }
     if (state==1) g_lcd.character(8,0,6); // surface icon
     if (state==2 && iseven(seconds)==1) g_lcd.character(8,0,4); // diving icon
@@ -169,18 +173,37 @@
 
 void leds() {
 // first turn everything off
-red=0;
-green=0;
-blue=0;
-float ppo;
-ppo=maximum(ppo1,ppo2); // use max value to compute leds...
-if(ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!!
-if(ppo>0.2 && ppo < 1) red=1; // non-flashing red
-if(ppo>=1.0 && ppo <1.2) {red=1;green=1;} // red-green
-if(ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode
-if(ppo<1.4 && ppo >=1.3){green=1;blue=1;} // green-blue - high ppo2 be careful of spiking
-if(ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2
-if(ppo2>=1.6 && flash==1) blue=1;
+    red=0;
+    green=0;
+    blue=0;
+    float ppo;
+    int mo=0;
+    mo=MODE;
+    ppo=maximum(ppo1,ppo2); // use max value to compute leds...
+    if (mo==0) { // CCR mode
+        if (ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!!
+        if (ppo>0.2 && ppo < 1) red=1; // non-flashing red
+        if (ppo>=1.0 && ppo <1.2) {
+            red=1;    // red-green
+            green=1;
+        }
+        if (ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode
+        if (ppo<1.4 && ppo >=1.3) {
+            green=1;    // green-blue - high ppo2 be careful of spiking
+            blue=1;
+        }
+        if (ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2
+        if (ppo2>=1.6 && flash==1) blue=1;
+    }
+    if (mo==1) { // SCR mode
+        if (ppo<0.2 && flash==1) red=1;
+        if (depth < 0.8*mod && ppo>0.2) green=1;
+        if (depth< mod && depth >=0.8*mod) {
+            green=1;
+            blue=1;
+        }
+        if (depth >=mod && flash==1) blue=1;
+    }
 }
 
 
@@ -203,18 +226,55 @@
 //x.xx:xx D XX  xx
 //x.xx:xx B XX xxx NB the warning, staus and battery icons are driven by separate subroutines.
 void display() {
+    int mo=0;
+    mo=MODE;
 //1st line
     g_lcd.locate(0,0);
-    g_lcd.printf("%1.2f:%.2d   %.2d  %.2d",ppo1,(int)fo1,(int)depth,(int)mod);
+    g_lcd.printf("%1.2f:%.2d",ppo1,(int)fo1);
+    g_lcd.locate(10,0);
+    g_lcd.printf("%.2d  %.2d",(int)depth,(int)mod);
 //2nd line
     g_lcd.locate(0,1);
-    g_lcd.printf("%1.2f:%.2d   %.2d %.3d",ppo2,(int)fo2,divetime,scrubtime);
+    g_lcd.printf("%1.2f:%.2d",ppo2,(int)fo2);
+    g_lcd.locate(10,1);
+    g_lcd.printf("%.2d %.3d",divetime % 100 ,scrubtime % 1000); // modulo to avoid digits conflict - means divetime is always less than 100
     // bung in battery icon
     battery();
-    status(); // this will set the diviong / suface mode icon
+    status(); // this will set the diving / suface mode icon
     warning(); // this will set the warning icon assuming that max ppo2 is exceeded
 
     leds(); // this sets the leds according to the various warning conditions
+    if (mo==0) {
+        g_lcd.character(7,1,99);    //'c' = ccr
+    } else {
+        g_lcd.character(7,1,115);    //'s' = scr
+    }
+    // custom character setting to sort out dp in depths
+    
+   
+    char cgchar[80]={
+        7,5,5,5,23,0,0,0, // .0
+        2,2,2,2,18,0,0,0, //  .1
+        7,1,7,4,23,0,0,0, // 0.2
+        7,1,3,1,23,0,0,0, // 0.3
+        5,5,7,1,17,0,0,0, //0.4
+        7,4,7,1,23,0,0,0, //0.5
+        7,4,7,5,23,0,0,0, //0.6
+        7,1,2,2,18,0,0,0, //.7
+        7,5,7,5,23,0,0,0, //.8
+        7,5,7,1,17,0,0,0 //.9
+
+    };
+
+    int i=0,d=0;
+    d=(int)((depth-(int)depth)*10); // should be size of the 1st decimal place
+// do stuff here to set cstom chars
+    g_lcd.writeCommand(120); // set start address for CGRAM
+    for (i=0; i<8; i++) {
+        g_lcd.writeData(cgchar[i+d*8]);
+    }
+
+    g_lcd.character(12,0,7); // put in appropriate custom character
 
 }
 
@@ -227,20 +287,24 @@
     float barometric=0,mod1,mod2;
     ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2
     ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2
+    // NB this assumes that the calibration is done at exactly 1 bar.... - not always the case but ok for sea level diving
     pressure=(PRESin*3.3-0.024)/(0.0038574); // pressure in kPa assuming standard cal for mpx5700 sensor SUSPECT
-    // barometric=(pcal*3.3-0.024)/(0.0038574); // sealevel in kPa assuming standard cal for mpx5700 sensor
-    depth=(pressure-101.325)*0.1;   //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater.
-    //with two sensors will calculate mod from the largest ppo2 reading
+    barometric=(pcal*3.3-0.024)/(0.0038574); // sealevel in kPa assuming standard cal for mpx5700 sensor
+    
+    depth=(pressure-barometric)*0.1;   //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater.
+    if(depth<0) depth=0;
 
-    fo1=100*ppo1/(pressure/100); // pressure in bar = pressure /100 and want a % so multiply by 100 as well
-    fo2=100*ppo2/(pressure/100);
+    fo1=100*ppo1/((pressure-barometric)/100+1); // pressure in bar = pressure /100 and want a % so multiply by 100 as well
+    fo2=100*ppo2/((pressure-barometric)/100+1);
+    
+    if(fo1<0) fo2=0;
+    if(fo2<0) fo1=0;
 
-
+    //with two sensors will calculate mod from the largest ppo2 reading
     mod1=(1.4/(fo1/100)-1)*10;
     mod2=(1.4/(fo2/100)-1)*10;
 
     mod=minimum(mod1,mod2); // pick the least value
-    //DEBUG
 
 }
 
@@ -280,7 +344,7 @@
         j=(j+1) % 4;
     }
     g_lcd.cls();
-    backlight=1; // backlight on - this driven by bc182l and 50ohm resistor off the 5V supply to send ~ 20mA
+
 
     // ok there are three states in this system
 //MAIN LOOP ONCE STARTUP PROTOCOLS ARE COMPLETED