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:
Thu Aug 02 16:05:46 2012 +0000
Parent:
1:9cff4feccbce
Child:
3:0d94a277aa8c
Commit message:
basic functions implemented - no backup readout for cal values or any logging. no leds or warnings setup.; need to restrict fo2 to avoid >100% issue and prevent negative depths...

Changed in this revision

Rebmon_main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Rebmon_main.cpp	Thu Aug 02 14:55:08 2012 +0000
+++ b/Rebmon_main.cpp	Thu Aug 02 16:05:46 2012 +0000
@@ -49,6 +49,9 @@
 int scrubtime=0; // these are expressed in minutes
 int divetime=0;
 
+
+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
 //dcal is the reading whe the pressure sensor is at the surface
 float eg1cal=0.09,eg2cal=0.09,pcal=0.1136;
@@ -76,7 +79,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,9,9,0,17,14,0 // happy symbol                 7
+        0,0,17,17,0,17,14,0 // happy symbol                 7
     };
     int i=0;
 // do stuff here to set cstom chars
@@ -112,20 +115,24 @@
     eg2cal=ppo2;
     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...
 }
 
-// subroutine to write the main display data
-//0123456789abcdef
 
-//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() {
-//1st line
-    g_lcd.locate(0,0);
-    g_lcd.printf("%1.2f:%.2d X %.2d  %.2d",ppo1,(int)fo1,(int)depth,(int)mod);
-    //2nd line
-    g_lcd.locate(0,1);
-    g_lcd.printf("%1.2f:%.2d B %.2d  %.2d",ppo2,(int)fo2,(int)depth,(int)mod);
+void status() {
+    if (state==0) g_lcd.character(8,0,5); // warning icon until 1 min up
+    if (state==1) g_lcd.character(8,0,6); // surface icon
+    if (state==2) g_lcd.character(8,0,4); // diving icon
+}
+
+void warning() {
+
+}
+
+void leds() {
 }
 
 //read battery state and insert the battery symbol
@@ -138,47 +145,73 @@
     g_lcd.character(8,1,batsym);
 }
 
+// subroutine to write the main display data
+//0123456789abcdef
+
+//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() {
+//1st line
+    g_lcd.locate(0,0);
+    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);
+    // bung in battery icon
+    battery();
+    status(); // this will set the diviong / 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
+
+}
+
+
 // pick maximum of two values
 float maximum(float a,float b) {
     float maximum;
     if (a>b) maximum=a;
     else maximum=b;
     return(maximum);
-       }
-       
+}
+
 // pick minimum  of two values
 float minimum(float a,float b) {
     float minim;
     if (a<b) minim=a;
     else minim=b;
     return(minim);
-       }
-       
-       
+}
+
 
-// read sensors and generate calibrated outputs
+
+// read sensors and generate calibrated outputs NB battery is read elsewhere
 void readsensors() {
     float barometric=0,mod1,mod2;
     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
-    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.
+    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
-    mod1=1.4/ppo1;
-    mod2=1.4/ppo2;
-    mod=minimum(mod1,mod2); // pick the 
+
+    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);
 }
 
 int main() {
-    // get time to log a startup time
-    //my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
-    //int startuptime=year*365*24*60*60+month*30*24*60*60+day*24*60*60+hours*60*60+min*60+sec; //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days.
+// first some local variables
+    int startuptime=getseconds();
+    int startdive=0; // value of seconds when dive starts
 
-    int startuptime=getseconds();
-    int startdive=0;
-
-    int seconds=0;; // this will be the divetiem variable eventually.
+    int seconds=0,minutes=0; // minutes is elapsed minutes since start of prog
     int i=0,j=0; // general loop counting variables
 
 
@@ -210,25 +243,18 @@
     // ok there are three states in this system
 //MAIN LOOP ONCE STARTUP PROTOCOLS ARE COMPLETED
     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
 
 
-        getseconds();
-        battery();
-        g_lcd.locate(0,0);
-        g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec);
-        led1=1;
-        wait(0.5);
-        g_lcd.character(i,1,i);
-        g_lcd.character(12,1,j);
-        i=(i+1) % 8;
-        j=(j+1) % 4;
-        // setup local file to store data in
-        //     FILE *fp = fopen("/local/out.txt", "a");  // Open "out.txt" on the local file system for writing
-        //   fclose(fp);
-        led1=0;
-        wait(0.5);
+
     } // end while
 } //end main