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:
9:71b8ac65b73a
Parent:
8:f45e654b47d0
--- a/Rebmon_main.cpp	Mon Jan 14 12:55:05 2013 +0000
+++ b/Rebmon_main.cpp	Fri Apr 12 10:16:53 2013 +0000
@@ -5,8 +5,6 @@
 #include "mbed.h"
 #include "TextOLED.h"
 
-//TODO - MAKE A VERSION THAT DRIVES THE HUD, CHECKS THE 5V SUPPLY AND COMPENSATES THE READINGS IF ITS VARYING (LINEARLY)
-// AND PREVENT A HANG IF THE DS1307 FAILS TO RESPOND.
 
 #define DRATIO 0.6420066 // ratio of voltage at pin20 to voltage actually generated by the sensor
 
@@ -17,6 +15,7 @@
 DigitalOut btest(p6); // pin to  drive lastblue led
 
 // offsets for lm324 amp in terms of reading values on adc
+// these are calibrated fromthe actual amplifier circuit but effectively include the ADC offsets for the mbed
 #define coff1 -0.013375
 #define coff2 -0.00936
 #define coff3 -0.0212136
@@ -232,12 +231,13 @@
     // average 20 readings for noise reduction
     g_lcd.cls();
     for (count=20; count>0; count--) {
-        g_lcd.locate(0,0);
-        g_lcd.printf("Calibrate 21%% %.2d",count);
         s1=s1+EG1;
         s2=s2+EG2;
         s3=s3+EG3;
         pres=pres+PRESin;
+        g_lcd.locate(0,0);
+        g_lcd.printf("CAL 21%% %.2d %1.2f",count,pres/(20-count+1));
+       
         g_lcd.locate(0,1);
         g_lcd.printf("%1.2f: %1.2f: %1.2f",s1/(20-count+1),s2/(20-count+1),s3/(20-count+1));
         wait(1);
@@ -354,6 +354,7 @@
 
 
 //read battery state and insert the battery symbol
+//RE-WRITE THIS TO USE THE 5 EMPTY PIXELS INSIDE THE BATTERY OUTLINE TO REPRESENT 50Mv INCREMENTS ON 3.5V
 void battery() {
  char cgchar[32]={
         6,9,9,9,9,9,9,15, // battery empty symbol         
@@ -363,35 +364,54 @@
         };
 
 
-    int batsym=0,i=0; // battery < 3.85V
+    int batsym=0,i=0,bstate=0,row=0; // bstate =(Vbattery-3.5V)/0.05;
 
 
     // idea to build in 6 levels of battery indicator by on the fly reprogramming character 2 as required.
     Vb=0;
-    for (i=0; i<4; i++) {
+    for (i=0; i<20; i++) {
         Vb=Vb+Vbatt; // read adc connected to battery via a 1/3 potential divider
         wait(0.05);
     }
-    Vb=Vb/4; // average 4 readings to reduce noise
+    Vb=Vb*3.3/20/0.337; // average 4 readings to reduce noise and rescale to ADC limit and convert to volts and account for potential divider on pcb.
 
+    bstate=floor((Vb-3.5)/0.05);
+    if(bstate > 9) bstate=9;
+    if(bstate <0) bstate=0;
+    
+    // fill up batery symbol according to bstate
+    for(i=0;i<10;i++)
+    {
+        // find row to enter 
+        row=6-floor((float)i/2);
+       if(bstate >=i) 
+       {
+       if(iseven(i)==1) cgchar[row]=cgchar[row]+4;
+       else cgchar[row]=cgchar[row]+2;
+       }
+        
+    }
+
+/*
     if (Vb>0.388) batsym=8; //3.85-3.92V
     if (Vb>0.395) batsym=16; // battery 3.92-4V
     if (Vb>0.404) batsym=24; // battery . >4V
+    */
 
 
 // write the appropriate battery symbol into the first custom character
     g_lcd.writeCommand(0x40); // set start address for CGRAM
     for (i=0; i<8; i++) {
-        g_lcd.writeData(cgchar[i+batsym]);
+        g_lcd.writeData(cgchar[i]);
     }
 
 g_lcd.character(11,1,0); // battery symbol
- if (batsym ==0 && flash==0) g_lcd.character(11,1,32); // bung in space if flashing
+ if (bstate <2 && flash==0) g_lcd.character(11,1,32); // bung in space if flashing
 
 
 }
 
-// sub to make the nice stop or no stop message work in locations 9,0 and 9,1
+// sub to make the nice status message work in locations 9,0 and 9,1
 void vmessage() {
 int i,d,cpos=0;
 // "INITSURFDIVE" in vertical chas - 1 custom char per two symbols
@@ -525,14 +545,14 @@
     s1=s1+EG1; // read o2 sensors
     s2=s2+EG2;
     s3=s3+EG3;
-    MPXref=MPXref+V5V; // read 5V
+    MPXref=MPXref+V5V; // read 5V reference
     wait_ms(10); // slows stuff down a bit but not a big problem
     }
     Vdepth=Vdepth/20; // now have the average
     s1=s1/20-coff1;
     s2=s2/20-coff2;
     s3=s3/20-coff3;
-    MPXref=MPXref/20*3.3*2; // should be 5V
+    MPXref=MPXref/20*3.3*2; // should be 5V but may not be.....
 
     
     // compute ppO2s
@@ -553,6 +573,8 @@
     
     if (depth<0) depth=0; // deals wtih noise that may lead to small variation in values
 
+
+
 // THESE SHOULD BE JUST 100*ppox/(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);
@@ -647,30 +669,41 @@
     for(i=0;i<n;i++)
     {
     HUD_clr();
-    wait(0.2);
+    wait(0.3);
     HUD_white();
-    wait(0.05);
+    wait(0.3);
+   
     }
+    HUD_display();
 }
-
+// sub to decide if the setpoint should change - in this variant it always changes at 9.5-10.5m
+// this might become annoyiong later so might want to make this function totally manual and use SW1 to control it.
 int setswitch()
 {
     if(setpoint==0 && depth >(switchdepth+0.5)) 
     { 
         setpoint=1; // handle switch from low to high
-        HUD_flash(4);
+        HUD_flash(4); // 4 flashes says going to high setpoint
         // flash the hud here
     }
     
     if(setpoint==1 && depth < (switchdepth -0.5))
     {
         setpoint=0;  // swtich to low setpoint
-        HUD_flash(2);
+        HUD_flash(2); // two flashes says going to low setpoint
         // flash the HUD here
     }
 }
 
 int main() {
+
+// start the clock in case it stopped for some reason 
+//this happens when the power drops due to battery getting too low. 
+// system still runs as a monitor but wont log.
+// might be useful later to build a sub that checks the clock is reading and starts it if its stopped
+
+    my1307.start_clock();
+
 // first some local variables
     int startuptime=getseconds();
     int startdive=0,endclock=0; // value of seconds when dive starts and counter to decide if dive complete...
@@ -682,10 +715,19 @@
 
     bool mdir=0;
 
+// code to deal with clock problem
+if(startuptime==0){ // clock buggered and needs reseting
+j=my1307.settime( 0, 0, 1, 1, 1, 1, 13); // set time to 1am on 1st jan 2013
+g_lcd.locate(0,0);
+g_lcd.printf( "Clockreset %d",j);
+    wait(3);
+}
     set_custom_char(); // does what it says on the tin really
     g_lcd.cls();
     g_lcd.locate(0, 0);
-    g_lcd.printf( "RebMon");
+    g_lcd.printf( "CCRMon SP%1.1f:%1.1f",lowsetpoint,highsetpoint);
+    wait(3);
+        g_lcd.cls(); // clear display to look nice
     g_lcd.locate(0,1);
     g_lcd.printf("CAL?");
     battery();
@@ -696,6 +738,7 @@
     recall();
     // display the correct scrubber time
     scrubtime=scrubold;
+
 // hang about waiting for the cal switch to be pressed in ccase it is
     while (scount<30) {
         seconds=getseconds(); // NB if this hangs then nothing works :( - usually means 5V is dodgy
@@ -738,6 +781,7 @@
         seconds=getseconds();
         minutes=(int)(((float)seconds-(float)startuptime)/60);
         led1=seconds % 2; // flash the onboard led to make it clear stuff is running
+        led2=!(seconds %2);
 
         if (j>1) flash=1;
         else flash=0;
@@ -765,12 +809,12 @@
             divetime=(seconds-startdive); // divetime no recorded in seconds since start of dive
 
             // do deco calcs here when implemented
-            if (divetime %15 ==0) store_log(); // this saves the dive profile and sensor optputs in a file called divelog.dat every 15s
+            if (divetime %15 ==0) store_log(); // this saves the dive profile data every 15s and sensor optputs in a file called divelog.dat
             if (depth<=0.5) {
                 endclock=endclock+1;
 
                 if (endclock>150) {
-                    state=1; // 30s at shallower than 0.3m and we return to surface mode. */
+                    state=1; // 30s at shallower than 0.5m 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...