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:
3:0d94a277aa8c
Parent:
2:a1c26faa9103
Child:
4:74df6d31ee0a
--- a/Rebmon_main.cpp	Thu Aug 02 16:05:46 2012 +0000
+++ b/Rebmon_main.cpp	Fri Aug 03 11:29:30 2012 +0000
@@ -49,7 +49,7 @@
 int scrubtime=0; // these are expressed in minutes
 int divetime=0;
 
-
+int flash=0; // variable used top control flashing icons
 int state=0; // IMPORTANT - VARIABLE THAT DRIVES HNTE STATE MACHINE STATE=0 = STARTUP, STATE=1=SURFACE  STATE=2= DIVING
 
 // variables for the eg cells and pressure sensor eg1calamd eg2cal ar reading when the sensor is in 0.21bar O2 and
@@ -59,6 +59,7 @@
 
 float depth=0,ppo1=0,ppo2=0,  Vb=0,pressure=0; // depth, 1st o2 sensor second o2 sensor battery voltage,,Pressure
 float fo1=0,fo2=0,mod=55; //%f values,mod
+
 //===== sub to get time from ds1307 and create the 'seconds' which is a version of timestamp....
 int getseconds() {
     my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
@@ -123,12 +124,19 @@
 
 
 void status() {
-    if (state==0) g_lcd.character(8,0,5); // warning icon until 1 min up
+    if (state==0) {
+        g_lcd.character(9,0,5); // warning icon until 1 min up
+        g_lcd.character(8,0,6); // surface icon
+    }
     if (state==1) g_lcd.character(8,0,6); // surface icon
-    if (state==2) g_lcd.character(8,0,4); // diving icon
-}
+    if (state==2 && flash==1) g_lcd.character(8,0,4); // diving icon
+    if (state==2 && flash==0) g_lcd.character(8,0,68); // diving icon
+    }
+
+// warning and LED conditions
 
 void warning() {
+    if (depth>=mod && flash==1) g_lcd.character(13,0,5);
 
 }
 
@@ -142,7 +150,9 @@
     if (Vb>0.606) batsym=1;
     if (Vb>0.707) batsym=2;
     if (Vb>0.808) batsym=3;
-    g_lcd.character(8,1,batsym);
+    if (batsym >0) g_lcd.character(8,1,batsym);
+    if (batsym ==0 && flash==1) g_lcd.character(8,1,batsym);
+    if (batsym ==0 && flash==0) g_lcd.character(8,1,32);
 }
 
 // subroutine to write the main display data
@@ -156,7 +166,7 @@
     g_lcd.printf("%1.2f:%.2d   %.2d  %.2d",ppo1,(int)fo1,(int)depth,(int)mod);
 //2nd line
     g_lcd.locate(0,1);
-    g_lcd.printf("%1.2f:%.2d   %.2d  %.2d",ppo2,(int)fo2,divetime,scrubtime);
+    g_lcd.printf("%1.2f:%.2d   %.2d %.3d",ppo2,(int)fo2,divetime,scrubtime);
     // bung in battery icon
     battery();
     status(); // this will set the diviong / suface mode icon
@@ -191,27 +201,34 @@
     ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2
     ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2
     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
+    // 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
 
     fo1=100*ppo1/(pressure/100); // pressure in bar = pressure /100 and want a % so multiply by 100 as well
     fo2=100*ppo2/(pressure/100);
-    
+
 
     mod1=(1.4/(fo1/100)-1)*10;
     mod2=(1.4/(fo2/100)-1)*10;
+
     mod=minimum(mod1,mod2); // pick the least value
     //DEBUG
-    printf("ppo1=%1.3f\tppo2=%1.3f\tfo1=%2.2f\tfo2=%2.2f\tmod1=%2.1f\tmod2=%2.1f\tpressure=%.3f\t scrubtime=%d\n\r",ppo1,ppo2,fo1,fo2,mod1,mod2,pressure,scrubtime);
+
 }
+// sub to test if a variable is an even number
+/*int iseven(int g) {
+    int test=0;
+    if ((float)g/2==(int)((float)g/2)) test=1;
+    return(test);
+}*/
 
 int main() {
 // first some local variables
     int startuptime=getseconds();
-    int startdive=0; // value of seconds when dive starts
+    int startdive=0,endclock=0;; // value of seconds when dive starts and counter to decide if dive complete...
 
-    int seconds=0,minutes=0; // minutes is elapsed minutes since start of prog
+    int seconds=0,minutes=0,dt=0;; // minutes is elapsed minutes since start of prog
     int i=0,j=0; // general loop counting variables
 
 
@@ -222,12 +239,14 @@
     g_lcd.locate(0,1);
     g_lcd.printf("CAL?");
     battery();
-
+j=0;
 // hang about waiting for the cal switch to be pressed in ccase it is
     while (seconds-startuptime<20) {
         seconds=getseconds();
         g_lcd.locate(5,1);
         g_lcd.printf("%.2d",21-(seconds-startuptime));
+        if(j>1) flash=1;
+        else flash=0;
         battery(); // bung in battery symbol.
         g_lcd.locate(7,0);
         g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec);
@@ -235,26 +254,46 @@
             calibrate();
 
         }
-        wait(1);
+        wait(0.2);
+        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
+    j=0;
     while (1) {
         wait(0.2); //stop screen flicker
         readsensors();
         seconds=getseconds();
         minutes=(int)((float)seconds-(float)startuptime)/60;
-        scrubtime=minutes; // temporary to test
-        display();
-        if(minutes<1) state=0;
-        if(minutes>=1) state=1; // surface mode - ok to go for a dive now
-        if(minutes>1 && depth>0.5) state=2; // enter dive mode
+        dt=seconds-startuptime; // elapsed seconds
+
+        if (j>1) flash=1;
+        else flash=0;
+
+        display(); // write the display
+
+        // setup state variable
+        if (minutes<1) state=0; // startup mode - do nothing just wait to allow sensor readings to settle.
+        if (minutes>=1) state=1; // surface mode - ok to go for a dive now
+        if (minutes>1 && depth>0.5 && state==1) {
+            state=2; // enter dive mode
+            startdive=seconds; // set start of divetime.
+            endclock=0; // reset end of dive clock
+        }
+        if (state==2) {
+            divetime=(int)((float)seconds-(float)startdive)/60; // time since start of dive in minutes.
+            // do deco calcs here when implemented
+            if (depth<0.3) {
+                endclock++;
+                if (endclock==150) state=1; // 30s at shallower than 0.3m and we return to surface mode.
+            }
+        }
 
 
-
+        j=(j+1) %4; // flash control variable = used to make the warnings flash for 0.4s duty cycle
     } // end while
 } //end main