Software to drive a monitor unit for a closed circuit rebreather using 3 electrogalvanic oxygen sensor cells run through an amplifier (lm324) . Uses a separate ds1307 clock IC to get timestamp values for logged data.

Dependencies:   DS1307 TextOLED_custom mbed

The main electornics is housed in another pod mounted on the back of the unit. I'm using an mbed lpc11u24 to drive everything which comes with a flash drive for data logging built in. It has an external ds1307 clock chip added and a very cheapo lm324 quad op-amp to amplify the o2 sensor signals from the 10s of mV range by 30x so that ppo2=0.21 corresponds to about 0.3V. I still have to do some ADC averaging with this amplifier and do have to calibrate out the individual offsets of the chip but this works ok now that I've worked out which amp is on which adc...

Files at this revision

API Documentation at this revision

Comitter:
pegcjs
Date:
Tue Aug 07 16:25:18 2012 +0000
Parent:
5:35417986539a
Child:
7:f93b7eaab5f6
Commit message:
finalised version - ready to build permanent hardware

Changed in this revision

Rebmon_main.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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; //
         }