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:
6:ab2d7d0a9b07
Parent:
5:35417986539a
Child:
7:f93b7eaab5f6
--- a/Rebmon_main.cpp	Tue Aug 07 11:33:03 2012 +0000
+++ b/Rebmon_main.cpp	Tue Aug 07 16:25:18 2012 +0000
@@ -21,6 +21,7 @@
 DigitalOut green(p33);
 DigitalOut blue(p30);
 
+
 // switches and buttons - these are pulled up by resistors so are active low
 DigitalIn CAL(p36);
 DigitalIn SW1(p35); // reed switch in display unit
@@ -49,7 +50,7 @@
 int year = 0;
 int seconds=0; // general number of seconds since 2000 etc timestamp variable
 
-int scrubtime=0; // these are expressed in minutes
+int scrubtime=0,scrubold=0;; // these are expressed in minutes
 int divetime=0;
 
 int flash=0; // variable used top control flashing icons
@@ -63,6 +64,8 @@
 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
 
+FILE *lp; // file pointer for log file
+
 //===== 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);
@@ -94,6 +97,13 @@
 
 }
 
+// stash cal values on local drive
+void store() {
+    FILE *fp=fopen("/local/CAL.dat","w");
+    fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime);
+    fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...
+}
+
 
 // subroutine to calibreate o2 sesnors and store ca data in /local/CAL.dat
 void calibrate() {
@@ -120,9 +130,10 @@
     pcal=pres/20; // surface pressure....
     scrubtime=0; // reset the scrubber timer to zero.
     // write cal data NB overwites previous
-    FILE *fp=fopen("/local/CAL.dat","w");
-    fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime);
-    fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...
+    /*  FILE *fp=fopen("/local/CAL.dat","w");
+      fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime);
+      fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...*/
+    store();
 }
 
 // sub to test if a variable is an even number
@@ -150,6 +161,7 @@
 
 void warning() {
     if (depth>=mod && flash==1) g_lcd.character(13,0,5);
+    else g_lcd.character(13,0,32); // blank sapce
 
 }
 
@@ -197,6 +209,7 @@
     }
     if (mo==1) { // SCR mode
         if (ppo<0.2 && flash==1) red=1;
+        if(ppo2>=0.2 && ppo2 <0.26) red=1; // will give green red for low but not lethal ppo2s
         if (depth < 0.8*mod && ppo>0.2) green=1;
         if (depth< mod && depth >=0.8*mod) {
             green=1;
@@ -204,6 +217,7 @@
         }
         if (depth >=mod && flash==1) blue=1;
     }
+
 }
 
 
@@ -232,7 +246,9 @@
     g_lcd.locate(0,0);
     g_lcd.printf("%1.2f:%.2d",ppo1,(int)fo1);
     g_lcd.locate(10,0);
-    g_lcd.printf("%.2d  %.2d",(int)depth,(int)mod);
+    g_lcd.printf("%.2d",(int)depth);
+    g_lcd.locate(14,0);
+    g_lcd.printf("%.2d",(int)mod);
 //2nd line
     g_lcd.locate(0,1);
     g_lcd.printf("%1.2f:%.2d",ppo2,(int)fo2);
@@ -250,8 +266,8 @@
         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
@@ -290,15 +306,15 @@
     // 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-barometric)*0.1;   //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater.
-    if(depth<0) depth=0;
+    if (depth<0) depth=0;
 
     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;
+
+    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;
@@ -307,6 +323,20 @@
     mod=minimum(mod1,mod2); // pick the least value
 
 }
+// get values back from cal file on local drive
+void recall() {
+    FILE *fp=fopen("/local/CAL.dat","r");
+    fscanf(fp,"%e\n%e\n%e\n%d",&eg1cal,&eg2cal,&pcal,&scrubold);
+    fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...
+}
+
+// write the logfile opened and closed by start and end of dive
+void store_log() {
+ Vb=Vbatt;
+    //FILE *fp=fopen("/local/divelog.dat","a");
+    fprintf(lp,"%d\t%e\t%e\t%e\t%e\t%d\n",seconds,depth,ppo1,ppo2,Vb,scrubtime);
+   // fclose(fp);
+}
 
 
 int main() {
@@ -314,8 +344,9 @@
     int startuptime=getseconds();
     int startdive=0,endclock=0; // value of seconds when dive starts and counter to decide if dive complete...
 
-    int minutes=0,dt=0;; // minutes is elapsed minutes since start of prog
-    int i=0,j=0; // general loop counting variables
+    int minutes=0; // minutes is elapsed minutes since start of prog
+    int j=0; // general loop counting variable
+
 
 
     set_custom_char(); // does what it says on the tin really
@@ -326,6 +357,10 @@
     g_lcd.printf("CAL?");
     battery();
     j=0;
+    // get cal values last used from local drive
+    recall();
+    // display the correct scrubber time
+    scrubtime=scrubtime+scrubold;
 // hang about waiting for the cal switch to be pressed in ccase it is
     while (seconds-startuptime<20) {
         seconds=getseconds();
@@ -354,7 +389,7 @@
         readsensors();
         seconds=getseconds();
         minutes=(int)(((float)seconds-(float)startuptime)/60);
-        dt=seconds-startuptime; // elapsed seconds
+
 
         if (j>1) flash=1;
         else flash=0;
@@ -364,20 +399,28 @@
         // setup state variable
         if (minutes<1) state=0; // startup mode - do nothing just wait to allow sensor readings to settle.
         if (minutes>=1 && state==0) state=1; // surface mode - ok to go for a dive now
-        if (minutes>=1 && depth>0.5 && state==1) {
+        if (minutes>=1 && depth>0.8 && state==1) {
             state=2; // enter dive mode
+            lp=fopen("/local/divelog.dat","a");
             if (startdive==0) startdive=seconds; // set start of divetime. don't do this twice
             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) {
+            if ((seconds-startdive) %15 ==0) store_log(); // this saves the dive profile and sensor optputs in a file called divelog.dat every 15s
+            if (depth<=0.3) {
                 endclock=endclock+1;
 
-                if (endclock>150) state=1; // 30s at shallower than 0.3m and we return to surface mode.
+                if (endclock>150) {
+                    state=1; // 30s at shallower than 0.3m and we return to surface mode.
+                    FILE *fp=fopen("/local/CAL.dat","w");
+                    fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime);
+                    fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...
+                    fclose(lp);
+                }
             }
-            scrubtime=minutes; // need to add memory of prior scrub time to this once variable input fom log file is implements
+            scrubtime=scrubold+divetime; //
         }