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:
Fri Aug 03 11:29:30 2012 +0000
Parent:
2:a1c26faa9103
Child:
4:74df6d31ee0a
Commit message:
just leds to go

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 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