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 11:33:03 2012 +0000
Parent:
4:74df6d31ee0a
Child:
6:ab2d7d0a9b07
Commit message:
basic function done - still no recovery of values fro cal file...

Changed in this revision

Rebmon_main.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show diff for this revision Revisions of this file
TextOLED.lib Show annotated file Show diff for this revision Revisions of this file
--- a/Rebmon_main.cpp	Fri Aug 03 14:19:44 2012 +0000
+++ b/Rebmon_main.cpp	Tue Aug 07 11:33:03 2012 +0000
@@ -1,7 +1,7 @@
 //lpc1124lcddemo
 #include "ds1307.h"
 #include "mbed.h"
-#include "TextLCD.h"
+#include "TextOLED.h"
 
 
 #define METRE 0.02 // change in DEPin for 1m depth
@@ -23,7 +23,9 @@
 
 // switches and buttons - these are pulled up by resistors so are active low
 DigitalIn CAL(p36);
-DigitalIn SW1(p35);
+DigitalIn SW1(p35); // reed switch in display unit
+DigitalIn SW2(p10); // reed switch in dispaly unit
+DigitalIn MODE(p11);// a switchn on the mbed pcb to select between SCR and CCR modes for the LEDs
 
 // log data storage
 LocalFileSystem local("local");
@@ -81,7 +83,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,17,17,0,17,14,0 // happy symbol                 7
+        2,6,2,2,2,2,23 // defined to handle dec point in depth          7
     };
     int i=0;
 // do stuff here to set cstom chars
@@ -126,7 +128,7 @@
 // sub to test if a variable is an even number
 int iseven(int g) {
     int test=0;
-    if(g%2 ==0) test=1;
+    if (g%2 ==0) test=1;
     return(test);
 }
 
@@ -135,6 +137,8 @@
     if (state==0) {
         g_lcd.character(9,0,5); // warning icon until 1 min up
         g_lcd.character(8,0,6); // surface icon
+    } else {
+        g_lcd.character(9,0,32);
     }
     if (state==1) g_lcd.character(8,0,6); // surface icon
     if (state==2 && iseven(seconds)==1) g_lcd.character(8,0,4); // diving icon
@@ -169,18 +173,37 @@
 
 void leds() {
 // first turn everything off
-red=0;
-green=0;
-blue=0;
-float ppo;
-ppo=maximum(ppo1,ppo2); // use max value to compute leds...
-if(ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!!
-if(ppo>0.2 && ppo < 1) red=1; // non-flashing red
-if(ppo>=1.0 && ppo <1.2) {red=1;green=1;} // red-green
-if(ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode
-if(ppo<1.4 && ppo >=1.3){green=1;blue=1;} // green-blue - high ppo2 be careful of spiking
-if(ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2
-if(ppo2>=1.6 && flash==1) blue=1;
+    red=0;
+    green=0;
+    blue=0;
+    float ppo;
+    int mo=0;
+    mo=MODE;
+    ppo=maximum(ppo1,ppo2); // use max value to compute leds...
+    if (mo==0) { // CCR mode
+        if (ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!!
+        if (ppo>0.2 && ppo < 1) red=1; // non-flashing red
+        if (ppo>=1.0 && ppo <1.2) {
+            red=1;    // red-green
+            green=1;
+        }
+        if (ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode
+        if (ppo<1.4 && ppo >=1.3) {
+            green=1;    // green-blue - high ppo2 be careful of spiking
+            blue=1;
+        }
+        if (ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2
+        if (ppo2>=1.6 && flash==1) blue=1;
+    }
+    if (mo==1) { // SCR mode
+        if (ppo<0.2 && flash==1) red=1;
+        if (depth < 0.8*mod && ppo>0.2) green=1;
+        if (depth< mod && depth >=0.8*mod) {
+            green=1;
+            blue=1;
+        }
+        if (depth >=mod && flash==1) blue=1;
+    }
 }
 
 
@@ -203,18 +226,55 @@
 //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() {
+    int mo=0;
+    mo=MODE;
 //1st line
     g_lcd.locate(0,0);
-    g_lcd.printf("%1.2f:%.2d   %.2d  %.2d",ppo1,(int)fo1,(int)depth,(int)mod);
+    g_lcd.printf("%1.2f:%.2d",ppo1,(int)fo1);
+    g_lcd.locate(10,0);
+    g_lcd.printf("%.2d  %.2d",(int)depth,(int)mod);
 //2nd line
     g_lcd.locate(0,1);
-    g_lcd.printf("%1.2f:%.2d   %.2d %.3d",ppo2,(int)fo2,divetime,scrubtime);
+    g_lcd.printf("%1.2f:%.2d",ppo2,(int)fo2);
+    g_lcd.locate(10,1);
+    g_lcd.printf("%.2d %.3d",divetime % 100 ,scrubtime % 1000); // modulo to avoid digits conflict - means divetime is always less than 100
     // bung in battery icon
     battery();
-    status(); // this will set the diviong / suface mode icon
+    status(); // this will set the diving / 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
+    if (mo==0) {
+        g_lcd.character(7,1,99);    //'c' = ccr
+    } else {
+        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
+        7,1,7,4,23,0,0,0, // 0.2
+        7,1,3,1,23,0,0,0, // 0.3
+        5,5,7,1,17,0,0,0, //0.4
+        7,4,7,1,23,0,0,0, //0.5
+        7,4,7,5,23,0,0,0, //0.6
+        7,1,2,2,18,0,0,0, //.7
+        7,5,7,5,23,0,0,0, //.8
+        7,5,7,1,17,0,0,0 //.9
+
+    };
+
+    int i=0,d=0;
+    d=(int)((depth-(int)depth)*10); // should be size of the 1st decimal place
+// do stuff here to set cstom chars
+    g_lcd.writeCommand(120); // set start address for CGRAM
+    for (i=0; i<8; i++) {
+        g_lcd.writeData(cgchar[i+d*8]);
+    }
+
+    g_lcd.character(12,0,7); // put in appropriate custom character
 
 }
 
@@ -227,20 +287,24 @@
     float barometric=0,mod1,mod2;
     ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2
     ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2
+    // 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-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
+    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;
 
-    fo1=100*ppo1/(pressure/100); // pressure in bar = pressure /100 and want a % so multiply by 100 as well
-    fo2=100*ppo2/(pressure/100);
+    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;
 
-
+    //with two sensors will calculate mod from the largest ppo2 reading
     mod1=(1.4/(fo1/100)-1)*10;
     mod2=(1.4/(fo2/100)-1)*10;
 
     mod=minimum(mod1,mod2); // pick the least value
-    //DEBUG
 
 }
 
@@ -280,7 +344,7 @@
         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
--- a/TextLCD.lib	Fri Aug 03 14:19:44 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/simon/code/TextLCD/#c1ad3961696d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextOLED.lib	Tue Aug 07 11:33:03 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/TextLCD/#8e272a434581